依赖注入ButterKnife

来源:互联网 发布:淘宝网商城女装斗篷 编辑:程序博客网 时间:2024/06/17 22:50

          在Android开发中,需要大量的编写初始化布局、点击事件、监听事件等一些简单重复的代码,会无形中浪费时间和精力。而使用ButterKnife这个开源库可以让我们从大量的findViewById()和setOnclicktListener()中解放出来。

   ButterKnife:是视图注入中相对简单易懂的开源框架,其优势在于:
      1. 强大的View绑定和Click事件处理功能,简单代码,提高开发效率
      2. 方便的处理Adapter和ViewHolder绑定问题
      3. 提高APP运行效率,使用配置方便
      4. 代码清晰,可读性强

    参考资料:

    ButterKnife官网:http://jakewharton.github.io/butterknife/

      在实际使用时,为了提高效率,也可以在Studio中使用插件:Android ButterKnife Aelezny

               

              ButterKnife使用心得:                 

     1.ButtKnife初始化ButterKnife.bind(this)必须在setContentView()之后,所以ButterKnife不能在Application中初始化。

    2.ButtKnife在Fragment和Adapter中使用时,初始化代码有所不同

       ButterKnife.bind(this, mRootView);

    3.属性布局不能用private or static 修饰,用public,否则会报错

    4.虽然使用ButterKnife很方便,但由于ButterKnife不是安卓原生的,所以使用时如果出错了,Studio

报错会很奇怪,需要耐心找。                

               ButterKnife使用步骤:

                 ButterKnife最新版本是8.4,需要编译工具Studio24以上,所以这里我是用了7.0的版本进行演示。其中我用到了ImageView,TextView,Button,CheckBox一些我们常用的控件以及ButterKnife在Fragment的使用的说明。最新8.4版本方法名有所改动,建议看官方文档,整体和原理没什么变动。

   效果图:

            

一、 在gradle文件中进行关联        

          compile 'com.jakewharton:butterknife:7.0.1'二、按照需求设计布局     
       <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"          xmlns:tools="http://schemas.android.com/tools"          android:id="@+id/activity_main"          android:layout_width="match_parent"          android:layout_height="match_parent"          android:gravity="center_horizontal"          android:orientation="vertical">          <ImageView             android:layout_marginTop="30dp"             android:id="@+id/imgShow"             android:layout_width="200dp"             android:layout_height="200dp"             android:src="@mipmap/dahuangfeng" />          <TextView             android:id="@+id/txtShowText"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_marginTop="20dp"             android:text="汽车人变形"             android:textSize="24sp" />          
         <Button             android:id="@+id/btnOK"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_marginTop="20dp"             android:text="跳到第二个页面"             android:textSize="24sp" />         <TextView             android:id="@+id/txtShowMessage"             android:layout_width="wrap_content"             android:layout_height="wrap_content"             android:layout_marginTop="20dp"             android:text="我来显示信息"             android:textSize="24sp" />   
<CheckBox
android:id="@+id/chbShow"
android
:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android
:text="点我一下试试"
android
:textSize="20sp" />
</LinearLayout>
完成效果:

三、在onCreate里进行初始化(注意不同的版本初始化的方法皆不一样,且注解控件的后缀名都不同  

          ButterKnife.bind(this);    四、加注解(相当于findViewByID,注意格式),先更改显示信息的TextView看下效果           
          @Bind(R.id.txtShowMessage)          TextView txtShowMessage;    五、使用注解完成点击事件的设置            
          txtShowMessage.setText("哈哈哈哈");
此时运行一下看看效果:

从效果图可以看出,通过使用注解,TextView显示的文字已经变了,但却要注意一个问题,
ButterKnife的初始化必须在setContentView()之后,否则运行会报错。这也是ButterKnife在
初始化时,不再Application中,而是在哪使用,就在哪初始化。

接下来加入TextView点击事件的相关代码,实现了点击后,产生动画效果:
1.添加注解
             @Bind(R.id.imgShow)             ImageView imgShow;
2.使用注解完成点击事件的设置
          @OnClick(R.id.txtShowText)          public void change(TextView textView){              imgShow.animate().scaleXBy(0.5f).alpha(0.3f).setDuration(2000).start();              textView.setText("变形成功");          }
运行看一下效果:

看一下详细的代码,注释写的很详细,有了点击事件的注解,就不需要在前面在添加了,
同时注意点击事件里方法的参数,是什么控件,就传该控件的对象,同时,我们也可以合并点击事件。

            public class MainActivity extends AppCompatActivity {                @Bind(R.id.txtShowMessage)                TextView txtShowMessage;                 @Bind(R.id.imgShow)                ImageView imgShow;                @Override                protected void onCreate(Bundle savedInstanceState) {                super.onCreate(savedInstanceState);                setContentView(R.layout.activity_main);                //在布局文件后,进行ButterKnife的绑定,参数类对象                 ButterKnife.bind(this);                //使用TextView设置数据                 txtShowMessage.setText("哈哈哈哈");             }                //TextView具备了点击事件,同时参数里就可以找到这个TextVIew(只能够在这个方法里使用其对象)                //相当于做了onClick点击事件,又做了findVIewByID                //设置点击事件,权限必须是默认权限以上                 @OnClick(R.id.txtShowText)                public void change(TextView textView){                //ImageViews做动画                 imgShow.animate().scaleXBy(0.5f).alpha(0.3f).setDuration(2000).start();                //具备点击事件的TextView,改变其文字                  textView.setText("变形成功");              }              /*给多个控件一起设置点击事件格式:                @OnClick( { , , .....} )                public void onClick(View view)参数是View view{                switch (view.getId()) { case R.id..... ..... break;}                }              */              @OnClick({R.id.btnOK,R.id.chbShow})              public void onClick(View view){                  switch (view.getId()){                   //为跳转到第二个页面的button设置了点击事件                    case R.id.btnOK:                        Intent intent = new Intent(MainActivity.this, Main2Activity.class);                         startActivity(intent);                  break;                  case R.id.chbShow:                  //CheckBox设置了点击事件                    Toast.makeText(MainActivity.this, "试试就试试", Toast.LENGTH_SHORT).show();                  break;               }            }         }
看一下效果图:
 
六、ButterKnife在Fragment里的使用
这个例子的目的是体现出,ButterKnife在Adapter和Fragment中的实现与在Activity中做对比。
由于Activity不能直接跳转到Fragment,这里我们采取跳转到Main2Activity后,在里面建立新的Fragment,将他的布局ID(container)替换为
新建Fragment的ID。

1.Main2Activity布局
          <FrameLayout android:layout_width="match_parent"              android:layout_height="match_parent"              android:id="@+id/container"              xmlns:android="http://schemas.android.com/apk/res/android"></FrameLayout>
2.fragment布局
          <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"             android:layout_width="match_parent"             android:layout_height="match_parent">             <ImageView                android:id="@+id/imgShow2"                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_alignParentLeft="true"                android:src="@mipmap/ic_arrow_back_black_48dp" />             <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:layout_centerHorizontal="true"                android:text="第二个页面"                android:textSize="24sp" />             <ListView                android:id="@+id/lstShow"                android:layout_width="match_parent"                android:layout_marginTop="8dp"                android:layout_below="@+id/imgShow"                android:layout_height="match_parent"></ListView>             </RelativeLayout>
3.ListView适配器
             public class MyAdapter extends BaseAdapter{                //上下文                Context mContext;                //构造方法,从外界得到上下文对象                public MyAdapter(Context context) {                mContext = context;              }              //listVIew加载的字符串,图片              int[] carsId={R.mipmap.car_black,R.mipmap.car_green,R.mipmap.car_red,R.mipmap.car_yellow};               String [] comentStr={"哈哈哈哈哈", "啦啦啦啦啦",                         "嘎嘎嘎嘎嘎", "嘿嘿嘿嘿嘿", "卡卡卡卡卡"};              @Override              public int getCount() {              return carsId.length;              }              @Override              public Object getItem(int position) {                 return null;              }              @Override              public long getItemId(int position) {                 return 0;              }              @Override              public View getView(int position, View convertView, ViewGroup parent) {                 ViewHolder viewHolder;                if(convertView == null ){                   convertView= LayoutInflater.from(mContext).inflate(R.layout.item_list, null);                   viewHolder=new ViewHolder( convertView) ;                   convertView.setTag(viewHolder);                }else{                   viewHolder= (ViewHolder) convertView.getTag();               }               //使用Random随机设置图片和评论文本,new Random().nextInt:随机产生0到指定int数的整数               viewHolder.car_IV.setImageResource(carsId[new Random().nextInt(4)]);               viewHolder.comment1_TV.setText(comentStr[new Random().nextInt(3)]);               viewHolder.comment2_TV.setText(comentStr[new Random().nextInt(3)]);               return convertView;            }              //创建listView里面用到的ViewHolder,首先要创建其构造方法,参数是VIew view              public static class ViewHolder{              @Bind(R.id.imgShowPic)              ImageView car_IV;              @Bind(R.id.txtShowComment1)              TextView comment1_TV;              @Bind(R.id.txtShowComment2)              TextView comment2_TV;               public ViewHolder(View view) {                  //进行ButterKnife的初始化,参数1 类对象,参数2VIew对象                  ButterKnife.bind(this,view);             }          }        }
4.item_list布局文件
        <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"            android:layout_width="match_parent"            android:layout_height="match_parent"            android:orientation="vertical">            <ImageView                android:id="@+id/imgShowPic"                android:layout_width="wrap_content"                android:layout_height="360dp" />            <TextView                android:id="@+id/txtShowComment1"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="20dp"                android:textColor="@android:color/black"                android:textSize="16sp" />            <TextView                android:id="@+id/txtShowComment2"                android:layout_width="match_parent"                android:layout_height="wrap_content"                android:layout_marginTop="8dp"                android:textColor="@android:color/black"                android:textSize="16sp" />        </LinearLayout>
5.Main2Activity
        public class Main2Activity extends AppCompatActivity {            @Override            protected void onCreate(Bundle savedInstanceState) {               super.onCreate(savedInstanceState);               setContentView(R.layout.activity_main2);               //Activity里的ID替换成一个Fragment               getSupportFragmentManager().beginTransaction()                   .replace(R.id.container, new PlaceHolderFragment())                   .commit();            }         //一个静态的内部类,继承Fragment         public static class PlaceHolderFragment extends Fragment {             //建立listview对象             @Bind(R.id.lstShow)             ListView lstShow;             @Override             public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {                View rootView = inflater.inflate(R.layout.fragment, container, false);                //进行ButterKnife的绑定,在Fragment使用即使两个参数 1.类对象 2.容器View对象,                ButterKnife.bind(this, rootView);                //创建一个adapter传递上下文,getActivity就是获取Fragment依赖Activity的上下文                MyAdapter adapter = new MyAdapter(getActivity());                lstShow.setAdapter(adapter);                return rootView;            }            //Image设置点击事件,关闭当前Activity,上下文调用finish            @OnClick(R.id.imgShow2)             public void finishActivity() {                getActivity().finish();           }        }     }
效果图:
这样就大功告成了!


     

   

1 0