这篇文章主要是介绍了Android中的AndroidAnnotations注入框架,AA框架有它自身的一些优点,这里不赘述,但是我总觉得和ButterKnife比起来来世有些差距,今天我们就来看看ButterKnife的正确使用姿势,结合AndroidStudio中ButterKnife的插件,你会发现ButterKnife用起来有多爽!
ButterKnife 优势:
1.强大的View绑定和Click事件处理功能,简化代码,提升开发效率
2.方便的处理Adapter里的ViewHolder绑定问题
3.运行时不会影响APP效率,使用配置方便
4.代码清晰,可读性强
使用心得:
1.Activity ButterKnife.bind(this);必须在setContentView();之后,且父类bind绑定后,子类不需要再bind
2.Fragment ButterKnife.bind(this, mRootView);
3.属性布局不能用private or static 修饰,否则会报错
4.setContentView()不能通过注解实现。(其他的有些注解框架可以)
如何添加依赖
在项目的project 的build.gredle 文件中的dependencies标签下添加。
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
例如:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.2'
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
}
}
allprojects {
repositories {
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
在module的build.gredle 文件中添加
apply plugin: ‘android-apt’
在module的build.gredle 文件中的dependencies标签中添加
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
例如
apply plugin: 'com.android.application'
apply plugin: 'android-apt'
android {
compileSdkVersion 24
buildToolsVersion "24.0.3"
defaultConfig {
applicationId "com.zyj.wifi"
minSdkVersion 14
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.jakewharton:butterknife:8.4.0'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
}
需要说明的一点就是:必须要在layout文件定义好控件的id值,然后再通过
@BindView、@BindBitmap等去绑定在一起
普通控件的绑定:
接下来进入正题:
//初始化TextView控件
@BindView(R.id.tv1)
TextView tv1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//绑定控件
ButterKnife.bind(this);
tv1.setText("Hello ButterKnife");
}
onclick点击事件:
@OnClick(R.id.tv2)
public void click1() {
Toast.makeText(MainActivity.this, "111", Toast.LENGTH_SHORT).show();
}
需要注意的是,只需要在onCreate外面写就好,不用再在里面引用一次方法click1,这样就会出现一进去的是就开始响应一次点击事件。
使用了ButterKnife我们也可以进行点击事件的绑定,现在我们在给Activity中的Button设置点击事件的时候大多是在布局文件中添加onClick属性,这种方式适用于Activity却不适用Fragment,如果你想在Fragment中也这么方便的设置点击事件,ButterKnife毫无疑问是你最好的选择。
多个onclick点击事件:
@OnClick({R.id.tv1,R.id.tv3})
public void click2(View view) {
switch (view.getId()) {
case R.id.tv1:
Toast.makeText(MainActivity.this, "111", Toast.LENGTH_SHORT).show();
break;
case R.id.tv3:
Toast.makeText(MainActivity.this, "333", Toast.LENGTH_SHORT).show();
break;
}
}
Activity和Fragment:
(1)Activity
由于每次都要在Activity中的onCreate绑定Activity,所以个人建议写一个BaseActivity完成绑定,子类继承即可
注:ButterKnife.bind(this);绑定Activity 必须在setContentView之后:
实现如下(FragmentActivity 实现一样):
[java]
public abstract class BaseActivity extends Activity {
public abstract int getContentViewId();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(getContentViewId());
ButterKnife.bind(this);
initAllMembersView(savedInstanceState);
}
protected abstract void initAllMembersView(Bundle savedInstanceState);
@Override
protected void onDestroy() {
super.onDestroy();
ButterKnife.unbind(this);//解除绑定,官方文档只对fragment做了解绑
}
}
(2)Fragment
public abstract class BaseFragment extends Fragment {
public abstract int getContentViewId();
protected Context context;
protected View mRootView;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRootView =inflater.inflate(getContentViewId(),container,false);
ButterKnife.bind(this,mRootView);//绑定framgent
this.context = getActivity();
initAllMembersView(savedInstanceState);
return mRootView;
}
protected abstract void initAllMembersView(Bundle savedInstanceState);
**@Override
public void onDestroyView() {
super.onDestroyView();
ButterKnife.unbind(this);//解绑
}** //记得加上这个
}
资源实例化:
@BindColor(R.color.colorAccent)
int tvBg;
@BindString(R.string.app_name)
String tvStr;
@BindDrawable(R.mipmap.ic_launcher)
Drawable tvDrawable;
@BindDimen(R.dimen.activity_horizontal_margin)
int tvMargin;
ListView中item控件实例化:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.item, parent, false);
holder = new ViewHolder(convertView);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
holder.iv.setImageResource(R.mipmap.ic_launcher);
holder.tv.setText(list.get(position));
return convertView;
}
class ViewHolder {
@BindView(R.id.tv)
TextView tv;
@BindView(R.id.iv)
ImageView iv;
public ViewHolder(View itemView) {
ButterKnife.bind(this, itemView);
}
}
控件的批量操作:
ButterKnife中还有一个好玩的地方莫过于控件的批量操作,我们可以定义统一的行为,来设置给某一组控件,比如我想给我某一组的TextView修改背景颜色,可以定义如下行为:
[java]
ButterKnife.Action<View> CHANGECOLOR = new ButterKnife.Action<View>() {
@Override
public void apply(@NonNull View view, int index) {
view.setBackgroundColor(Color.RED);
}
};
使用方式如下:
[java]
ButterKnife.apply(textViews, CHANGECOLOR);
其中textViews是一个TextView的集合。
如果你想给TextView设置不同的背景颜色,那么还可以这样来定义:
[java]
ButterKnife.Setter<View,List<Integer>> CHANGECOLOR2 = new ButterKnife.Setter<View, List<Integer>>() {
@Override
public void set(@NonNull View view, List<Integer> value, int index) {
view.setBackgroundColor(value.get(index));
}
};
使用方式如下:
[java]
List<Integer> colors = new ArrayList<>();
colors.add(Color.RED);
colors.add(Color.GREEN);
colors.add(Color.BLUE);
ButterKnife.apply(textViews,CHANGECOLOR2,colors);
EditText的监听事件:
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
void onTextChanged(CharSequence s, int start, int before, int count) {
}
@OnTextChanged(value = R.id.mobileEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
void afterTextChanged(Editable s) {
}
可选绑定:
可选绑定:默认情况下,“绑定”和“监听”绑定都是必需的。如果不能找到目标视图,则将抛出异常。所以做空处理
[java]
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;
@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
// TODO ...
}
代码混淆:
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }
-keepclasseswithmembernames class * {
@butterknife.* <fields>;
}
-keepclasseswithmembernames class * {
@butterknife.* <methods>;
}