Original address: http://stormzhang.com/openandroid/android/2014/01/12/android-butterknife/
As the saying goes, "A programmer who is not lazy is not a good programmer!" As an Android developer, are you often tired of a lot of findViewById and setOnClickListener code? ButterKnife It's a View Injection Framework that focuses on Android systems, freeing you from all this cumbersome code. Let's start with a code example to illustrate how ButterKnife simplifies the code:
Note: If you are using Eclipse to reference the library, you need to refer to it here. Eclipse Configuration Make some configurations, or you'll run incorrectly.
class ExampleActivity extends Activity { TextView title; TextView subtitle; TextView footer; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.simple_activity); title = (TextView) findViewById(R.id.title); subtitle = (TextView) findViewById(R.id.subtitle); footer = (TextView) findViewById(R.id.footer); // TODO Use views... } }
The code after using ButterKnife is as follows:
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... } }
Is it very simple and easy to use? Here is a systematic introduction to the use of ButterKnife.
Characteristics of Butter Knife
-
Support View Injection in Activity
-
Support View Injection in View
-
Support for View Event Callback Function Injection
The following event callback functions are currently supported:
-
View: @OnLongClick and @OnFocusChanged.
-
TextView: @OnEditorAction.
-
AdapterView: @OnItemClick and @OnItemLongClick.
-
CompoundButton: @OnCheckedChanged.
Let's look at some injected sample code:
Injection into Activity
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... } }
Injection in Fragment
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; } }
Injection in ViewHolder mode
public class MyAdapter extends BaseAdapter { @Override public View getView(int position, View view, ViewGroup parent) { 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; } static class ViewHolder { @InjectView(R.id.title) TextView name; @InjectView(R.id.job_title) TextView jobTitle; public ViewHolder(View view) { ButterKnife.inject(this, view); } } }
Injection callback function
Following are several examples of methods for injecting callback functions:
// With Button parameter @OnClick(R.id.submit) public void sayHi(Button button) { button.setText("Hello!"); } // Without parameters @OnClick(R.id.submit) public void submit() { // TODO submit data to server... } // Injecting multiple View events at the same time @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(); } }
Reset function
If you need to set the injected View to Null when the interface is destroyed, you can use the reset function:
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(); Views.reset(this); } }
Optional View Injection is also supported. If the View does not exist, it will not:
@Optional @InjectView(R.id.might_not_be_there) TextView mightNotBeThere; @Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() { // TODO ... }
There are also two findViewById functions to simplify the way you look for Views. If none of them meets your needs, you can use them:
View view = LayoutInflater.from(context).inflate(R.layout.thing, null); TextView firstName = Views.findById(view, R.id.first_name); TextView lastName = Views.findById(view, R.id.last_name); ImageView photo = Views.findById(view, R.id.photo);
Finally, if you use Android Studio as an IDE, there is a ButterKnife plug-in android-butterknife-zelezny This plug-in allows you to manually generate the injection code mentioned above, thus making yourself a lazier programmer. Let's take a screenshot.