前言

成都创新互联是一家专业提供长宁企业网站建设,专注与成都网站制作、网站设计、H5开发、小程序制作等业务。10年已为长宁众多企业、政府机构等服务。创新互联专业网站建设公司优惠进行中。
话说,Android开发的兄弟们都知道,每次初始化控件,设置相应的事件,写的那点过程多而且恶心。我们先一块回顾下不堪的曾经~那些年,我们是这样初始化控件:
- // 每次的习惯上来写一个initView()方法
 - tvContent = (TextView) findViewById(R.id.btn_content);
 - // 遇到项目大的时候,这里面的东西,也曾占据半壁江山。苦不堪言
 - // 当然也曾封装过方法,避免各种findViewById,但是依旧如此。
 
那些年,我们是这样设置事件:
- tvContent.setOnClickListener(this);
 - // 当然,LZ的习惯依旧扔到initView中,让他们尽情的浪荡,放纵~
 
But,骚年,身为一个Android开发,你还能继续忍受这种不堪的摧残么?答案当然不能!
那么,接下来为大家带来一个神器,助我们开发高效,快捷~
Butterknife 初识
ButterKnife,又被戏称为黄油刀,至于为什么被戏称为这个,大家可以看下面附上的从官方截取的icon~
一块桌布,一个盘子,一个Android小机器人形状的黄油,一把刀。这些合起来被大家戏称为黄油刀。(我说呢,纠结我半天,都搞不懂黄油刀是个什么鬼,这次晓得了)icon下面简单解释就是为Android 视图(View)提供绑定字段和方法。 也就是说,我们今后可以通过这把刀去替换之前琐碎的初始化~
大家有兴趣的也可以去官网上看看,下面为大家附上官网地址以及GitHub地址捎带的附带个api地址。
官方地址:http://jakewharton.github.io/butterknife/
GitHub地址:https://github.com/JakeWharton/butterknife
API访问地址:http://jakewharton.github.io/butterknife/javadoc/
话说,简单了解之后,还是来点干货吧~不然说不过去哈
首先我们要明白,ButterKnife 是出自Android大神JakeWharton之手的一个开源库,它的作用就是通过注解绑定视图的方法,从而简化代码量(减少我们当年findViewById以及设置事件时编写的大量代码)。
而我们使用一个东西,必须要知道他的优势在哪儿?我用它能给我带来什么方便之处?那么接下来,我们看看这把“黄油刀”有着什么样的优势,从而能简化我们一些代码?
ButterKnife 优势
1. 强大的View绑定,Click事件处理功能以及资源内容,简化代码,提升开发效率;
2. 方便的处理Adapter里的ViewHolder绑定问题;
3. 运行时不会影响APP效率,使用配置方便;
4. 代码清晰,可读性强。
了解完ButterKnife优势后,怀着好奇心,我们看看他都支持哪儿些方面,换句话说就是,我们开发过程中,在什么情况下可以通过使用ButterKnife去减少我们曾经的代码量?
ButterKnife 使用场景
ButterKnife 语法
1. activity fragment 绑定与 fragment解绑
想要使用ButterKnife,简单配置之后,我们还需要在Activity中onCreate()绑定,如下:
- @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - setContentView(R.layout.activity_main);
 - // 必须在setContentView()之后绑定
 - ButterKnife.bind(this);
 - }
 
而如果使用fragment,官方给出的绑定以及解绑如下:
- 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);
 - // 绑定
 - unbinder = ButterKnife.bind(this, view);
 - // TODO Use fields...
 - return view;
 - }
 - @Override public void onDestroyView() {
 - super.onDestroyView();
 - // 解绑
 - unbinder.unbind();
 - }
 - }
 
绑定之后,我们一起来看看,常用的几种监听通过使用ButterKnife之后,我们又该如何编写相关事件呢?别急,往下看~
2.单击事件
首先我们先看看人家表层提供我们代码中,我们可以得到哪儿些对我们有用的信息
首先明确,targetType(目标类型)为View,setter为setOnClickListener(单击事件监听),type为ButterKnife封装的单击事件(butterknife.internal.DebouncingOnClickListener),而method中则是name为doClick以及parameters为View类型的俩个参数;而下面的interface接口中需要我们传递一个id。
简单了解后,我们衍生出三种写法,如下:
- // 写法1
 - @OnClick(控件ID)
 - void 方法名() {
 - //业务逻辑操作
 - }
 - // 写法2
 - @OnClick(控件ID)
 - void 方法名(控件类型) {
 - //业务逻辑操作
 - }
 - // 写法3
 - @OnClick(控件ID)
 - void 方法名(View view) {
 - //业务逻辑操作
 - }
 
你可以按照上面指定一个个的写,也可以绑定多个,如官网提供下面写法:
3.长按事件
同样依旧看人家怎么写的,看看我们能了解到什么
和单击事件对比,长按时间则多出了一个returnType(返回值),且默认为false。So,写法如下~
- // 方法1
 - boolean 方法名(){
 - // 业务逻辑操作
 - return false;
 - }
 - // 方法2
 - boolean 方法名(控件类型){
 - // 业务逻辑操作
 - return false;
 - }
 - // 方法3
 - boolean 方法名(View view){
 - // 业务逻辑操作
 - return false;
 - }
 
4.Checked改变事件
老规矩:
改变,一般来说,会提供我们一个标识,去方便我们根据不同的状态去处理不同的逻辑,so...
- // 写法1
 - @OnCheckedChanged(控件ID)
 - void radioButtonCheckChange(boolean isl) {
 - // 业务逻辑
 - }
 - // 写法2
 - @OnCheckedChanged(控件ID)
 - void radioButtonCheckChange(控件类型,boolean isl) {
 - // 业务逻辑
 - }
 
5.监听软键盘右下角按钮事件
老规矩:
so...经过上面几个大家可以知道,我们只需要对parameters以及是否是returnType重点关注即可。
- // 写法1
 - @OnEditorAction(控件ID)
 - boolean 方法名() {
 - // 业务逻辑操作
 - return false;
 - }
 - // 写法2
 - // code:状态码
 - @OnEditorAction(控件ID)
 - boolean EditTextAction(int code) {
 - // 业务逻辑操作
 - return false;
 - }
 - // 写法3
 - // KeyEvent
 - @OnEditorAction(控件ID)
 - boolean EditTextAction(KeyEvent keyEvent) {
 - // 业务逻辑操作
 - return false;
 - }
 - // 写法4
 - @OnEditorAction(控件ID)
 - boolean EditTextAction(int code, KeyEvent keyEvent) {
 - // 业务逻辑操作
 - return false;
 - }
 - // 写法5
 - @OnEditorAction(控件ID)
 - boolean EditTextAction(TextView textView,int code, KeyEvent keyEvent) {
 - // 业务逻辑操作
 - return false;
 - }
 
6. EditText内容改变监听事件
由于源码中内容较长,不方便截图,故截取部分代码做解析,如下:
- @Target(METHOD)
 - @Retention(CLASS)
 - @ListenerClass(
 - targetType = "android.widget.TextView",
 - setter = "addTextChangedListener",
 - remover = "removeTextChangedListener",
 - type = "android.text.TextWatcher", ---> 这里同样对之前的TextWatcher做了相关处理 ggg
 - callbacks = OnTextChanged.Callback.class ---> 自定义枚举,通过枚举类型标识当前操作 666
 - )
 - 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. */
 - Callback callback() default Callback.TEXT_CHANGED; ---> 未改变状态
 - /** {@link TextWatcher} callback methods. */
 - enum Callback { ---> 枚举中分为三种类似 未改变 改变前 改变后
 - /** {@link TextWatcher#onTextChanged(CharSequence, int, int, int)} */
 - @ListenerMethod(
 - name = "onTextChanged", ---> 当前标识为 未改变
 - parameters = {
 - "java.lang.CharSequence", ---> 用户输入字符
 - "int", ---> 改变前个数
 - "int", ---> 测试时,返回0,没整明白代表什么意思
 - "int" ---> 根据打印结果,猜测这个应该是每次增加内容个数
 - }
 - )
 - TEXT_CHANGED,
 - /** {@link TextWatcher#beforeTextChanged(CharSequence, int, int, int)} */
 - @ListenerMethod(
 - name = "beforeTextChanged", ---> 当前标识为 改变前
 - parameters = {
 - "java.lang.CharSequence", ---> 用户输入字符
 - "int", ---> 改变前个数
 - "int",
 - "int"
 - }
 - )
 - BEFORE_TEXT_CHANGED,
 - /** {@link TextWatcher#afterTextChanged(android.text.Editable)} */
 - @ListenerMethod(
 - name = "afterTextChanged", ---> 当前标识为 改变后
 - parameters = "android.text.Editable" ---> 用户输入字符
 - )
 - AFTER_TEXT_CHANGED, ---> 我们关注的重点在此,每次只需要监听这个,去做相关处理即可
 - }
 
从上得知,关于EditText内容改变事件,我们关注点只在乎改变后的内容格式(个数)是否符合项目需求,而其他可以暂时忽略,从而衍生下面写法:
- // 内容改变后监听
 - // Editable editable:用户输入字符
 - @OnTextChanged(value = 控件ID, callback = 监听类型,改变后取值为:OnTextChanged.Callback.AFTER_TEXT_CHANGED)
 - void editTextChangeAfter(Editable editable) {
 - // 业务逻辑
 - }
 - // 内容改变前监听
 - @OnTextChanged(value = 控件ID, callback = 监听类型,改变前取值为:OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
 - void editTextChangeBefore(CharSequence s, int start) {
 - // 业务逻辑
 - }
 - // 内容未发生改变监听
 - @OnTextChanged(value = 控件ID, callback = 监听类型,取值为:OnTextChanged.Callback.TEXT_CHANGED)
 - void editTextChange(CharSequence s, int start) {
 - // 业务逻辑
 - }
 
7. 焦点监听事件
老规矩:
由此可见,如下:
- @OnFocusChange(控件ID)
 - void editTextFocus(boolean isl){
 - // 业务逻辑
 - }
 
8. 触摸监听事件
老规矩:
写法如下:
- @OnTouch(控件ID)
 - boolean imageView(MotionEvent event){
 - // 业务逻辑
 - return false;
 - }
 
9. item项单击监听事件
老规矩:
so...
- @OnItemClick(控件ID)
 - void listItemClick(int position){
 - // 业务逻辑
 - }
 
10. item项长按监听事件
老规矩:
so...
- @OnItemLongClick(R.id.listView)
 - boolean listItemLongClick(int position) {
 - Toast.makeText(this, "OnItemLongClick---点击了第" + position + "个", Toast.LENGTH_SHORT).show();
 - return true;
 - }
 
ButterKnife 使用注意
1.Activity ButterKnife.bind(this) 必须在 setContentView() 之后,且父类 bind 绑定后,子类不需要再 bind;
2.Fragment 中使用需要传入view:Fragment ButterKnife.bind(this, mRootView);
3.属性布局不能用private or static 修饰,否则会报错;
4.setContentView()不能通过注解实现。(其他的有些注解框架可以)
通过上面简单介绍,相信大家对这把刀已经有了一个初步的理解,那么如何在Android Studio中通过使用这把刀从而改善我们的代码呢?我们接着往下瞧。
Android Studio使用ButterKnife前期准备操作
想要在Android Studio中使用ButterKnife,首先需要下载安装ButterKnife插件,之后经过简单配置之后方可使用~
***步:Android Studio集成ButterKnife插件
1.点击 File ---> Settings... ---> 选择 Plugins(也可以使用快捷键 Ctrl+Alt+S)
2.输入ButterKnife,选择“Android ButterKnife Zelezny”,点击安装(LZ这里已经安装好了),稍后Android Studio会提示重启AS,确认即可。
3.经过以上简单俩步,我们的Android Studio又get了新技能,那就是:支持ButterKnife插件!
第二步:配置ButterKnife
1.使用前,我们需要对ButterKnife进行简单配置( 为我们的项目引入'com.jakewharton:butterknifecompiler:8.5.1','com.jakewharton:butterknife:8.5.1' ),引入过程如下所示:
2.引入完成之后,我们先来小试牛刀~得瑟得瑟
在MainActivity中的onCreate 右键layout,选择Generate... ,Generate ButterKnife Injections,选择要使用注解的控件,点击Confirm
一键可视化操作,方便快捷~进过上面的配置后,我们可以在项目中尽情的使用ButterKnife各种秀了~
刀法一部曲,玩转常用事件监听
1.在MainActivity布局中新增几个常用控件,通过右键layout,选择Generate... ,Generate ButterKnife Injections,选择要使用注解的控件,点击Confirm ,从而生成我们接下来演示根本(后面会有所更改),如下图所示~
接下来为大家演示相关事件使用,一点点玩转黄油刀
1. 单击事件(以TextView为例)
代码如下:
- @OnClick(R.id.text)
 - void textClick() {
 - Toast.makeText(MainActivity.this, "TextView的单击事件触发。(无参-默认)", Toast.LENGTH_SHORT).show();
 - }
 - @OnClick(R.id.text)
 - void textClick(TextView textView){
 - Toast.makeText(MainActivity.this, "TextView的单击事件触发。(TextView)", Toast.LENGTH_SHORT).show();
 - }
 - @OnClick(R.id.text)
 - void textClick(View view){
 - Toast.makeText(MainActivity.this, "TextView的单击事件触发。(View)", Toast.LENGTH_SHORT).show();
 - }
 
运行结果展示:
2. 长按事件(以Button为例)
代码如下:
- @OnLongClick(R.id.button)
 - boolean buttonLongClick(){
 - Toast.makeText(MainActivity.this, "Button的长按事件触发。(无参-默认)", Toast.LENGTH_SHORT).show();
 - return false;
 - }
 - // @OnLongClick(R.id.button)
 - // boolean buttonLongClick(Button button){
 - // Toast.makeText(MainActivity.this, "Button的长按事件触发。(TextView)", Toast.LENGTH_SHORT).show();
 - // return false;
 - // }
 - // @OnLongClick(R.id.button)
 - // boolean buttonLongClick(View view){
 - // Toast.makeText(MainActivity.this, "Button的长按事件触发。(View)", Toast.LENGTH_SHORT).show();
 - // return false;
 - // }
 
运行结果如下:
这里大家可能会问了,LZ你干嘛要把下面的注释掉了呢,是不是不能用呢?确实,一开始没有注释,运行时候出现异常,提示如下:
- Multiple listener methods with return value specified for ID:2131165193
 
LZ理解为,这个监听只会为ID(2131165193)返回相应监听,也就是一一对应!so... 一山不容二虎,除非一公一母啊~
3. Checked改变事件(以CheckBox为例)
代码如下:
- @OnCheckedChanged(R.id.checkBox)
 - void radioButtonCheckChange(boolean isl) {
 - Toast.makeText(MainActivity.this, "CheckBox。(无参)" + 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();
 - }
 
运行结果如下:
4. 监听软键盘右下角按钮事件
代码如下:
- // @OnEditorAction(R.id.tv_editor_action)
 - // boolean EditTextAction() {
 - // Toast.makeText(MainActivity.this, " 点击---通往天堂 无参", Toast.LENGTH_SHORT).show();
 - // return false;
 - // }
 - // @OnEditorAction(R.id.tv_editor_action)
 - // boolean EditTextAction(int code) {
 - // Toast.makeText(MainActivity.this, " 点击---通往天堂 code:"+code, Toast.LENGTH_SHORT).show();
 - // return false;
 - // }
 - // @OnEditorAction(R.id.tv_editor_action)
 - // boolean EditTextAction(KeyEvent keyEvent) {
 - // Toast.makeText(MainActivity.this, "点击---通往天堂 KeyEvent:"+keyEvent, Toast.LENGTH_SHORT).show();
 - // return false;
 - // }
 - // @OnEditorAction(R.id.tv_editor_action)
 - // boolean EditTextAction(int code, KeyEvent keyEvent) {
 - // Toast.makeText(MainActivity.this, "点击---通往天堂 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()+" 点击---通往天堂 code:"+code+" KeyEvent:"+keyEvent, Toast.LENGTH_SHORT).show();
 - return false;
 - }
 
运行效果下:
5. EditText内容改变监听事件
代码如下:
- @OnTextChanged(value = R.id.editText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
 - void editTextChangeAfter(Editable editable) {
 - Toast.makeText(MainActivity.this, "改变后内容为:"+editable.toString(), Toast.LENGTH_SHORT).show();
 - System.out.println("改变后---内容为:"+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, "编辑内容为:"+s+",开始前个数:"+start, Toast.LENGTH_SHORT).show();
 - System.out.println("改变前---内容为:"+s+",开始前个数:"+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, "编辑内容为:"+s+",开始前个数:"+start, Toast.LENGTH_SHORT).show();
 - System.out.println("未编辑---内容为:"+s+",开始前个数:"+start+","+before+","+count);
 - }
 
运行结果如下:
6.焦点监听事件
代码如下:
- @OnFocusChange(R.id.editTextFocus)
 - void editTextFocus(boolean isl) {
 - if (isl) {
 - Toast.makeText(MainActivity.this, "获取焦点" + isl, Toast.LENGTH_SHORT).show();
 - } else {
 - Toast.makeText(MainActivity.this, "失去焦点" + isl, Toast.LENGTH_SHORT).show();
 - }
 - }
 
运行结果如下:
7. 触摸监听事件
代码如下:
- @OnTouch(R.id.imageView)
 - boolean imageView(MotionEvent event){
 - System.out.println(event);
 - return false;
 - }
 
运行结果如下:
- 04-10 11:47:04.504 32627-32627/cn.hlq.butterknifestudyI/System.out: MotionEvent { 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单击以及长按监听事件
代码如下:
- @OnItemClick(R.id.listView)
 - void listItemClick(int position){
 - Toast.makeText(this,"OnItemClick---点击了第"+position+"个",Toast.LENGTH_SHORT).show();
 - }
 - @OnItemLongClick(R.id.listView)
 - boolean listItemLongClick(int position) {
 - Toast.makeText(this, "OnItemLongClick---点击了第" + position + "个", Toast.LENGTH_SHORT).show();
 - return true;
 - }
 
运行结果如下:
想必大家通过以上已经掌握这套刀法基本使用了,那么上面曾说过,还可以对Adapter进行改造,从而节省开发过程中一些编码,那就一块瞅瞅呗~
刀法二部曲,巧用Adapter
创建一个item_layout作为接下来演示用~
- android:layout_width="match_parent"
 - android:layout_height="wrap_content"
 - android:orientation="horizontal">
 - android:id="@+id/item_username"
 - android:layout_width="0dp"
 - android:layout_height="wrap_content"
 - android:layout_gravity="center_vertical"
 - android:layout_weight="1"/>
 - android:id="@+id/item_userPwd"
 - android:layout_width="0dp"
 - android:layout_height="wrap_content"
 - android:layout_gravity="center_vertical"
 - android:layout_weight="1"/>
 
很简单,没什么东西,接下来看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).inflate(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);
 - }
 - }
 - }
 
运行结果为:
在此告诉大家一个小秘密,你可以直接右键layout,在生成注解时,选择自动创建ViewHolder,如下图:
是不是相当方便?在此,顺便捎带脚的介绍下,如何使用这把刀玩玩资源内容呢?
- // 初始化指定默认值
 - @BindString(R.string.app_test)
 - String titleContent;
 - lvTitle.setText(titleContent);
 
运行结果如下:
[[194039]]
除以上,刀法中还包含对以下支持,大家有兴趣自己了解即可,没什么难度了
而且官方上也提供了一些基本的使用,如下:
刀法三部曲BaseActivity封装,进一步简化代码
通常我们会封装一个BaseActivity,里面写好常用内容,之后activity继承此BaseActivity。同样我们也可以在此进行初始化,避免我们多次初始化,看下面一波代码~
- 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 2017年4月14日
 - */
 - public abstract class BaseActivity extends Activity {
 - private Unbinder unbinder;
 - @Override
 - protected void onCreate(Bundle savedInstanceState) {
 - super.onCreate(savedInstanceState);
 - // 必须重写setContentView()的三个方法,不然会出现子类继承无效,具体原因没有深入了解
 - 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
 当前名称:一篇文章玩转ButterKnife,让代码更简洁
URL标题:http://www.csdahua.cn/qtweb/news32/519132.html网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网