Android技术之ButterKnife

这篇文章主要是介绍了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>;  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值