`
XiangdongLee
  • 浏览: 90810 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

【攻克Android (34)】Butter Knife 黄油刀

 
阅读更多
本文围绕以下四个部分展开:

一、注解式框架
二、Butter Knife
案例一
案例二:用 ListView 展示一个列表数据,每个Item里含有一个Button,可以点击。






一、注解式框架

        1. 注解式开发:

        JDK 1.5后支持注解方式。想用注解式开发,就要自定义注解。

        @Override就是一种自带的注解。很多框架都采用注解方式来实现。

        当追求更高的开发效率,用更简洁的代码、更清晰的代码逻辑来进行高效的开发的时候,使用注解式框架开发可简化代码提升开发效率代码的可读性



        2. 主流注解式框架:

        (1)AndroidAnnotations

        配置麻烦,需要在功能清单文件中注册生成的子类。反射机制会占用资源内存,且耗时。

        (2)Dagger

        采用预编译技术,高效。但是对View绑定操作注解不是很方便。

        (3)Butter Knife

        它是View 及事件等依赖注入框架。使用方便,配置简单,有强大的View注入绑定和简单的常用方法注解。


二、Butter Knife

        它是View 及事件等依赖注入框架。

        1. 特点:

        (1)强大的View注入绑定和Click事件的处理。简化代码,提升开发效率。

        (2)可以方便地处理ListView的Adapter里的ViewHolder绑定问题。

        (3)运行时不会影响App效率,使用配置方便。

        (4)代码思路清晰,可读性强。

        2. 用法:

        导包:

        compile 'com.jakewharton:butterknife:6.0.0'

        在当前 Activity(this)的onCreate中注册(注入黄油刀):

ButterKnife.inject(this);


        (1)View绑定(绑定控件):

        Activity声明绑定控件:

    @InjectView(R.id.tvTitle) 
    TextView tvTitle;


        黄油刀注入控件,相当于:先声明变量,然后通过 findViewById(R.id.tvCompany) 初始化变量。黄油刀直接帮我们绑定好了控件:

        InjectView: Bind a field to the view for the specified ID. The view will automatically be cast to the field type.

    @InjectView(R.id.tvTitle) // 相当于 通过 findViewById(R.id.tvCompany) 初始化变量。
    TextView tvTitle; // 相当于 声明变量:private TextView tvCompany;


        注意:不同写为:private TextView tvTitle;  会报错:@InjectView fields must not be private or static.

        (2)Onclick等事件处理:

    @OnClick(R.id.btnHello)
    public void sayHi(){
        Toast.makeText(this,"你好!",Toast.LENGTH_SHORT).show();
    }


        (3)ListView的Adapter里的ViewHolder绑定问题。


案例一














        1. strings.xml。字符串。

<resources>
    <string name="app_name">ButterKnifeDemo</string>

    <string name="hello_world">Hello world!</string>
    <string name="action_settings">Settings</string>

    <string name="btn_good_night">Good Night!</string>
    <string name="btn_play">播放</string>
    <string name="btn_stop">停止</string>
    <string name="btn_view_holder">ViewHolder</string>
</resources>


        2. activity_main.xml。布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnHello"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"/>

    <Button
        android:id="@+id/btnGoodNight"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnHello"
        android:text="@string/btn_good_night"/>

    <Button
        android:id="@+id/btnPlay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnGoodNight"
        android:text="@string/btn_play"/>

    <Button
        android:id="@+id/btnStop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnPlay"
        android:text="@string/btn_stop"/>

    <Button
        android:id="@+id/btnViewHolder"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/btnStop"
        android:text="@string/btn_view_holder"/>

</RelativeLayout>


        3. MainActivity。View绑定和Onclick事件处理

package com.android.butterknifedemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnClick;
import butterknife.Optional;


public class MainActivity extends Activity {

    // 2. Actitvity里声明绑定控件
    // @Optional:加入后,若此id不存在,则程序不会崩溃,而是抛出异常
    @Optional@InjectView(R.id.btnHello)
    Button buttonHello;
    @InjectView(R.id.btnPlay)
    Button buttonPlay;
    @InjectView(R.id.btnStop)
    Button buttonStop;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 1. onCreate() 方法里注册 ButterKnife
        ButterKnife.inject(this);
    }

    // 3. 注入 View 事件,不带参数
    @OnClick(R.id.btnHello)
    public void sayHi(){
        Toast.makeText(this,"你好!",Toast.LENGTH_SHORT).show();
    }

    // 4. 注入 View 事件,带参数
    @OnClick(R.id.btnGoodNight)
    public void sayGoodNight(Button btnGoodNight){
        btnGoodNight.setText("晚上好!");
    }

    // 5. 同时注入多个 View 事件
    @OnClick({R.id.btnPlay,R.id.btnStop})
    public void playMusic(View view){
        switch (view.getId()){
            case R.id.btnPlay:
                Toast.makeText(this,"播放音乐",Toast.LENGTH_SHORT).show();
                break;
            case R.id.btnStop:
                Toast.makeText(this,"停止播放",Toast.LENGTH_SHORT).show();
        }
    }


    // ----------------------------------------------------------
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}


        4. MyAdapter。处理ListView的Adapter里的ViewHolder绑定问题。

package com.android.butterknifedemo;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;

import butterknife.ButterKnife;
import butterknife.InjectView;

/**
 * 在 ViewHolder 模式中注入
 */
// 1. 继承自 BaseAdapter
public class MyAdapter extends BaseAdapter{
    // 4. 定义上下文
    private Context mContext;

    /**
     * 5. 构造方法
     * @param context
     */
    public MyAdapter(Context context) {
        // 上下文通过构造方法传过来
        mContext = context;
    }

    @Override
    public int getCount() {
        return 0;
    }

    @Override
    public Object getItem(int position) {
        return position;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        // 3. 声明 holder 为空
        ViewHolder holder = null;

        // 6.
        if(holder==null){
            // 重新载入布局
            convertView = LayoutInflater.from(mContext).inflate(
                    R.layout.activity_main,parent,false);
            // 对 holder 进行实例化
            holder = new ViewHolder(convertView);
            // 获得按钮控件
            holder.btnViewHolder = (Button) convertView.findViewById(R.id.btnViewHolder);
            // 设置标签
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        // 7.
        holder.btnViewHolder.setText("更改");
        return convertView;
    }

    // 2. 写一个 结构持有者 类
    static class ViewHolder{
        @InjectView(R.id.btnViewHolder)
        Button btnViewHolder;

        public ViewHolder(View view){
            ButterKnife.inject(this,view);
        }
    }
}



案例二:用 ListView 展示一个列表数据,每个Item里含有一个Button,可以点击。










        1. activity_main.xml。布局:一个ListView。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>


        2. item.xml。每一个ListView的项。包括一个文本和一个按钮

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:descendantFocusability="blocksDescendants"
    android:orientation="vertical">

    <TextView
        android:id="@+id/tvText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/app_name" />

    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/tvText" />

</RelativeLayout>


        注:ListView中出现button等可以拦截点击事件的控件的时候,要加属性:

android:descendantFocusability="blocksDesendants"


        3. MyAdapter。自定义适配器。

package com.android.bufferknifedemo;

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;

import butterknife.ButterKnife;
import butterknife.InjectView;

/**
 * Created by Xiangdong on 2015/7/12.
 */
public class MyAdapter extends BaseAdapter {
    Context mContext;
    private ArrayList<String> lists;

    public MyAdapter(Context context, ArrayList<String> list) {
        mContext = context;
        lists = list;
    }

    @Override
    public int getCount() {
        return lists.size();
    }

    @Override
    public Object getItem(int position) {
        return lists.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = View.inflate(mContext, R.layout.item, null);
            holder = new ViewHolder(convertView);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        String s = lists.get(position);
        holder.tvText.setText(s);
        holder.btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(mContext, "点击", Toast.LENGTH_SHORT).show();
            }
        });
        return convertView;
    }

    static class ViewHolder {
        // 绑定控件
        @InjectView(R.id.tvText)
        TextView tvText;
        @InjectView(R.id.btn)
        Button btn;

        public ViewHolder(View view) {
            ButterKnife.inject(this, view);
        }
    }
}


        4. MainActivity。

package com.android.bufferknifedemo;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
import android.widget.Toast;

import java.util.ArrayList;

import butterknife.ButterKnife;
import butterknife.InjectView;
import butterknife.OnItemClick;

public class MainActivity extends Activity {
    @InjectView(R.id.listView)
    ListView listView;
    private MyAdapter adapter;
    private ArrayList<String> list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ButterKnife.inject(this);

        list = new ArrayList<>();
        list.add("测试1");
        list.add("测试2");
        list.add("测试3");
        list.add("测试4");
        list.add("测试5");
        list.add("测试6");
        list.add("测试7");
        list.add("测试8");
        list.add("测试9");
        adapter = new MyAdapter(this, list);
        listView.setAdapter(adapter);
    }

    @OnItemClick(R.id.listView)
    public void onMyItemClick(int position) {
        Toast.makeText(this, "位置:" + position, Toast.LENGTH_SHORT).show();
    }

    // ------------------------------------------------------------------
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}



整理时重点参考:http://www.jikexueyuan.com/course/1320.html
0
1
分享到:
评论

相关推荐

    Android高级应用源码-模仿butter knife,实现 两个基本的功能.rar

    "Android高级应用源码-模仿butter knife,实现 两个基本的功能.rar" 这个标题提到了一个Android开发中的实践项目,它旨在仿照Butter Knife库来实现两个关键功能。Butter Knife是一个流行的Android绑定库,它简化了...

    黄油刀jar包

    黄油刀(Butter Knife)是Android开发中的一个流行的视图注入库,由Jake Wharton 创建,它极大地简化了UI组件的查找和事件处理过程,从而减少了代码的冗余和提高了开发效率。这个库的名字来源于它能像黄油刀一样轻松...

    Android高级应用源码-模仿butter knife,实现 两个基本的功能.zip

    在Android开发中,Butter Knife是一个非常流行的注解库,它极大地简化了UI元素的绑定,使得开发者可以更专注于业务逻辑而不是繁琐的findViewById操作。这个压缩包中的源码旨在模仿Butter Knife,实现两个基本功能,...

    Android-Butter-Knife-Calculator

    Android黄油刀计算器该存储库包含一个简单的Android应用程序。 应用项目和屏幕截图这不是专业应用程序,仅是一个使用Android Butter Knife编码的演示应用程序,旨在展示使用Butter Knife库实现的代码的简单性。

    黄油刀注解butterknife-master

    黄油刀(Butter Knife)是一款由Jake Wharton开发的Android绑定库,它极大地简化了在Android应用中处理UI元素的工作。通过使用特定的注解,开发者可以避免编写大量的findViewById()调用来绑定视图,从而提高代码的...

    移除 Butter Knife 注释标签

    快速移除Android 代码中 butterknife-zelezny 生成 ButterKnife 注解,并自动生成findViewById 代码

    Android-ButterKnife:使用 Butter Knife 在 Android 上注入视图

    Tuts+ 教程:在 Android 上使用 Butter Knife 注入视图指导教师:Kerry Perez Huanca 在这个快速提示中,您将学习如何在项目中集成 Butter Knife 库,以便在应用程序代码中轻松实例化布局中的视图。 Tuts+ 教程的...

    java注解、反射和动态代理 简易Android Retrofit和Butter Knife 框架

    java注解、反射和动态代理 简易Android Retrofit和Butter Knife 框架 https://blog.csdn.net/soulshui/article/details/123332183?spm=1001.2014.3001.5501

    黄油刀绑定控件的点击事件.rar

    在Android应用开发中,"黄油刀"(Butter Knife)是一个非常实用的视图绑定库,由Jake Wharton开发。这个库简化了在Activity、Fragment以及View中处理UI元素的点击事件和其他视图交互的方式。标题中的"黄油刀绑定控件...

    android的插件:android-butterknife-zelezny-master

    Android Butter Knife Zelezny 是一个为Android开发者设计的插件,主要用于简化Butter Knife库的使用。Butter Knife是一个视图注入库,它通过消除在Android应用中手动查找和设置视图对象的样板代码,提高了开发效率...

    Android butterknife注解框架

    Android Butter Knife注解框架是一款由Jake Wharton开发的Android库,它极大地简化了视图绑定的过程,让开发者从繁琐的findViewById()调用中解脱出来。这个框架的核心思想是使用Java注解来标识UI元素,然后通过编译...

    android显示系统黄油计划

    Android 显示系统黄油计划 Android 显示系统的黄油计划是 Android OS 开发团队为了解决 UI 显示不流畅的问题而推出的一个重要项目。该项目通过引入 VSYNC、Triple Buffer 和 Choreographer 三个核心元素来重构 ...

    Bobo.zip_247bobo..com_butter_www eebobo com_www.231bobo com.

    2. Butter Knife:Butter Knife是一个视图注入框架,它通过注解来减少在Android应用中设置点击事件和获取视图对象所需的样板代码。开发者不再需要手动查找视图,而是通过注解在Activity或Fragment中声明视图。使用...

    Android注解省去findviewbyid

    除了Butter Knife,还有其他类似库如ViewInjector、Dagger2(配合Android Jetpack的Hilt)等,它们都利用注解来简化视图绑定和依赖注入。这些工具的使用能够显著提升代码的可读性和可维护性,减少了因手动操作`...

    源码 视图注入库 模仿butter knife,实现 两个基本的功能.zip

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    butterknife-butterknife-parent-7.0.1.zip

    Butter Knife是一款在Android开发中广泛使用的视图注入框架,由Jake Wharton创建,极大地简化了Android应用中UI组件的绑定和事件处理工作。下面我们将深入探讨Butter Knife的核心概念、功能以及如何在项目中使用它。...

    android IOC 实现

    在Android中,我们可以使用Dagger或Butter Knife等库来实现这一功能。 2. 好处:减少耦合,提高代码可读性,更便于测试和维护,同时可以实现组件的解耦,使代码结构更加清晰。 二、Android注解 1. 注解...

    u2020:jakewharton 的匕首+黄油刀演示应用程序的工作示例

    匕首(Dagger)和黄油刀(Butter Knife)是Android开发中两个非常重要的库,它们分别专注于依赖注入和视图绑定。本项目是一个由知名Android开发者Jake Wharton创建的示例应用,用于演示如何在实际应用中结合使用这两...

    Android studio插件集合

    3. **Butter Knife Zelezny**: Butter Knife是一款注解库,用于简化视图注入。而Zelezny插件则提供了图形化的界面,一键生成Butter Knife注解,避免手动编写。 4. **Stringlate**: 这个插件用于管理应用的多语言...

    Android使用注解查找控件

    - 在Android中,DI框架如Dagger和Butter Knife通过注解实现控件注入,使得代码更加整洁,降低了Activity或Fragment直接查找和操作控件的复杂性。 3. **@Inject注解的使用** - `@Inject`通常用在类的成员变量上,...

Global site tag (gtag.js) - Google Analytics