view holder generator for Android
Android dev is painful. for example, findViewById()
. some project like butterknife try to solve it by view injection. but is this really a good solution? the ideal way is for one view, only give it a name once. but using view injection, you still need to write the name three times:
@InjectView(R.id.subtitle) TextView subtitle;
android:id="@+id/subtitle"
an alternative approach is use a uniform binding pattern between Java field names and view ids. using this tool, a layout file like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
holder="main.MainAct"
android:id="@+id/nav">
<LinearLayout
android:id="@+id/profile"
style="@style/nav_item">
<ImageView
style="@style/image"
android:id="@+id/image">
<TextView
style="@style/main_nav_left_item_text"/>
</LinearLayout> </LinearLayout>
will generate code in the MainAct
class which is specified in the xml holder
attribute:
LinearLayout _nav;
LinearLayout _nav_profile;
ImageView _nav_profile_image;
private void __find_views_main_nav_left(View view) {
_nav = ((LinearLayout) view);
_nav_profile = ((LinearLayout) ((ViewGroup) view).getChildAt(0));
_nav_profile_image = ((VRounded) ((ViewGroup)((ViewGroup) view).getChildAt(0)).getChildAt(0));
}
protected View __inflate_view_main_nav_left(LayoutInflater inflater, ViewGroup parent) {
View view = inflater.inflate(com.p1.mobile.putong.R.layout.main_nav_left, parent, false);
__find_views_main_nav_left(view);
return view;
}
then you can use the __inflate_view_
or __find_views_
methods whatever way you want
for example, in a activity, setContentView(__inflate_view_)
and in a custom view __find_views_(this)
inside onInflateFinished
it will skip ( flatmap
) all the views that has no id. and the field names is generated by stacking all the ids together. i use this approach because the names preserved the tree structure of the xml naturally. because in practice it is very hard to give proper names for views if it is nested too much
just a demo
- it should be easy to support
include
andmerge
tags, but it is not done yet - and should be easy to support inner classes...
- it do not support layout files for multiple folders now. i think you can do this by do not generate
getChildAt
calls, butview.findViewById()
calls. but be careful with name collision if you want to use the stacked short name approach. alternatively, you can just do not stack them at all. then it is just a better butterknife import
s is not generated. but with IntelliJ IDEA, i hardly found it a inconvenience