文档章节

android 注解框架ButterKnife(一)

ForingY
 ForingY
发布于 2016/08/02 13:57
字数 1552
阅读 62
收藏 0
点赞 0
评论 0

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  
    <dependency>  
      <groupId>com.jakewharton</groupId>  
      <artifactId>butterknife</artifactId>  
      <version>(insert latest version)</version>  
    </dependency>  
  
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<edittext> 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<view> DISENABLE = new ButterKnife.Action<view>() {
        @Override
        public void apply(@NonNull View view, int index) {
            view.setEnabled(false);
        }
    };
 
    static final ButterKnife.Setter<view, boolean=""> ENABLE = new ButterKnife.Setter<view, boolean="">() {
        @Override
        public void set(@NonNull View view, Boolean value, int index) {
            view.setEnabled(value);
        }
    };
}   </view,></view,></view></view></edittext>

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<edittext> 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<view> DISENABLE = new ButterKnife.Action<view>() {
        @Override
        public void apply(@NonNull View view, int index) {
            view.setEnabled(false);
        }
    };
 
    static final ButterKnife.Setter<view, boolean=""> ENABLE = new ButterKnife.Setter<view, boolean="">() {
        @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();
    }
}</view,></view,></view></view></edittext>

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<unbinder> 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();
    }
}</unbinder>

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

输入图片说明

© 著作权归作者所有

共有 人打赏支持
ForingY
粉丝 23
博文 252
码字总数 156129
作品 0
杭州
程序员
ButterKnife注解框架详解

  Android 懒人注解框架 :https://github.com/JakeWharton/butterknife   前言:     注解,相信很多同学都用到了,对控件进行初始化的时候需要用到 findViewById() ,当一个activit...

听着music睡 ⋅ 2017/04/12 ⋅ 0

Java高级特性——注解,这也许是最简单易懂的文章了

博主在初学注解的时候看到网上的介绍大部分都是直接介绍用法或者功能,没有实际的应用场景,篇幅又很长导致学习的时候难以理解其意图,而且学完就忘QAQ。本篇文章中我将结合实际的应用场景尽...

美的让人心动 ⋅ 04/12 ⋅ 0

Android studio插件整理

Android studio 以下简称AS,*号表示插件的常用比例,越高常用性越高 AS打开设置的快捷键Ctrl + alt + S 在线安装:File-->settings-->Plugins-->Browse repositories-->然后再输入框输入But...

惟吾德馨_慧 ⋅ 05/23 ⋅ 0

ButterKnife源码解析

ButterKnife(https://github.com/JakeWharton/butterknife)是一款android平台的依赖注入框架,通过该工具可以实现View、OnClickListener的注入,省去了findViewById、setOnClickListener的...

JasmineBen ⋅ 05/29 ⋅ 0

ChameleonAdapter-利用注解快速完成多类型列表创建

ChameleonAdapter An easy way to create multiple item type list using annotation In daily work, it's hard to manage the adapter with various item type so that we must add lots of......

Leo_Zheng ⋅ 05/11 ⋅ 0

使用Kotlin高效地开发Android App(二)

继上一篇文章介绍了项目中所使用的Kotlin特性,本文继续整理当前项目所用到的特性。 一.apply 函数 和 run 函数 with、apply、run函数都是Kotlin标准库中的函数。with在第一篇文章中已经介绍...

Tony沈哲 ⋅ 04/27 ⋅ 0

浅谈Activity,Fragment模块化封装

欢迎大家访问我的博客:博客地址 概述 继承关系 这里的继承关系大家肯定十分熟悉了,这里贴出的是v4包中fragment,可以看出fragment是直接继承于object的,与四大组件没有任何关系。 两者之间...

stone_zhu ⋅ 06/12 ⋅ 0

Gradle/Studio构建问题(Ant/Gradle)

> 使用Gradle遇到的问题及其他: Android Studio安装过程常见问题图解-- http://jingyan.baidu.com/article/fd8044fad5bdca5031137ab7.html 1. 将GitHub上的新项目导入Studio中 Pano360-mast......

shareus ⋅ 05/11 ⋅ 0

Java注解(Annotation)详解

Java注解(Annotation)详解 1.Annotation的概念 An annotation is a form of metadata, that can be added to Java source code. Classes, methods, variables, parameters and packages may......

幻海流心 ⋅ 05/23 ⋅ 0

Android DataBinding 实战全解

2015年的Google IO大会上,Android 团队发布了一个数据绑定框架(Data Binding Library),官方原生支持 MVVM 模型。数据绑定的概念并不陌生,Web开发中已经很是普遍,因此DataBinding或多或...

sunrongxin.py ⋅ 2017/07/17 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JavaScript零基础入门——(十一)JavaScript的DOM操作

JavaScript零基础入门——(十一)JavaScript的DOM操作 大家好,欢迎回到我们的JavaScript零基础入门。最近有些同学问我说,我讲的的比书上的精简不少。其实呢,我主要讲的是我在开发中经常会...

JandenMa ⋅ 25分钟前 ⋅ 0

volatile和synchronized的区别

volatile和synchronized的区别 在讲这个之前需要先了解下JMM(Java memory Model :java内存模型):并发过程中如何处理可见性、原子性、有序性的问题--建立JMM模型 详情请看:https://baike.b...

MarinJ_Shao ⋅ 52分钟前 ⋅ 0

深入分析Kubernetes Critical Pod(一)

Author: xidianwangtao@gmail.com 摘要:大家在部署Kubernetes集群AddOn组件的时候,经常会看到Annotation scheduler.alpha.kubernetes.io/critical-pod"="",以表示这是一个关键服务,那你知...

WaltonWang ⋅ 今天 ⋅ 0

原子性 - synchronized关键词

原子性概念 原子性提供了程序的互斥操作,同一时刻只能有一个线程能对某块代码进行操作。 原子性的实现方式 在jdk中,原子性的实现方式主要分为: synchronized:关键词,它依赖于JVM,保证了同...

dotleo ⋅ 今天 ⋅ 0

【2018.06.22学习笔记】【linux高级知识 14.4-15.3】

14.4 exportfs命令 14.5 NFS客户端问题 15.1 FTP介绍 15.2/15.3 使用vsftpd搭建ftp

lgsxp ⋅ 今天 ⋅ 0

JeeSite 4.0 功能权限管理基础(Shiro)

Shiro是Apache的一个开源框架,是一个权限管理的框架,实现用户认证、用户授权等。 只要有用户参与一般都要有权限管理,权限管理实现对用户访问系统的控制,按照安全规则或者安全策略控制用户...

ThinkGem ⋅ 昨天 ⋅ 0

python f-string 字符串格式化

主要内容 从Python 3.6开始,f-string是格式化字符串的一种很好的新方法。与其他格式化方式相比,它们不仅更易读,更简洁,不易出错,而且速度更快! 在本文的最后,您将了解如何以及为什么今...

阿豪boy ⋅ 昨天 ⋅ 0

Python实现自动登录站点

如果我们想要实现自动登录,那么我们就需要能够驱动浏览器(比如谷歌浏览器)来实现操作,ChromeDriver 刚好能够帮助我们这一点(非谷歌浏览器的驱动有所不同)。 一、确认软件版本 首先我们...

blackfoxya ⋅ 昨天 ⋅ 0

线性回归原理和实现基本认识

一:介绍 定义:线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商...

wangxuwei ⋅ 昨天 ⋅ 0

容器之查看minikue的environment——minikube的环境信息

执行如下命令 mjduan@mjduandeMacBook-Pro:~/Docker % minikube docker-envexport DOCKER_TLS_VERIFY="1"export DOCKER_HOST="tcp://192.168.99.100:2376"export DOCKER_CERT_PATH="/U......

汉斯-冯-拉特 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部