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

本文链接http://blog.youkuaiyun.com/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<-----
最后,谢谢阅读。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值