您的位置:首页 > 移动开发 > Android开发

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

2016-03-01 15:30 706 查看
本文链接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<-----

最后,谢谢阅读。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  butterknife