Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

The principle and how to use ButterKnife

2025-01-19 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

The principle of ButterKnife and how to use it. In view of this problem, this article introduces the corresponding analysis and solution in detail, hoping to help more partners who want to solve this problem to find a more simple and feasible way.

Preface

In other words, the brothers of Android developers all know that every time the control is initialized and the corresponding event is set, the process of writing that point is numerous and disgusting. Let's first review the awkward past ~ those years, we initialized the control like this:

/ / it is customary to write an initView () method tvContent = (TextView) findViewById (R.id.btn_content) each time; / / when the project is big, it used to account for half of the total. Miserable / / of course, methods have been encapsulated to avoid all kinds of findViewById, but this is still the case.

In those years, we set events like this:

TvContent.setOnClickListener (this); / / of course, LZ's habits are still thrown into initView, allowing them to indulge and indulge.

But, Sao Nian, as an Android developer, can you continue to endure this unbearable devastation? The answer is of course not!

So, next, let's bring you an artifact to help us develop efficiently and quickly.

First acquaintance of ButterKnife

ButterKnife, also known as the butter knife, as to why it is jokingly called this, you can take a look at the attached icon~ intercepted from the official

A tablecloth, a plate, butter in the shape of an Android robot, a knife. Together, these are jokingly called butter knives. (I mean, I've been bothering me for a long time, but I don't know what a butter knife is, this time.) the simple explanation of icon is to provide binding fields and methods for Android View. In other words, we can use this knife to replace the trivial initialization in the future.

If you are interested, you can also go to the official website to have a look. Here is the address of the official website and an api address attached to the GitHub address.

Official address: http://jakewharton.github.io/butterknife/

GitHub address: https://github.com/JakeWharton/butterknife

API access address: http://jakewharton.github.io/butterknife/javadoc/

In other words, after a simple understanding, let's have some practical information. Otherwise, it doesn't make sense.

First of all, we have to understand that ButterKnife is an open source library from JakeWharton, the great god of Android, and its purpose is to simplify the amount of code (reducing the amount of code we wrote when we findViewById and set events) by annotating the method of binding views.

And when we use something, we have to know what its advantage is. What convenience can it bring me when I use it? So next, what are the advantages of this butter knife to simplify some of our code?

ButterKnife advantage

1. Powerful View binding, Click event handling and resource content, simplify code and improve development efficiency

two。 It is convenient to deal with ViewHolder binding in Adapter.

3. The running time will not affect the efficiency of APP, and it is easy to use and configure.

4. The code is clear and readable.

After learning about the advantages of ButterKnife, with curiosity, let's see what aspects he supports, in other words, under what circumstances can we reduce the amount of code we used to use ButterKnife in our development process?

ButterKnife usage scenario

View (view) binding: for example, initializing a control

Resource binding: for example, color,string, etc.

Non-Activity binding: it's worth using fragment at that time.

View List binding: ViewHolder in Adapter. Specific usage will be explained below.

Listener binding: this is easy to understand, that is, usually the control needs to listen to events.

ButterKnife syntax

1. Unbind activity fragment from fragment

To use ButterKnife, after a simple configuration, we also need to onCreate () binding in Activity, as follows:

@ Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState); setContentView (R.layout.activity_main); / / ButterKnife.bind (this) must be bound after setContentView ();}

If fragment is used, the official binding and unbinding are as follows:

Public class FancyFragment extends Fragment {@ BindView (R.id.button1) Button button1; @ BindView (R.id.button2) Button button2; private Unbinder unbinder; @ Override public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {View view = inflater.inflate (R.layout.fancy_fragment, container, false); / / bind unbinder = ButterKnife.bind (this, view); / / TODO Use fields... Return view;} @ Override public void onDestroyView () {super.onDestroyView (); / / unbind unbinder.unbind ();}}

After binding, let's take a look at several commonly used listeners. After using ButterKnife, how can we write related events? Don't worry, look down.

two。 Click event

First of all, let's take a look at what information we can get from the surface of our code that is useful to us.

First of all, it is clear that targetType (target type) is View,setter, which is setOnClickListener (click event listening), type is click event (butterknife.internal.DebouncingOnClickListener) encapsulated by ButterKnife, while in method, there are two parameters with name as doClick and parameters as View type. The following interface API requires us to pass an id.

After a brief understanding, we derive three kinds of writing methods, as follows:

/ / write 1 @ OnClick (control ID) void method name () {/ / business logic operation} / / write 2 @ OnClick (control ID) void method name (control type) {/ / business logic operation} / / write 3 @ OnClick (control ID) void method name (View view) { / / Business logic operation}

You can write one by one as specified above, or you can bind multiple ones, such as the following on the official website:

3. Long press event

It still depends on what other people write, to see what we can learn.

Compared with the click event, there is an extra returnType (return value) for a long time, and the default is false. So, written as follows ~

/ / method 1 boolean method name () {/ / business logic operation return false;} / / method 2 boolean method name (control type) {/ / business logic operation return false;} / / method 3 boolean method name (View view) {/ / business logic operation return false;}

4.Checked change event

The old rule:

Change, generally speaking, will provide us with a logo to facilitate us to deal with different logic according to different states, so...

/ / write 1 @ OnCheckedChanged (control ID) void radioButtonCheckChange (boolean isl) {/ / business logic} / / write 2 @ OnCheckedChanged (control ID) void radioButtonCheckChange (control type, boolean isl) {/ / business logic}

5. Listen for button events in the lower right corner of the soft keyboard

The old rule:

So... As you can see from the above, we only need to focus on parameters and whether it is returnType or not.

/ / write 1 @ OnEditorAction (control ID) boolean method name () {/ / business logic operation return false;} / / write 2 / / code: status code @ OnEditorAction (control ID) boolean EditTextAction (int code) {/ / business logic operation return false } / / KeyEvent @ OnEditorAction (control ID) boolean EditTextAction (KeyEvent keyEvent) {/ / business logic operation return false;} / / 4 @ OnEditorAction (control ID) boolean EditTextAction (int code, KeyEvent keyEvent) {/ / business logic operation return false } / / write 5 @ OnEditorAction (control ID) boolean EditTextAction (TextView textView,int code, KeyEvent keyEvent) {/ / business logic operation return false;}

6. EditText content change listening event

Because the content of the source code is long, it is not convenient to take screenshots, so capture part of the code for parsing, as follows:

@ Target (METHOD) @ Retention (CLASS) @ ListenerClass (targetType = "android.widget.TextView", setter = "addTextChangedListener", remover = "removeTextChangedListener", type = "android.text.TextWatcher",-> here also deals with the previous TextWatcher ggg callbacks = OnTextChanged.Callback.class-- > custom enumeration Identify the current operation by enumerating types) public @ interface OnTextChanged {/ * * View IDs to which the method will be bound. * / @ IdRes int [] value () default {View.NO_ID};-> ID / * * Listener callback to which the method will be bound is required. * / Callback callback () default Callback.TEXT_CHANGED;-- > unchanged status / * * {@ link TextWatcher} callback methods. The * / enum Callback {- > enumeration is divided into three categories that are similar to change before and after change / * * {@ link TextWatcher#onTextChanged (CharSequence, int, int, int)} * / @ ListenerMethod (name = "onTextChanged",-- > currently identified as unchanged parameters = {"java.lang.CharSequence" -> user input character "int",-> change the previous number "int",-> when testing Return 0, do not understand what it means "int"-> according to the printed result Guess that this should be the number of content added each time}) TEXT_CHANGED, / * {@ link TextWatcher#beforeTextChanged (CharSequence, int, int, int)} * / @ ListenerMethod (name = "beforeTextChanged",-- > parameters = {"java.lang.CharSequence" before the current identity is changed -> user input character "int",-- > change the previous number "int", "int"}) BEFORE_TEXT_CHANGED, / * {@ link TextWatcher#afterTextChanged (android.text.Editable)} * / @ ListenerMethod (name = "afterTextChanged") -> the current identity is changed to parameters = "android.text.Editable"-> user input characters) AFTER_TEXT_CHANGED,-> our focus is here. You only need to monitor this every time and do the relevant processing}.

We know from the above that with regard to the EditText content change event, we only care about whether the changed content format (number) meets the project requirements, while others can be ignored for the time being, thus deriving the following words:

/ / listen after content change / / Editable editable: user input character @ OnTextChanged (value = control ID, callback = listening type, value changed to: OnTextChanged.Callback.AFTER_TEXT_CHANGED) void editTextChangeAfter (Editable editable) {/ / business logic} / / listen before content change @ OnTextChanged (value = control ID, callback = listening type The value before changing is: OnTextChanged.Callback.BEFORE_TEXT_CHANGED) void editTextChangeBefore (CharSequence s, int start) {/ / business logic} / / content has not changed listening @ OnTextChanged (value = control ID, callback = listening type, value: OnTextChanged.Callback.TEXT_CHANGED) void editTextChange (CharSequence s, int start) {/ / business logic}

7. Focus monitoring event

The old rule:

Thus it can be seen as follows:

@ OnFocusChange (control ID) void editTextFocus (boolean isl) {/ / business logic}

8. Touch monitoring event

The old rule:

It is written as follows:

@ OnTouch (control ID) boolean imageView (MotionEvent event) {/ / business logic return false;}

9. Item item Click to listen for events

The old rule:

So...

@ OnItemClick (control ID) void listItemClick (int position) {/ / business logic}

10. Long press item to listen for events

The old rule:

So...

@ OnItemLongClick (R.id.listView) boolean listItemLongClick (int position) {Toast.makeText (this, "OnItemLongClick--- clicked the first" + position + ", Toast.LENGTH_SHORT) .show (); return true;}

Note when using ButterKnife

1.Activity ButterKnife.bind (this) must be followed by setContentView (), and after the parent class bind is bound, the subclass no longer needs to bind

View:Fragment ButterKnife.bind (this, mRootView) is required for use in 2.Fragment.

3. Attribute layout cannot be modified with private or static, otherwise an error will be reported.

4.setContentView () cannot be implemented through annotations. (some other annotation frameworks can)

Through the brief introduction above, I believe you have a preliminary understanding of this knife, so how to improve our code by using this knife in Android Studio? Let's move on.

Pre-preparation for Android Studio using ButterKnife

If you want to use ButterKnife in Android Studio, you need to download and install the ButterKnife plug-in first, and then use it after simple configuration.

Step 1: Android Studio integrates the ButterKnife plug-in

1. Click File-> Settings... -- > Select Plugins (you can also use the shortcut key Ctrl+Alt+S)

two。 Enter ButterKnife, select "Android ButterKnife Zelezny", and click install (LZ has been installed here). Later, Android Studio will prompt you to restart AS and confirm it.

3. After the above two simple steps, our Android Studio has get a new skill, that is: support the ButterKnife plug-in!

Step 2: configure ButterKnife

1. Before using it, we need to simply configure ButterKnife (to introduce 'com.jakewharton:butterknifecompiler:8.5.1','com.jakewharton:butterknife:8.5.1' for our project). The introduction process is as follows:

two。 After the introduction is complete, let's try it out first.

Right-click layout in onCreate in MainActivity and select Generate... , Generate ButterKnife Injections, select the control you want to use annotations, and click Confirm

One-click visual operation, convenient and quick ~ after entering the above configuration, we can use all kinds of ButterKnife shows in the project.

The knife method is a song, which is often used to monitor events.

1. Add several common controls to the MainActivity layout. Right-click layout and select Generate.... , Generate ButterKnife Injections, select the control for which you want to use annotations, and click Confirm to generate our next demo base (which will be changed later), as shown in the following figure ~

Next, I'll show you the use of related events, playing butter knife a little bit.

1. Click event (take TextView as an example)

The code is as follows:

@ OnClick (R.id.text) void textClick () {Toast.makeText (MainActivity.this, "click event triggered by TextView. (no parameter-default) ", Toast.LENGTH_SHORT) .show ();} @ OnClick (R.id.text) void textClick (TextView textView) {Toast.makeText (MainActivity.this," Click event trigger for TextView. (TextView) ", Toast.LENGTH_SHORT) .show ();} @ OnClick (R.id.text) void textClick (View view) {Toast.makeText (MainActivity.this," Click event triggered by TextView. (View) ", Toast.LENGTH_SHORT. Show ();}

Show the running results:

two。 Long press event (take Button as an example)

The code is as follows:

@ OnLongClick (R.id.button) boolean buttonLongClick () {Toast.makeText (MainActivity.this, "long press event trigger of Button. (no parameter-default) ", Toast.LENGTH_SHORT) .show (); return false;} / / @ OnLongClick (R.id.button) / / boolean buttonLongClick (Button button) {/ / Toast.makeText (MainActivity.this," long press event trigger for Button. (TextView) ", Toast.LENGTH_SHORT) .show (); / / return false; / /} / / @ OnLongClick (R.id.button) / / boolean buttonLongClick (View view) {/ / Toast.makeText (MainActivity.this," long press event trigger of Button. (View) ", Toast.LENGTH_SHORT) .show (); / / return false; / /}

The running results are as follows:

Here you may ask, LZ, why did you leave out the comments below? can you not use them? Indeed, there were no comments at first, and an exception occurred at run time, with the following prompt:

Multiple listener methods with return value specified for ID:2131165193

LZ understands that this snooping will only return the corresponding snooping for ID (2131165193), that is, one-to-one so.... There is no room for two tigers in one mountain, unless one male and one female.

3. Checked change event (take CheckBox as an example)

The code is as follows:

@ OnCheckedChanged (R.id.checkBox) void radioButtonCheckChange (boolean isl) {Toast.makeText (MainActivity.this, "CheckBox.). (no reference)" + isl, Toast.LENGTH_SHORT). Show ();} @ OnCheckedChanged (R.id.checkBox) void radioButtonCheckChange (CheckBox checkBox,boolean isl) {Toast.makeText (MainActivity.this, "CheckBox.. (CheckBox)" + isl, Toast.LENGTH_SHORT). Show ();}

The running results are as follows:

4. Listen for button events in the lower right corner of the soft keyboard

The code is as follows:

/ / @ OnEditorAction (R.id.tv_editor_action) / / boolean EditTextAction () {/ / Toast.makeText (MainActivity.this, "Click-to Heaven without reference", Toast.LENGTH_SHORT). Show (); / / return false / /} / / @ OnEditorAction (R.id.tv_editor_action) / / boolean EditTextAction (int code) {/ / Toast.makeText (MainActivity.this, "Click-to Heaven code:" + code, Toast.LENGTH_SHORT). Show (); / / return false / /} / / @ OnEditorAction (R.id.tv_editor_action) / / boolean EditTextAction (KeyEvent keyEvent) {/ / Toast.makeText (MainActivity.this, "Click-to Heaven KeyEvent:" + keyEvent, Toast.LENGTH_SHORT). Show (); / / return false / /} / / @ OnEditorAction (R.id.tv_editor_action) / / boolean EditTextAction (int code, KeyEvent keyEvent) {/ / Toast.makeText (MainActivity.this, "Click-to Heaven code:" + code+ "KeyEvent:" + keyEvent, Toast.LENGTH_SHORT). Show (); / / return false / /} @ OnEditorAction (R.id.tv_editor_action) boolean EditTextAction (TextView textView,int code, KeyEvent keyEvent) {Toast.makeText (MainActivity.this, textView.getText (). ToString () + "Click-to Heaven code:" + code+ "KeyEvent:" + keyEvent, Toast.LENGTH_SHORT). Show (); return false;}

Under the running effect:

5. EditText content change listening event

The code is as follows:

@ OnTextChanged (value = R.id.editText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED) void editTextChangeAfter (Editable editable) {Toast.makeText (MainActivity.this, "changed content is:" + editable.toString (), Toast.LENGTH_SHORT) .show (); System.out.println ("changed-content is:" + editable.toString ()) } @ OnTextChanged (value = R.id.editText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED) void editTextChangeBefore (CharSequence s, int start, int before, int count) {Toast.makeText (MainActivity.this, "editing content is:" + s + ", before starting:" + start, Toast.LENGTH_SHORT). Show () System.out.println ("before change-content is:" + s + ", number before starting:" + start+ "," + before+ "," + count ") } @ OnTextChanged (value = R.id.editText, callback = OnTextChanged.Callback.TEXT_CHANGED) void editTextChange (CharSequence s, int start, int before, int count) {Toast.makeText (MainActivity.this, "editing content is:" + s + ", before starting:" + start, Toast.LENGTH_SHORT). Show () System.out.println ("unedited-content:" + s + ", the number before starting:" + start+ "," + before+ "," + count);}

The running results are as follows:

6. Focus monitoring event

The code is as follows:

@ OnFocusChange (R.id.editTextFocus) void editTextFocus (boolean isl) {if (isl) {Toast.makeText (MainActivity.this, "get focus" + isl, Toast.LENGTH_SHORT). Show ();} else {Toast.makeText (MainActivity.this, "lose focus" + isl, Toast.LENGTH_SHORT). Show ();}}

The running results are as follows:

7. Touch monitoring event

The code is as follows:

@ OnTouch (R.id.imageView) boolean imageView (MotionEvent event) {System.out.println (event); return false;}

The running results are as follows:

04-10 11 action=ACTION_DOWN 47 action=ACTION_DOWN, actionButton=0, id [0] = 0, x [0] = 189.8265, y [0] = 148.42676, toolType [0] = TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=6743683, downTime=6743683, deviceId=1, source=0x1002}

8. Item click and long press to listen for events

The code is as follows:

@ OnItemClick (R.id.listView) void listItemClick (int position) {Toast.makeText (this, "OnItemClick--- clicked" + position+ ", Toast.LENGTH_SHORT). Show ();} @ OnItemLongClick (R.id.listView) boolean listItemLongClick (int position) {Toast.makeText (this," OnItemLongClick--- clicked "+ position+", Toast.LENGTH_SHORT). Show (); return true;}

The running results are as follows:

Presumably everyone has mastered the basic use of this set of knives through the above, so it has been said above that Adapter can also be modified to save some code in the development process, so let's take a look.

The second part of Dao method, skillfully using Adapter

Create an item_layout for the next demonstration ~

It's very simple. It's nothing. Let's take a look at adapter~.

Package cn.hlq.butterknifestudy.adapter; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; import java.util.ArrayList; import java.util.List; import butterknife.BindView; import butterknife.ButterKnife; import cn.hlq.butterknifestudy.R; import cn.hlq.butterknifestudy.model.Student; / * Created by HLQ on 2017-4-11 0011. * / public class ListViewAdapter extends BaseAdapter {private Context context; private List stuList = new ArrayList (); public ListViewAdapter (Context context, List stuList) {this.context = context; this.stuList = stuList;} @ Override public int getCount () {return stuList! = null? StuList.size (): 0;} @ Override public Object getItem (int position) {return stuList! = null? StuList.get (position): null;} @ Override public long getItemId (int position) {return position;} @ Override public View getView (int position, View convertView, ViewGroup parent) {ViewHolder viewHolder = null; if (viewHolder = = null) {convertView = LayoutInflater.from (context) .propagate (R.layout.item_listview_show, null); viewHolder = new ViewHolder (convertView) ConvertView.setTag (viewHolder);} else {viewHolder = (ViewHolder) convertView.getTag ();} Student stu = stuList.get (position); viewHolder.itemUsername.setText (stu.getUserName ()); viewHolder.itemUserPwd.setText (stu.getUserPwd ()); return convertView } static class ViewHolder {@ BindView (R.id.item_username) TextView itemUsername; @ BindView (R.id.item_userPwd) TextView itemUserPwd; ViewHolder (View view) {ButterKnife.bind (this, view);}

The running result is:

To tell you a little secret, you can right-click layout and choose to create ViewHolder automatically when generating annotations, as shown below:

Isn't it quite convenient? Here, by the way, with the introduction of feet, how to use this knife to play with resource content?

/ / initialize the specified default value @ BindString (R.string.app_test) String titleContent; lvTitle.setText (titleContent)

The running results are as follows:

In addition to the above, the knife method also includes the following support, if you are interested in understanding for yourself, it is not difficult.

And some basic uses are officially provided, as follows:

Knife trilogy BaseActivity package to further simplify the code

Usually we encapsulate a BaseActivity with common content written in it, and then activity inherits the BaseActivity. Similarly, we can also initialize here to prevent us from initializing many times. Take a look at the following wave of code ~

Package com.heliquan.butterknife.base; import android.app.Activity; import android.content.Context; import android.os.Bundle; import android.support.annotation.LayoutRes; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; import butterknife.ButterKnife; import butterknife.Unbinder; / * created by heliquan at 14 April 2017 * / public abstract class BaseActivity extends Activity {private Unbinder unbinder; @ Override protected void onCreate (Bundle savedInstanceState) {super.onCreate (savedInstanceState) / / the three methods of setContentView () must be overridden, otherwise the subclass inheritance will be invalid. The specific reasons are not in-depth understanding of setContentView (getContentViewId ()); unbinder = ButterKnife.bind (this);} @ Override public void setContentView (@ LayoutRes int layoutResID) {super.setContentView (layoutResID); unbinder = ButterKnife.bind (this) } @ Override public void setContentView (View view) {super.setContentView (view); unbinder = ButterKnife.bind (this);} @ Override public void setContentView (View view, ViewGroup.LayoutParams params) {super.setContentView (view, params); unbinder = ButterKnife.bind (this);} / * * get content id * / protected abstract int getContentViewId () / * initialize View * / protected abstract void initView (); @ Override protected void onDestroy () {super.onDestroy (); unbinder.unbind () } / * * return resource content based on id * * @ param context * @ param strId * @ return * / protected String getStrResource (Activity activity, int strId) {return activity.getResources () .getString (strId) } / * listen back button, click to return to the finish current page * * @ param keyCode * @ param event * @ return * / @ Override public boolean onKeyDown (int keyCode, KeyEvent event) {if (keyCode = = KeyEvent.KEYCODE_BACK & & event.getRepeatCount () = 0) {finish (); return true } return super.onKeyDown (keyCode, event);}} this is the answer to the question about the principle of ButterKnife and how to use it. I hope the above content can be of some help to you. If you still have a lot of doubts to be solved, you can follow the industry information channel for more related knowledge.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report