[Android]ButterKnife-无尽之刃-绑定视图控件和事件的快速开发工具

来源:互联网 发布:软件平台建设规划 编辑:程序博客网 时间:2024/04/29 19:44

本文链接http://blog.csdn.net/jan_s/article/details/50772360,转载请留言

简单介绍

Butter knife是大神JakeWharton的一款Android利器,多数开发者都应该了解和使用过,这把黄油刀最大的吸引人的地方就是简化了android程序编写中的view,findviewById(id)和setOnxxxListener事件的写法,它使用了一种很简洁的注解写法,例如

会发现没有了findviewById这种超累的代码片段了,哈哈,这就值得让我们为这把黄油刀点赞!

简单使用

1.先下载butterknife的jar包,本文示例代码用的是版本7.0.1,可能与旧版本有些方法名不一样。如果用的是as:直接用gradle:

compile 'com.jakewharton:butterknife:7.0.1'

@bind方式就是简化了findviewbyid的代码,但在使用之前,一定要在Acivity中初始化Butterknife.bind(activity)。

先上本地demo的activity_main.xml,你可以直接跳过这段,没有具体的内容,主要是看这么引用这些控件的id.

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context=".ExampleActivity">    <LinearLayout        android:id="@+id/layout1"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:id="@+id/app_title_text"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="123"            android:gravity="center"            android:textSize="20sp" />        <Button            android:id="@+id/bind_btn"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:text="@string/bind_me" />        <TextView            android:id="@+id/text_content"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_gravity="center"            android:text="@string/cool_text"            android:textSize="20sp"            android:visibility="invisible" />    </LinearLayout>    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/layout1"        android:background="#ADE8BA"        android:orientation="vertical">        <fragment            android:id="@+id/example_fragment"            android:name="org.jan.butterknife.demo.ExampleFragment"            android:layout_width="match_parent"            android:layout_height="wrap_content" />    </LinearLayout></RelativeLayout>

ExampleActivity,先看看我们怎么使用butter knife获取控件引用,以及快速注册点击事件的。
import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.util.TypedValue;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import butterknife.Bind;import butterknife.BindString;import butterknife.ButterKnife;import butterknife.OnClick;import butterknife.OnLongClick;import static android.widget.Toast.LENGTH_SHORT;/** * butterknife的简单使示例代码 */public class ExampleActivity extends AppCompatActivity {    /**     * 2:7.0+版本的butterKnife将使用bind注解     * 注:因为注解用到了反射机制,所以这里的所有用到butterKnife的注解的变量都是非private的     */    @Bind(R.id.bind_btn)    Button button;    @Bind(R.id.text_content)    TextView mCoolText;    @Bind(R.id.app_title_text)    TextView mTitleText;    //绑定预定义的字符串资源,还有其他的一些方法如:@BindBool, @BindColor, @BindDimen, @BindDrawable, @BindInt    @BindString(R.string.butterknife_demo)    String title;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //1.将绑定该Activity        ButterKnife.bind(this);        //3.已经不再需要一个个findviewbyid了,可以直接调用,非常省心        userFieldToDo();    }    private void userFieldToDo() {        button.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 20);        mTitleText.setText(title);        mCoolText.setText("bind textview");    }    /**     * 4.@Onclick可以根据view's id来注册一个点击事件     * 方法参数是可选的,可以传一个view,或者widget,     * 这里是无参的,你可以写成onClickBindButton(View view)或onClickBindButton(Button btn)     */    @OnClick(R.id.bind_btn)    void onClickBindButton() {        mCoolText.setVisibility(View.VISIBLE);        Toast.makeText(this, "I bind it!", LENGTH_SHORT).show();    }    /**     * 绑定长按事件,这里要有返回一个boolean值,默认为false     * @return     */    @OnLongClick(R.id.bind_btn)    boolean onLongClickBindButton(){        Toast.makeText(this, "Let me go!", LENGTH_SHORT).show();        return true;    }    @Override    public void onBackPressed() {        super.onBackPressed();        finish();    }}
其实就是两个步骤:1.初始化butterknife
  2.bind所需要的widget
  3.在fragment中的话可以选择解除绑定。
这样写到底有没有用呢?看看效果吧,别搞了半天还是奔溃的。
果然是可行的,好东西果断要分享啊!
2.可能有人会有疑问,在Activity中这样做是可行的,但如果换在Fragment中或者listview的Adapter中,是否也可以用butterknife来简化代码呢,答案是肯定可以的。
** * 在fragment中的butterknifey运用 */public class ExampleFragment extends Fragment {//    @Bind(R.id.fragment_title)    TextView mTitleText;    @Bind(R.id.example_listview)    ListView mListview;    public ExampleFragment() {    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_example, container, false);        //1.bind方法很是很灵活的        ButterKnife.bind(this, view);        //2.如果遇到必须要利用findviewbyid的方式来引用某个view的话,你可以使用下面这种方式        mTitleText = ButterKnife.findById(view,R.id.fragment_title);        mTitleText.setGravity(Gravity.CENTER_HORIZONTAL);        mTitleText.setText("Example Fragment");        SimpleAdapter adapter = new SimpleAdapter(getContext());        mListview.setAdapter(adapter);        return view;    }    //给listview注册了一个onItemClick事件,这里的会传入一个position    @OnItemClick(R.id.example_listview)    void onItemClick(int position){        String item = mListview.getAdapter().getItem(position).toString();        Toast.makeText(getContext(),"i clicked "+item,Toast.LENGTH_SHORT).show();    }    @Override    public void onResume() {        super.onResume();    }    @Override    public void onPause() {        super.onPause();    }    @Override    public void onDestroyView() {        super.onDestroyView();        //2.解除绑定        ButterKnife.unbind(this);    }}
fragment_example.xml 这是fragment的布局文件,就是展示一个简单的listview.
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="org.jan.butterknife.demo.ExampleFragment">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:orientation="vertical">        <TextView            android:id="@+id/fragment_title"            android:layout_width="wrap_content"            android:layout_height="wrap_content"/>        <ListView            android:id="@+id/example_listview"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:divider="#FFFFFF"            android:dividerHeight="1dp" />    </LinearLayout></FrameLayout>

Listview使用的SimpleAdapter.java
import android.content.Context;import android.graphics.drawable.Drawable;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.ImageView;import android.widget.TextView;import butterknife.Bind;import butterknife.BindDrawable;import butterknife.ButterKnife;public class SimpleAdapter extends BaseAdapter {  private static final String[] CONTENTS =      "谁也 跟不上 我的 节奏 德玛西亚 啦啦 啦啦啦".split(" ");  private final LayoutInflater inflater;  public SimpleAdapter(Context context) {    inflater = LayoutInflater.from(context);  }  @Override public int getCount() {    return CONTENTS.length;  }  @Override public String getItem(int position) {    return CONTENTS[position];  }  @Override public long getItemId(int position) {    return position;  }  @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.simple_list_item, parent, false);      holder = new ViewHolder(view);      view.setTag(holder);    }    String s = getItem(position);    holder.word.setText(s);    holder.imageView.setBackground(holder.defaultImage);    return view;  }  /**   * 看ViewHolder的变量就知道我们又省去在getview方法里不停的findviewbyid了   */  static class ViewHolder {    @Bind(R.id.hehe_image)    ImageView imageView;    @Bind(R.id.hehe_text)    TextView word;    @BindDrawable(R.drawable.main_icon_service)    Drawable defaultImage;    ViewHolder(View view) {      //这里黄油刀在构造函数中久把fragment中的视图绑定了      ButterKnife.bind(this, view);    }  }}
simple_list_item.xml 这是list_item的布局。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal">    <ImageView        android:id="@+id/hehe_image"        android:layout_width="wrap_content"        android:layout_height="wrap_content" />    <TextView        android:id="@+id/hehe_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="test"        android:textSize="16sp" /></LinearLayout>


还有一些事件的写法我这里就不一一举例了。详细的使用我们可以看--->DOC<-----
最后,谢谢阅读。

0 0
原创粉丝点击