Butter knife: An Android View injection framework
Thursday, May 8, 2014
14:52
Official website: http://jakewharton.github.io/butterknife/
GitHub Address: https://github.com/JakeWharton/butterknife
JavaDocs Address: http://jakewharton.github.io/butterknife/javadoc/
Note: This essay is translated from the official website and made some collation and comments. From my OneNote notes
Outline:
- @InjectView (Activity,Fragment)
- @InjectViews
- Apply
- @OnClick
- Reset
- @Optional
- @OnItemSelected
- TextView FirstName = Butterknife.findbyid (view, r.id.first_name);
How to inject Activity:
Basic Use Method: call butterknife.inject (this) in the OnCreate method, then you can invoke the annotations Class exampleactivity extends Activity { @InjectView (r.id.title) TextView title; @InjectView (r.id.subtitle) TextView subtitle; @InjectView (r.id.footer) TextView footer; @Override public void OnCreate (Bundle savedinstancestate) { Super.oncreate (savedinstancestate); Setcontentview (r.layout.simple_activity); Butterknife.inject (this); TODO use "injected" views ... } } |
This injection is not implemented by reflection (slow reflection), but rather generates code directly. The above three injections finally generate the following code
public void inject (exampleactivity activity) { Activity.subtitle = (Android.widget.TextView) Activity.findviewbyid (2130968578); Activity.footer = (Android.widget.TextView) Activity.findviewbyid (2130968579); Activity.title = (Android.widget.TextView) Activity.findviewbyid (2130968577); } |
Fragment method of injection :
public class Fancyfragment Exten DS Fragment { @InjectView (r.id.button1) button button1; @InjectView (r.id.button2) button button2; @Override View Oncreateview (layoutinflater inflater, ViewGroup container, Bundle Savedinstancestate) { view View = Inflater.inflate (r.layout.fancy_ Fragment, container, false); // just the difference here. butterknife.inject (this, view); //TODO use "injected" views ... return view; } } |
Simplifying The use of Viewholder
public class Myadapter extends Baseadapter { @Override public View getView (int position, view view, ViewGroup parent) { //viewholder is an ordinary class that contains all the View required by a Adapter and is then set to tag for easy reuse . Viewholder Holder; if (view! = null) { Holder = (viewholder) view.gettag (); } else { View = Inflater.inflate (R.layout.whatever, parent, false); Holder = new Viewholder (view); View.settag (holder); } Holder.name.setText ("John Doe"); etc... return convertview; } Here is Viewholder: This can be injected Static Class Viewholder { @InjectView (r.id.title) TextView name; @InjectView (r.id.job_title) TextView jobtitle; Public Viewholder (view view) { Butterknife.inject (this, view); } } } |
Inject a View list:@InjectViews
inject a View list @InjectViews({r.id.first_name, r.id.middle_name, r.id.last_name}) List<edittext> nameviews; Call the Apply method to set properties in bulk for a view Butterknife.apply (Nameviews, DISABLE); Butterknife.apply (Nameviews, ENABLED, false); Wherein, disable and enabled are the implementations of the two interfaces: Action,setter Static final action<view> DISABLE = new action<> () { @Override public void Apply (view view, int index) { View.setenabled (FALSE); } } Static final Setter<view, boolean> ENABLED = new setter<> () { @Override public void Set (view view, Boolean value, int index) { view.setenabled (value); } } View all properties can be called in the Apply method Butterknife.apply (nameviews, View.alpha, 0); |
Click on the listener's injection:onclicklistener- @OnClick
Simple to use @OnClick(r.id.submit) Ren Public void submit () { TODO submit data to server ... } You can pass in a parameter, Butter knife will automatically convert the injected view to the corresponding type @OnClick(r.id.submit) Public void sayhi (button button) { Button.settext ("hello!"); } Of course, you can also specify multiple views of IDs for common processing @OnClick({r.id.door1, R.id.door2, R.id.door3}) Public void Pickdoor (doorview door) { if (Door.hasprizebehind ()) { Toast.maketext (This, "You win!", Length_short). Show (); } else { Toast.maketext (This, "Try again", Length_short). Show (); } } |
Injection Reset: Reset
In Fragment , we need to set these View to null in Ondestroyview, but as long as the reset method is called,Butter Knife will perform this step automatically.
public class Fancyfragment extends Fragment { @InjectView ( R.id.button1) Button button1; @InjectView (r.id.button2) button button2; @Override View Oncreateview (layoutinflater inflater, ViewGroup container, Bundle Savedinstancestate) { view View = Inflater.inflate (r.layout.fancy_ Fragment, container, false); butterknife.inject (this, view); //TODO use "injected" views ... return view; } @Override void Ondestroyview () { Super.ondestroyview (); butterknife.reset (this); } } |
Optional injection @Optional
By default,@InjectView and @OnClick injections are required, so if the target View is not found, an exception is thrown. If you want to suppress this situation, you can @Optional annotations:
@Optional @InjectView (r.id.might_not_be_there) TextView mightnotbethere; @Optional @OnClick(r.id.maybe_missing) void onmaybemissingclicked () { Todo... } |
Multi-method monitoring @OnItemSelected
Some methods of listening for annotation responses have multiple callback functions, so we can implement binding of multiple callback methods by specifying callback parameters.
@OnItemSelected (R.id.list_view) void onitemselected (int position) { Todo... } @OnItemSelected(value = r.id.maybe_missing, callback = nothing_selected) void onnothingselected () { Todo... } |
BONUS: Actually, it's a convenient static method.
In general, when we instantiate a View by the findByid (ID), and then cast the implementation, such code looks unsightly. So,Butterknife has a way to automatically help us with such conversions (Context can be View and Activity), as in the following example:
View view = Layoutinflater.from (context). Inflate (r.layout.thing, NULL); TextView FirstName = Butterknife.findbyid (view, r.id.first_name); TextView LastName = Butterknife.findbyid (view, r.id.last_name); ImageView photo = Butterknife.findbyid (view, R.id.photo); |
Latest Version:5.0.1
Integration method
Maven:
<dependency> <groupId>com.jakewharton</groupId> <artifactId>butterknife</artifactId> <version>5.0.1</version> </dependency> |
Gradle:
- Add dependency
Compile ' com.jakewharton:butterknife:5.0.1 ' |
- Eliminate Lint warning
lintoptions { Disable ' Invalidpackage ' } |
- Some configurations may also require additional exclusions.
packagingoptions { Exclude ' meta-inf/services/javax.annotation.processing.processor ' } |
Procuard Configuration : (This configuration is to pack the APK when not to have your seemingly unused program fragments deleted)
-dontwarn butterknife.internal.** -Keep class **$ $ViewInjector {*;} -Keepnames class * {@butterknife. Injectview *;} |