Open source Chinese source learning (vi) use of--butterknife

Source: Internet
Author: User

This article was translated from the Butter Knife official website: butterknife

Brief introduction

Use @bind to annotate a field and butter knife to find and automatically convert to a view that matches your layout based on the given view ID.

Activity Binding

The activity binding sample code is as follows:

class ExampleActivity extends Activity {  @Bind(R.id.title) TextView title;  @Bind(R.id.subtitle) TextView subtitle;  @Bind(R.id.footer) TextView footer;  @Override public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.simple_activity);    ButterKnife.bind(this);    // TODO Use fields...  }}

Instead of slow reflection, the code usually behaves like a view. Call bind to delegate these generic codes you can see and Debug.

The common code in the above example generates the code that looks like this:

public void bind (exampleactivity activity) {Activity = (android.widget  ) Activity.findviewbyid  ( 2130968578 ) ;  Activity.footer  = (android.widget  Span class= "Hljs-preprocessor". TextView ) Activity.findviewbyid  ( 2130968579 ) ;  Activity.title  = (android.widget  Span class= "Hljs-preprocessor". TextView ) Activity.findviewbyid  ( 2130968577 ) ; } 
Non-activity binding (binds to inflate view)

You can also support your own view root by binding on custom objects.

publicclass FancyFragment extends Fragment {  @Bind(R.id.button1) Button button1;  @Bind(R.id.button2) Button button2;  @OverridepubliconCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {    false);    ButterKnife.bind(this, view);    // TODO Use fields...    return view;  }}
Binding to the View Holder
 Public  class myadapter extends baseadapter {  @Override  PublicViewGetView(intPosition, view view, ViewGroup parent) {Viewholder holder;if(View! =NULL) {holder = (Viewholder) view.gettag (); }Else{view = Inflater.inflate (R.layout.whatever, parent,false); Holder =NewViewholder (view);    View.settag (holder); } holder.name.setText ("John Doe");//etc ...    returnView }StaticClass Viewholder {@Bind(r.id.title) TextView name;@Bind(R.id.job_title) TextView JobTitle; Public Viewholder(View view) {Butterknife.bind ( This, view); }  }}

You can see the specific application of these techniques in the examples provided above:

You can call Butterknife.bind from anywhere instead of calling Findviewbyid.

Other available binding APIs:

Binds a custom object, using an activity as the view root node. If you use a pattern like MVC, you can use its activity to bind the controller, with butterknife.bing (this, activity).

Use Butterknife.bind (this) to bind a view's child node field. You can call this method immediately if you use a node in your layout or a custom view constructor that uses inflate. Alternatively, a custom view type that is reflected from XML can be used in the Onfinishinflate callback method.

VIEW LISTS

You can organize complex views into a list or array.

@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })List<EditText> nameViews;

applymethod allows you to manipulate all the view in the list.

ButterKnife.apply(nameViews, DISABLE);ButterKnife.apply(nameViews, ENABLED, false);

Actionand Setter interfaces allow you to specifically declare simple performance

static  final  butterknife.action<view> DISABLE = new  butterknife.action<view> () { Span class= "hljs-annotation" > @Override public  void  apply  (View view, int  Index) {view.setenabled (false ); }}; static  final  Butterknife.setter<view, boolean> ENABLED = new  Butterknife.setter<view, Boolean> () { @Override  public  void  set  (view view, Boolean value, int  index) {view.setenabled (value); }};

Android Property (configuration information) can also be used in apply methods, as apply parameters of the method.

ButterKnife.apply(nameViews, View.ALPHA0.0f);
LISTENER BINDING

The listener can also be automatically configured into the method:

@OnClick(R.id.submit)publicvoidsubmit(View view) {  // TODO submit data to server...}

All parameters of the listening method can be manipulated:

@OnClick(R.id.submit)publicvoidsubmit() {  // TODO submit data to server...}

Define a specific type and it will be automatically converted by type

@OnClick(R.id.submit)publicvoidsayHi(Button button) {  button.setText("Hello!");}

Declaring multiple IDs in a separate binding for a common event operation

@OnClick({ R.id.door1, R.id.door2, R.id.door3 })public void pickDoor(DoorView door) {  if (door.hasPrizeBehind()) {    Toast.makeText"You win!", LENGTH_SHORT).show();  } else {    Toast.makeText"Try again", LENGTH_SHORT).show();  }}

Custom view can be tied to their own listener and does not need to specifically declare an ID.

publicclass FancyButton extends Button {  @OnClick  publicvoidonClick() {    // TODO do something!  }}
BINDING RESET

Fragment have different life cycles compared to activity. When binding in a fragment Oncreateview, you need to set the views to null in Ondestoryview. However, Butter knife has a Unbind method to do this automatically.

 Public  class fancyfragment extends Fragment {  @Bind(R.id.button1) Button button1;@Bind(r.id.button2) Button button2;@Override  PublicViewOncreateview(Layoutinflater inflater, ViewGroup container, Bundle savedinstancestate) {View view = Inflater.inflate (R.layout.fancy_fragment, container,false); Butterknife.bind ( This, view);//TODO use fields ...    returnView }@Override  Public void Ondestroyview() {Super. Ondestroyview (); Butterknife.unbind ( This); }}
OPTIONAL BINDINGS

By default, the bindings for @Bind and listeners are mandatory. If the target view is not found, an exception will be thrown.

To suppress this behavior and create an optional binding, add a @nullable annotation to the field or method

Note: Any annotations named @nullable can be used in this way. Encourage you to use the @nullable annotations in Android's own annotation library "Support-annotations", see Android Tools Project.

@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {  ...}
Multi-method LISTENERS

Listeners that match method annotations have multiple callbacks that can be used to bind to any one of them. Each annotation has a default callback bound to it. You can use callback parameters to declare an alternative callback.

@OnItemSelected(R.id.list_view)void onItemSelected(int position) {  ...}@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)void onNothingSelected() {  ...}
BONUS

Butter Knife also includes the FindByID method, which can still be used to find the target view in a view, Activity, or dialog.
It usually infers the type of the return value and then automatically casts the type.

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);ADDA static import for Butterknife. FindByID  andEnjoy even more fun.
Download

Butter knife v7.0.1 JAR Download
Butter Knife Github Address
Butter Knife Java Docs Address

Maven

If you compile with MAVEN, you can declare the library as your dependency

<dependency>  <groupId>com.jakewharton</groupId>  <artifactId>butterknife</artifactId>  <version>7.0.1</version></dependency>
GRADLE

Compile ' com.jakewharton:butterknife:7.0.1 '

Be sure to suppress this lint warning in your Build.gradle file.

lintOptions {  disable‘InvalidPackage‘}

Some configurations may also require separate processing

{  exclude ‘META-INF/services/javax.annotation.processing.Processor‘}
IDE CONFIGURATION

Some ides require additional configuration in order for annotations to be able to use the

    • IntelliJ idea--If your project uses additional configuration (such as Maven's Pom.xml), then the annotation process will work. If not, try manual configuration
    • eclipse--Setting Manual Configuration
Proguard

Butter knife dynamic generation and use of class, which means that static analysis tools like Proguard may think this is useless. In order to prevent them from being removed, it is clearly indicated that they will be kept. To prevent Proguard from renaming class, a @bind is used in the class to annotate a member variable, so you need to use Keepclasseswithmembernames.

The obfuscation code is as follows

-keep class butterknife.** { *; }-dontwarn butterknife.internal.**-keep class **$$ViewBinder { *; }-keepclasseswithmembernames class * {    @butterknife.* <fields>;}-keepclasseswithmembernames class * {    @butterknife.* <methods>;}
Summarize

The problems encountered in the project are as follows:

In the open source Chinese source code, Butter Knife uses: Butterknife.inject (this)

    @InjectView(R.id.quick_option_iv)    @Override    protectedvoidonCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        ButterKnife.inject(this);    }

While reading the official website Doc, found that the method does not exist, but is: Butterknife.bind (this)

@Bind (R. ID. TV1) TextView TV1;@Bind (R. ID. TV2) TextView TV2;@Bind (R. ID. TV3) TextView TV3;@Override protected void OnCreate (Bundle savedinstancestate) {Super. OnCreate(savedinstancestate);Setcontentview (R. Layout. Activity_main);Butterknife. Bind(this);Tv1. SetText("TV1");Tv2. SetText("TV2");Tv3. SetText("TV3");}

And the test inject in the code can not be used, and later found the reason:

  1. --butterknife-6.1.0.jar is used in open source China.
  2. The Official document is--butterknife-7.0.1.jar

Find the answer, this should be a version issue

About this kind of annotation, actually I do not like, the use of shortcut keys is not very troublesome, on the contrary, I always worry about excessive use of butterknife instead of looking for components to bring additional overhead, in short, there is a degree of the line

Open source Chinese source learning (vi) use of--butterknife

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.