Android视图注入框架butterknife

Butterknife是一个Android的注解框架,可以代替findViewById和onClick等方法,达到精简代码的目的。

1、 官网介绍及下载jar包

http://jakewharton.github.io/butterknife/

2、 导入butterknife框架

把jar包导入工程里面,并且在Activity里面使用注解的方式来绑定控件:

public class MainActivity extends ActionBarActivity {

	@InjectView(R.id.main_text_1) TextView tv_1;
	@InjectView(R.id.main_text_2) TextView tv_2;
	@InjectView(R.id.main_text_3) TextView tv_3;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.inject(this);
		init();
	}
	
	private void init() {
		tv_1.setText("第一行");
		tv_2.setText("第二行");
		tv_3.setText("第三行");
	}

}直接这样使用是不行的,会报空指针异常,还要配置Eclipse。官网介绍配置方法:

http://jakewharton.github.io/butterknife/ide-eclipse.html

具体的配置方法如下:

右键工程----> propertise----> java compiler ----> Annotation Processing ----> 勾选Enable projectspecific settings


然后打开AnnotationProcessing ----> Factory Path ----> Add JARs,把下载的jar包添加进来


然后工程才能正常运行,跟普通的jar包使用起来不一样,那么如果我们导入别人的工程是使用了butterknife框架的,能不能正常运行和修改呢?继续试验:

使用butterknife框架的工程比其他工程多了这样一个文件夹:

点击进去是一个java文件,用来执行查找view的操作:

MainActivity$$ViewInjector.java:

package com.butterknifetest;

import android.view.View;
import butterknife.ButterKnife.Finder;

public class MainActivity$$ViewInjector {
  public static void inject(Finder finder, final com.butterknifetest.MainActivity target, Object source) {
    View view;
    view = finder.findRequiredView(source, 2131034173, "field 'tv_1'");
    target.tv_1 = (android.widget.TextView) view;
    view = finder.findRequiredView(source, 2131034175, "field 'tv_3'");
    target.tv_3 = (android.widget.TextView) view;
    view = finder.findRequiredView(source, 2131034172, "field 'helloWorldTextView'");
    target.helloWorldTextView = (android.widget.TextView) view;
    view = finder.findRequiredView(source, 2131034174, "field 'tv_2'");
    target.tv_2 = (android.widget.TextView) view;
  }

  public static void reset(com.butterknifetest.MainActivity target) {
    target.tv_1 = null;
    target.tv_3 = null;
    target.helloWorldTextView = null;
    target.tv_2 = null;
  }
}

把Eclipse里面原来的工程删掉,再重新导入,程序能正常运行,但是再用这种注解的方式绑定新的控件,就会出现空指针异常,要按照前面的方法重新配置Eclipse,多人合作开发或者导入别人使用了这个框架的工程时要注意。

3、继续研究butterknife能用在程序的哪些地方,实现精简代码:

①  可以在Activity、fragment和Adapter的ViewHolder里面使用,取代findViewById方法

Activity:

public class MainActivity extends ActionBarActivity {
	@InjectView(R.id.main_text_1) TextView tv_1;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		ButterKnife.inject(this);
		tv_1.setText("第一页");
	}
}
Fragment:

在fragment的onCreateView里注入时,应该在onDestroyView里设置视图为空:

public class FancyFragment extends Fragment {
  @InjectView(R.id.button1) Button button1;
  @InjectView(R.id.button2) Button button2;

  @Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    ButterKnife.inject(this, view);
    // TODO Use "injected" views...
    return view;
  }

  @Override void onDestroyView() {
    super.onDestroyView();
    ButterKnife.reset(this);
  }
}

Adapter:

public class MyAdapter extends BaseAdapter {
  @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.whatever, parent, false);
      holder = new ViewHolder(view);
      view.setTag(holder);
    }

    holder.name.setText("John Doe");
    // etc...

    return view;
  }

  static class ViewHolder {
    @InjectView(R.id.title) TextView name;
    @InjectView(R.id.job_title) TextView jobTitle;

    public ViewHolder(View view) {
      ButterKnife.inject(this, view);
    }
  }

②  可以使用@InjectViews获取view列表,如:

@InjectViews({ R.id.main_text_1, R.id.main_text_2, R.id.main_text_3 })
	List<TextView> nameViews;
然后可以通过apply方法定义view列表中所有view的行为:

    ButterKnife.apply(nameViews, DISABLE);
    ButterKnife.apply(nameViews, ENABLED, true);

    static final Action<View> DISABLE = new Action<View>() {
          @Override public void apply(View view, int index) {
              ((TextView)view).setText("第一行");
          }
        };
        
    static final Setter<View, Boolean> ENABLED = new Setter<View, Boolean>() {
      @Override public void set(View view, Boolean value, int index) {
          if(value) {
              ((TextView)view).setText("true");
          } else {
              ((TextView)view).setText("false");
          }

      }
    };

③  点击监听注入

直接通过id来监听点击事件:

	@OnClick(R.id.main_text_1)
	public void tv_1() {
		Toast.makeText(MainActivity.this, "点击了第一行", 2000).show();
	}

还可以把view作为参数传入方法:

	@OnClick(R.id.main_text_2)
	public void tv_2(TextView tv) {
		tv.setTextSize(20);
		Toast.makeText(MainActivity.this, "点击了第二行", 2000).show();
	}
还可以同时传入多个id:
	@OnClick({ R.id.main_text_1, R.id.main_text_2, R.id.main_text_3 })
	public void pickDoor(TextView tv) {
		switch (tv.getId()) {
		case R.id.main_text_1:
			Toast.makeText(MainActivity.this, "点击了第一行", 2000).show();
			break;
		case R.id.main_text_2:
			Toast.makeText(MainActivity.this, "点击了第二行", 2000).show();
			break;
		case R.id.main_text_3:
			Toast.makeText(MainActivity.this, "点击了第三行", 2000).show();
			break;

		default:
			break;
		}
	}

简单介绍到这里,更加具体的用法,可以去查看官网~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值