Android依赖注入之BufferKnife 8.0注解使用

前言:

App项目开发大部分时候还是以UI页面为主,这时我们需要调用大量的findViewById以及setOnClickListener等代码,控件的少的时候我们还能接受,控件多起来有时候就会有一种想砸键盘的冲动。所以这个时候我们想着可以借助注解的方式让我们从这种繁重的工作中脱离出来,也让代码变得更加简洁,便于维护,今天主要学习一下只专注View、Resource、Action注解框架BufferKnife 。

BufferKnife 介绍

BufferKnife 是一个专注于Android系统的View、Resource、Action注入框架。

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

gitHub:https://github.com/JakeWharton/butterknife/

BufferKnife 使用前后对比:

看看没有使用View注解之前我们是如何做的

1.)使用之前
public class ExampleActivity extends AppCompatActivity {
    private final static String TAG = ExampleActivity.class.getSimpleName();
    String butterKnifeStr;
    Drawable butterKnifeDrawable;
    Button butterKnifeBtn;
    ImageView butterKnifeIv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_butter_knife);
        initResource();
        initViews();
    }

    private void initViews() {
        butterKnifeBtn = (Button) findViewById(R.id.btn_butter_knife);
        butterKnifeBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.e(TAG, "onButterKnifeBtnClick");
            }
        });
        butterKnifeIv = (ImageView) findViewById(R.id.iv_butter_knife);
        butterKnifeBtn.setText(butterKnifeStr);
        butterKnifeIv.setImageDrawable(butterKnifeDrawable);
    }

    private void initResource() {
        butterKnifeStr = getString(R.string.title_btn_butter_knife);
        butterKnifeDrawable = getDrawable(R.mipmap.ic_launcher);
    }
}
2.)使用之后
public class ButterKnifeActivity extends AppCompatActivity {
    private final static String TAG = ButterKnifeActivity.class.getSimpleName();
    private Unbinder unbinder;
    @BindString(R.string.title_btn_butter_knife)
    String butterKnifeStr;
    @BindDrawable(R.mipmap.ic_launcher)
    Drawable butterKnifeDrawable;
    @BindView(R.id.btn_butter_knife)
    Button butterKnifeBtn;
    @BindView(R.id.iv_butter_knife)
    ImageView butterKnifeIv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_butter_knife);
        unbinder = ButterKnife.bind(this);
        initViews();
    }

    private void initViews() {
        butterKnifeBtn.setText(butterKnifeStr);
        butterKnifeIv.setImageDrawable(butterKnifeDrawable);
    }

    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(View view) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbinder.unbind();
    }
}
3.)ButterKnife 优势

通过上面使用前后对比来分析下ButterKnife优势

  • 强大的View绑定和Click事件处理功能,简化代码,提升开发效率
  • 方便的处理Adapter里的ViewHolder绑定问题
  • 运行时不会影响APP效率,使用配置方便
  • 代码清晰,可读性强

使用前后对比之后有没有觉得非常的简单易用。接下来来看下具体怎么使用的?

BufferKnife 如何使用:

1.)在Project的build.gradle中添加如下配置
buildscript {
  repositories {
    mavenCentral()
   }
  dependencies {
    classpath ‘com.neenbedankt.gradle.plugins:android-apt:1.8‘
  }
}
2.)在Module的build.gradle添加如下配置
apply plugin: ‘com.neenbedankt.android-apt‘

android {
  ...
}

dependencies {
  compile ‘com.jakewharton:butterknife:8.1.0‘
  apt ‘com.jakewharton:butterknife-compiler:8.1.0‘
}
3.)注入和重置注入

Activity

class ExampleActivity extends Activity {
  @BindView(R.id.title) TextView title;
  @BindView(R.id.subtitle) TextView subtitle;
  @BindView(R.id.footer) TextView footer;

  @Override public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.simple_activity);
    ButterKnife.bind(this);
    // TODO Use fields...
  }
}

Fragment:由于不同的视图生命周期,所以需要在onCreateView bind,在onDestroyView unbind

public class FancyFragment extends Fragment {
  @BindView(R.id.button1) Button button1;
  @BindView(R.id.button2) Button button2;
  private Unbinder unbinder;

  @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fancy_fragment, container, false);
    unbinder = ButterKnife.bind(this, view);
    // TODO Use fields...
    return view;
  }

  @Override public void onDestroyView() {
    super.onDestroyView();
    unbinder.unbind();
  }
}

ViewHolder

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 {
    @BindView(R.id.title) TextView name;
    @BindView(R.id.job_title) TextView jobTitle;

    public ViewHolder(View view) {
      ButterKnife.bind(this, view);
    }
  }
}
4.)view注入 @BindView,@BindViews
    @BindView(R.id.btn_butter_knife)
    Button butterKnifeBtn;
    @BindViews({R.id.tv_butter_knife1,R.id.tv_butter_knife2,R.id.tv_butter_knife3})
    List<TextView> textViews;
5.)Resource注入
    @BindString(R.string.title_btn_butter_knife)
    String butterKnifeStr;//string注解使用
    @BindDrawable(R.mipmap.ic_launcher)
    Drawable butterKnifeDrawable;//Drawable注解使用
    @BindBitmap(R.mipmap.ic_launcher)
    Bitmap  butterKnifeBitmap;;//Bitmap注解使用
    @BindArray(R.array.day_of_week)
    String weeks[];//数组
    @BindColor(R.color.colorPrimary)
    int colorPrimary;//color注解使用
    @BindDimen(R.dimen.activity_horizontal_margin)
    Float spacer;
6.)单事件注入

一个控件指定一个事件回调

    /**
     * 带参数
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick() {
    }

    /**
     * 带参数
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(View view) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

    /**
     * 带参数
     * @param button
     */
    @OnClick(R.id.btn_butter_knife)
    public void onButterKnifeBtnClick(Button button) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

也可以多个控件指定一个事件回调

    /**
     * 两个不同的button都相应onButterKnifeBtnClick事件回调
     *
     * @param button
     */
    @OnClick({R.id.btn_butter_knife, R.id.btn_butter_knife1})
    public void onButterKnifeBtnClick(Button button) {
        Log.e(TAG, "onButterKnifeBtnClick");
    }

自定义的控件不通过ID也可以绑定到自己的事件

public class FancyButton extends Button {
  @OnClick
  public void onClick() {
    // TODO do something!
  }
}
7.)多事件回调

有一些View的listener是有多个回调方法的,比如EditText添加addTextChangedListener

 editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });

可以使用注解方式改成如下

    @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.BEFORE_TEXT_CHANGED)
    void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }
    @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.TEXT_CHANGED)
    void onTextChanged(CharSequence s, int start, int before, int count) {

    }
    @OnTextChanged(value = R.id.nameEditText, callback = OnTextChanged.Callback.AFTER_TEXT_CHANGED)
    void afterTextChanged(Editable s) {

    }
8.)选择性注入

默认情况下,@Bind 和listener的注入都是必须的,如果target view没有被发现,则会报错. 为了抑制这种行为,可以用@Optional注解来标记field和方法,让注入变成选择性的,如果targetView存在,则注入, 不存在,则什么事情都不做.或者使用 Android‘s "support-annotations" library.中的@Nullable来修饰

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

@Optional @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
  // TODO ...
}
9.)ButterKnife.apply()函数

可以通过ButterKnifeapply()函数对view集合元素或者单个view的Action, Setter和Property进行修改

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

static final ButterKnife.Action<View> DISABLE = new ButterKnife.Action<View>() {
  @Override public void apply(View view, int index) {
    view.setEnabled(false);
  }
};
static final ButterKnife.Setter<View, Boolean> ENABLED = new ButterKnife.Setter<View, Boolean>() {
  @Override public void set(View view, Boolean value, int index) {
    view.setEnabled(value);
  }
};
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);
10.)ButterKnife.findById()

ButterKnife 也提供了findById函数,通过findById()可以获取Activity、Dialog、View中的view,并且是泛型类型不需要强转

View view = LayoutInflater.from(context).inflate(R.layout.thing, null);
TextView firstName = ButterKnife.findById(view, R.id.first_name);
TextView lastName = ButterKnife.findById(view, R.id.last_name);
ImageView photo = ButterKnife.findById(view, R.id.photo);

BufferKnife 自动生成插件安装:

在AndroidStudio->File->Settings->Plugins->搜索Zelezny下载添加就行 ,可以快速生成对应组件的实例对象,不用手动写。使用时,在要导入注解的Activity 或 Fragment 或 ViewHolder的layout资源代码上,右键——>Generate——Generate ButterKnife Injections,然后就出现如图的选择框。

插件gitHub地址:https://github.com/avast/android-butterknife-zelezny

上面给了一个使用流程图,不过流程图不会针对最新的8.0.1版本的,但是都是差不多的

时间: 2024-10-09 19:25:47

Android依赖注入之BufferKnife 8.0注解使用的相关文章

Android 依赖注入: Dagger 2 实例讲解(一)

本文原创,转载请注明出处:http://blog.csdn.net/zjbpku 关于Dagger,在之前的博文(Android 依赖注入:Dagger 实例讲解(Demo下载))中已有介绍, 本文说的Dagger 2主要是由Google技术 人员参与开发的,当然包括Square的各位及其他一些Contributors在内的大牛也贡献了不少.该项目大概是从去年11月份开始启动的,到目前该项 目还在继续进行,Snapshot version也是刚刚发布不久,从Github提供的内容看,不久会是Pr

Android依赖注入Dagger的使用和源码解析(上篇)

一.基本概念 依赖注入(DI)和控制反转(IOC): 依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源:而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源. 使用依赖注入可以带来以下好处: 依赖的注入和配置独立于组件之外. 因为对象是在一个独立.不耦合的地方初始化,所以当注入抽象方法的时候,我们只需要修改对象的实现方法,而不用大改代码库. 依赖可以注入到一个组件中:我们可以注入这

SpringMVC实现依赖注入的几个常用注解的用法解释和示例说明

在以前,我们使用Spring对一些属性进行依赖注入(DI)时,通常都是通过在配置文件中配置一个个的<bean>标签来实现,比如说这样: <bean id="userBiz" class="cn.zifangsky.biz.UserBizImpl"> <property name="userDAO" ref="userDAO"/> </bean> 但是一旦项目大了之后,如果要把所有

Android 依赖注入框架RoboGuice

概述 在开发应用时一个基本原则是模块化,并且尽最大可能性地降低模块之间的耦合性.Dependency injection 大大降低了类之间的依赖性,可以通过annotation描述类之间的依赖性,避免了直接调用类似的构造函数或是使用Factory来参加所需的类,从而降低类或模块之间的耦合性,以提高代码重用并增强代码的可维护性. Google Guice提供了Java平台上一个轻量级的 Dependency injection 框架,并可以支持开发Android应用.本指南将使用Android平台

框架 day36 Spring3 入门,DI依赖注入,装配bean基于xml/注解, 整合Junit4,配置约束自动提示

1 什么是spring 1.1官网 spring.io 1.2介绍 Spring的核心是控制反转(IoC)和面向切面(AOP). IoC(Inverse of Control 反转控制) AOP(Aspect Oriented Programming 面向切面编程为内核) 简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架. *轻量级:依赖其他内容较小,使用资源消耗也少.对比:EJB 重量级 *分层:经典三层体系架构,spring 提供解决方案

Spring 依赖注入(DI)的注解

Spring中想要使用注解进行依赖注入,需要进行如下配置: <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocatio

Android 依赖注入 ButterKnife 基本使用

ButterKnife 是一个快速 Android View 注入框架,开发者是Jake Wharton,简单的来说,ButterKnife 是用注解的方式替代findViewById和setXXXListener 项目GitHub地址:https://github.com/JakeWharton/butterknife/ Android Studio 配置步骤可以直接参考Github上的介绍,很简单. ButterKnife 是在编译时注解,不会在运行时产生负担,Build工程后你会发现它生成

spring四种依赖注入方式 (set,构造器,工厂,注解 )

平常的java开发中,程序员在某个类中需要依赖其它类的方法,则通常是new一个依赖类再调用类实例的方法,这种开发存在的问题是new的类实例不好统一管理,spring提出了依赖注入的思想,即依赖类不由程序员实例化,而是通过spring容器帮我们new指定实例并且将实例注入到需要该对象的类中.依赖注入的另一种说法是"控制反转",通俗的理解是:平常我们new一个实例,这个实例的控制权是我们程序员,而控制反转是指new实例工作不由我们程序员来做而是交给spring容器来做. spring有多种

关于Android依赖注入框架ButterKnife和Dagger的简单比较

最近调研了Android平台可以使用的依赖注入框架.发现现在常用的有四种.Dagger.Butter Knife.RoboGuice.Android Annotations.经过一系列的比较,最后我们的选择 的范围缩小到Dagger.Butter Knife这2个框架上.其实在国内外使用的比较多的应该是Dagger.但是我觉得还是有点复杂了,再看jakewharton的blog时,他也提到了dagger,我 摘抄了他在stackoverflow上回答Difference between Dagg