android 注解编程,android 注解框架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()不能通过注解实现。(其他的有些注解框架可以)

不同于其他的注解框架通过反射在代码运行阶段实现对View的赋值和设置监听事件,ButterKnife是在代码编译阶段直接生成可执行的代码。这样就可以避免反射带来的运行缓慢的问题。

使用步骤: 一.导入ButterKnife jar包:

1)如果你是Eclipse,可以去官网下载jar包

2)如果你是AndroidStudio可以直接 File->Project Structure->Dependencies->Library dependency 搜索butterknife即可,第一个就是

3)当然也可以用maven和gradle配置

MAVEN

com.jakewharton

butterknife

(insert latest version)

GRADLE

compile 'com.jakewharton:butterknife:(insert latest version)'

Be sure to suppress this lint warning in your build.gradle.(关闭)

lintOptions {

disable 'InvalidPackage'

}

用as下载好butterknife后,重启, 1.找到项目的build.gradle中添加:

classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'

我的项目的添加结果:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

repositories {

jcenter()

}

dependencies {

classpath 'com.android.tools.build:gradle:2.0.0'

**classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'**

// NOTE: Do not place your application dependencies here; they belong

// in the individual module build.gradle files

}

}

allprojects {

repositories {

jcenter()

}

}

task clean(type: Delete) {

delete rootProject.buildDir

}

2,在app模块的build.gradle中添加:

apply plugin: 'com.neenbedankt.android-apt'

compile 'com.jakewharton:butterknife:8.2.1'

apt 'com.jakewharton:butterknife-compiler:8.2.1'

我的项目的添加结果:

apply plugin: 'com.android.application'

apply plugin: 'com.neenbedankt.android-apt'

android {

compileSdkVersion 23

buildToolsVersion "21.1.2"

defaultConfig {

applicationId "com.xhgjky.amm"

minSdkVersion 15

targetSdkVersion 23

versionCode 1

versionName "1.0"

}

buildTypes {

release {

minifyEnabled false

proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

}

}

sourceSets {

main {

jniLibs.srcDirs = ['libs']

}

}

}

dependencies {

provided fileTree(include: ['*.jar'], dir: 'libs')

testCompile 'junit:junit:4.12'

compile files('libs/ksoap2-android.jar')

compile 'com.android.support:appcompat-v7:23.4.0'

compile 'com.android.support:support-v4:23.4.0'

compile files('libs/gson-2.2.4.jar')

compile files('libs/simr-android-duqiancn-0.5.jar')

compile 'com.jakewharton:butterknife:8.2.1'

apt 'com.jakewharton:butterknife-compiler:8.2.1'

//引入RxAndroid

compile 'io.reactivex:rxandroid:1.1.0'

compile 'io.reactivex:rxjava:1.1.0'

}

二,支持的功能; 1,在Activity中绑定view

public class ButterKnifeDemoAct extends AppCompatActivity {

@BindView(R.id.tv1) TextView tv1;

@BindView(R.id.btn1) Button btn1;

@BindView(R.id.iv1) ImageView iv1;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.butter_knife_act);

ButterKnife.bind(this);//必须在setContentView之后

// TODO Use fields...

}

}

2,支持资源变量的绑定:

public class ButterKnifeDemoAct extends AppCompatActivity {

@BindView(R.id.tv1) TextView tv1;

@BindView(R.id.btn1) Button btn1;

@BindView(R.id.iv1) ImageView iv1;

@BindDrawable(R.mipmap.dji_fly) Drawable flyDrawable;//图片

@BindDimen(R.dimen.text_size) int textSize;//Dimen

@BindColor(R.color.red) int red;//颜色

@BindString(R.string.text_name) String name;//字符串

@BindArray(R.array.flight_rc_pole_modes) String[] items;//字符串数组

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.butter_knife_act);

ButterKnife.bind(this);//必须在setContentView之后

// TODO Use fields...

}

}

3,支持对一个集合的View进行绑定,同时也支持对一个集合的View进行一组相同的操作。 这个操作可以是自定义的也可以是View的属性

public class ButterKnifeDemoAct extends AppCompatActivity {

@BindViews({R.id.editText, R.id.editText2, R.id.editText3}) List editTexts;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.butter_knife_act);

ButterKnife.bind(this);//必须在setContentView之后

// TODO Use fields...

}

@OnClick(R.id.btn1)

public void onClick() {

Log.i(TAG, "onClick: ");

ButterKnife.apply(editTexts, DISENABLE);//对editTexts的所有的View设置disable

}

@OnClick(R.id.iv1)

public void setEnableView() {

ButterKnife.apply(editTexts, ENABLE, true);//对editTexts的所有的View设置ensable

ButterKnife.apply(editTexts, View.ALPHA, 0.0f);//对editTexts的所有的View设置透明

}

static final ButterKnife.Action DISENABLE = new ButterKnife.Action() {

@Override

public void apply(@NonNull View view, int index) {

view.setEnabled(false);

}

};

static final ButterKnife.Setter ENABLE = new ButterKnife.Setter() {

@Override

public void set(@NonNull View view, Boolean value, int index) {

view.setEnabled(value);

}

};

}

4,支持对View设置监听方法,这个方法的参数是可选的: 既可以:

@OnClick(R.id.btn1)

public void onClick() {

Log.i(TAG, "onClick: ");

// TODO Use fields...

}

也可以:

@OnClick(R.id.btn1)

public void onClick(View v) {

Log.i(TAG, "onClick: ");

// TODO Use fields...

}

同时也支持对多个View设置同一个监听:

@OnClick({R.id.editText, R.id.editText2, R.id.editText3})

public void onClickEdit(View v) {

Log.i(TAG, "onClick: ");

// TODO Use fields...

}

在自定义View中:

public class FancyButton extends Button {

@OnClick

public void onClick() {

// TODO do something!

}

}

对有多个回调方法的监听,可以只写其中的一个方法,注意要用方法的参数进行区别执行的是什么方法;

@OnItemSelected(R.id.spinner)

public void onSelected(int position) {

Log.i(TAG, "onSelected: ");

}

@OnItemSelected(value = R.id.spinner, callback = OnItemSelected.Callback.NOTHING_SELECTED)

public void onNothingSelected() {

Log.i(TAG, "onNothingSelected: ");

}

当有一个View的id不确定是否在这个Target中可以用@Nullable @Optional注解:

@Nullable @BindView(R.id.might_not_be_there) TextView mightNotBeThere;

@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {

// TODO ...

}

总的代码;

public class ButterKnifeDemoAct extends AppCompatActivity {

public static final String TAG = ButterKnifeDemoAct.class.getName();

@BindView(R.id.tv1)

TextView tv1;

@BindView(R.id.btn1)

TextView btn1;

@BindView(R.id.iv1)

ImageView iv1;

@BindDrawable(R.mipmap.dji_fly)

Drawable flyDrawable;

@BindDimen(R.dimen.text_size)

int textSize;

@BindColor(R.color.red)

int red;

@BindString(R.string.text_name)

String name;

@BindViews({R.id.editText, R.id.editText2, R.id.editText3})

List editTexts;

@BindArray(R.array.flight_rc_pole_modes)

String[] items;

@BindView(R.id.spinner)

Spinner spinner;

private Unbinder unbinder;

@Override

protected void onCreate(@Nullable Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

try {

ButterKnife.setDebug(true);

setContentView(R.layout.butter_knife_act);

unbinder = ButterKnife.bind(this);

tv1.setTextSize(textSize);

tv1.setTextColor(red);

tv1.setText("this is ok !" + name);

btn1.setText("you can click me !");

iv1.setImageDrawable(flyDrawable);

BaseAdapter leftAdapter = new MyAdapter(items,this);

spinner.setAdapter(leftAdapter);

} catch (Exception e) {

e.printStackTrace();

}

}

@OnClick(R.id.btn1)

public void onClick() {

Log.i(TAG, "onClick: ");

ButterKnife.apply(editTexts, DISENABLE);

}

@OnClick(R.id.iv1)

public void setEnableView() {

ButterKnife.apply(editTexts, ENABLE, true);

ButterKnife.apply(editTexts, View.ALPHA, 0.0f);

}

static final ButterKnife.Action DISENABLE = new ButterKnife.Action() {

@Override

public void apply(@NonNull View view, int index) {

view.setEnabled(false);

}

};

static final ButterKnife.Setter ENABLE = new ButterKnife.Setter() {

@Override

public void set(@NonNull View view, Boolean value, int index) {

view.setEnabled(value);

}

};

@OnItemSelected(R.id.spinner)

public void onSelected(int position) {

Log.i(TAG, "onSelected: ");

}

@OnItemSelected(value = R.id.spinner, callback = OnItemSelected.Callback.NOTHING_SELECTED)

public void onNothingSelected() {

Log.i(TAG, "onNothingSelected: ");

}

@Override

protected void onDestroy() {

super.onDestroy();

unbinder.unbind();

}

}

5,ButterKnife不只是可以在Activity中使用,还可以在其他地方,比如Dialog,Fragment,Adapter的holder中使用

/**

* A placeholder fragment containing a simple view.

*/

public static class PlaceholderFragment extends Fragment {

@BindView(R.id.section_label)

TextView textView;

@Nullable @BindView(R.id.item_tv)

TextView tv;

Unbinder unbinder;

public PlaceholderFragment() {

}

public static PlaceholderFragment newInstance(int sectionNumber) {

PlaceholderFragment fragment = new PlaceholderFragment();

return fragment;

}

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {

View rootView = inflater.inflate(R.layout.fragment_main, container, false);

unbinder = ButterKnife.bind(this, rootView);

textView.setText(getString(R.string.section_format, getArguments().getInt(ARG_SECTION_NUMBER)));

return rootView;

}

@Override

public void onDestroy() {

super.onDestroy();

unbinder.unbind();

}

}

public class MyAdapter extends BaseAdapter {

public static final String TAG = MyAdapter.class.getName();

private String[] items;

private Context context;

private List unbinders = new ArrayList<>();

public MyAdapter(String[] items, Context context) {

this.items = items;

this.context = context;

}

@Override

public int getCount() {

return items.length;

}

@Override

public Object getItem(int position) {

return items[position];

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup parent) {

MyHolder myHandler;

if (convertView != null) {

myHandler = (MyHolder) convertView.getTag();

} else {

convertView = LayoutInflater.from(context).inflate(R.layout.flight_rc_pole_mode_item, parent, false);

myHandler = new MyHolder(convertView);

convertView.setTag(myHandler);

}

myHandler.itemTv.setText(getItem(position).toString());

return convertView;

}

class MyHolder {

@BindView(R.id.item_tv)

TextView itemTv;

@OnClick(R.id.item_tv)

public void onClick(){

Log.i(TAG, "onClick: ");

}

MyHolder(View view) {

Unbinder un = ButterKnife.bind(this, view);

unbinders.add(un);

}

}

/**

* 只在Adapter对象销毁的时候调用

* 清除所有的绑定的MyHolder和View

*/

public void unBinder(){

for (Unbinder un:unbinders) {

un.unbind();

}

unbinders.clear();

}

}

6,在有生命周期的组件的销毁方法中或一个对象销毁的时候要un.unbind();解绑,防止内存泄露 生成的代码位置;

92d1c55ef1f1747c93afe68552cf03b5.png

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值