Butter Knife

Butter Knife

参考:

Introductionhttp://jakewharton.github.io/butterknife/
JakeWharton/butterknifehttps://github.com/JakeWharton/butterknife
依赖注入框架AndroidAnnotations和ButterKnife真的方便了开发者?https://www.zhihu.com/question/38742543?sort=created


最近才接触到 ButterKnife,很好用,不过刚入门还是有一些困难,网上查找了不少资料,记录下 ButterKnife 最常用的方法,方便以后使用

下面代码的实现工程:ButterKnifeDemo

源代码编译工程:http://download.csdn.net/detail/u012005313/9824876


主要内容

  1. 基本原理
  2. Android Studio 导入 ButterKnife
  3. Activity 中使用
  4. FragmentAdapter 中使用
  5. Android Studio 插件 android-butterknife-zelezny 使用

基本原理

参考:【腾讯Bugly干货分享】深入理解 ButterKnife,让你的程序学会写代码

ButterKnife 是利用 Java 注解机制来实现辅助代码生成的框架,其在编译期生成代码,对运行时没有任何副作用(注:暂时不理解注解机制,没深入看过 ButterKnife 代码


Android Studio 导入 ButterKnife

当前最新版本:8.5.1

新建工程 ButterKnifeDemo

打开 app->build.gradle,直接添加:

dependencies {
    ...
    compile 'com.jakewharton:butterknife:8.5.1'
    compile 'com.jakewharton:butterknife-compiler:8.5.1'
}

或者

打开 File->Project Structure,在 app->Dependencies 中打开 Library Dependency 窗口,输入 butterknife 进行查找

自此,导入完成


Activity 中使用

ButterKnife 的使用方式非常简单

Field and method binding for Android views which uses annotation processing to generate boilerplate code for you.

* Eliminate findViewById calls by using @BindView on fields.
* Group multiple views in a list or array. Operate on all of them at once with actions, setters, or properties.
* Eliminate anonymous inner-classes for listeners by annotating methods with @OnClick and others.
* Eliminate resource lookups by using resource annotations on fields.

接下来用具体的实例验证

Activity 中使用

MainActivity 中实现

  • 文本视图(TextView
  • 进度条(ProgressBar
  • 按钮(Button
  • 多选框(CheckBox
  • 单选框(RadioButton
  • 下拉框(Spinner
  • 图像按钮(ImageButton

利用 ButterKnife 进行组件绑定,同时进行值设置,属性设置,以及接口调用

strings.xml

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

    <string-array name="array">
        <item>卡西</item>
        <item>阿道夫</item>
        <item>供电所</item>
    </string-array>

    <string-array name="array2">
        <item>啊等发达</item>
        <item>噶地方</item>
        <item>擦地方</item>
    </string-array>

    <string-array name="array3">
        <item>fadf</item>
        <item>cadrfe</item>
        <item>gadfa</item>
        <item>cafd</item>
    </string-array>
</resources>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.uniview.butterknifedemo.MainActivity">


    <TextView
        android:id="@+id/am_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <TextView
            android:id="@+id/ll_tv1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="TextView" />

        <TextView
            android:id="@+id/ll_tv2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="TextView" />

        <TextView
            android:id="@+id/ll_tv3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="TextView" />
    </LinearLayout>

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Button" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <CheckBox
            android:id="@+id/checkBox3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="CheckBox" />

        <CheckBox
            android:id="@+id/checkBox2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="CheckBox" />

        <CheckBox
            android:id="@+id/checkBox"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="CheckBox" />

    </LinearLayout>

    <RadioGroup
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        >

        <RadioButton
            android:id="@+id/radioButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="RadioButton" />

        <RadioButton
            android:id="@+id/radioButton4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="RadioButton" />

        <RadioButton
            android:id="@+id/radioButton3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="RadioButton" />

        <RadioButton
            android:id="@+id/radioButton2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="RadioButton" />
    </RadioGroup>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Spinner
            android:id="@+id/spinner"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1" />

        <ImageButton
            android:id="@+id/imageButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:src="@android:drawable/arrow_down_float"
            app:srcCompat="@color/colorPrimaryDark" />
    </LinearLayout>

</LinearLayout>

MainActivity.java

package com.uniview.butterknifedemo;

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

import java.util.List;

import butterknife.BindArray;
import butterknife.BindString;
import butterknife.BindView;
import butterknife.BindViews;
import butterknife.ButterKnife;
import butterknife.OnClick;
import butterknife.OnItemSelected;

public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getSimpleName();

    @BindView(R.id.am_tv)
    TextView textView;

    @BindView(R.id.progressBar)
    ProgressBar progressBar;

    @BindViews({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
    List<TextView> textViewList;

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

    @BindViews({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
    List<CheckBox> checkBoxList;

    @BindViews({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
    List<RadioButton> radioButtonList;

    @BindView(R.id.spinner)
    Spinner spinner;

    @BindView(R.id.imageButton)
    ImageButton imageButton;


    @BindString(R.string.app_name)
    String appName;

    @BindArray(R.array.array)
    String[] arrays;

    @BindArray(R.array.array2)
    String[] arrays2;

    @BindArray(R.array.array3)
    String[] arrays3;

    static final ButterKnife.Setter<TextView, String[]> initialText = new ButterKnife.Setter<TextView, String[]>() {
        @Override
        public void set(@NonNull TextView view, String[] value, int index) {
            view.setText(value[index]);
        }
    };

    static final ButterKnife.Setter<TextView, String[]> initialRadio = new ButterKnife.Setter<TextView, String[]>() {
        @Override
        public void set(@NonNull TextView view, String[] value, int index) {
            view.setText(value[index]);
        }
    };

    static final ButterKnife.Action<TextView> visible = new ButterKnife.Action<TextView>() {
        @Override
        public void apply(@NonNull TextView view, int index) {
            view.setVisibility(View.VISIBLE);
        }
    };

    static final ButterKnife.Action<TextView> invisible = new ButterKnife.Action<TextView>() {
        @Override
        public void apply(@NonNull TextView view, int index) {
            view.setVisibility(View.INVISIBLE);
        }
    };

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

        initView();
    }

    private void initView() {
        textView.setText(appName);

//        for (int i = 0; i < 3; i++) {
//            textViewList.get(i).setText(arrays[i]);
//        }

        ButterKnife.apply(textViewList, initialText, arrays);
//        ButterKnife.apply(textViewList, actionText);
        ButterKnife.apply(checkBoxList, initialText, arrays2);
        ButterKnife.apply(radioButtonList, initialRadio, arrays3);

        ButterKnife.apply(textViewList, invisible);

        ArrayAdapter<CharSequence> spinnerAdapter = ArrayAdapter.createFromResource(this, 
            android.R.array.organizationTypes, android.R.layout.simple_spinner_item);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(spinnerAdapter);
    }

    @OnClick(R.id.am_tv)
    void textViewClick() {
        String text = textView.getText().toString();
        if (text.equals("Hello World")) {
            textView.setText("Hello zj");
        } else {
            textView.setText("Hello World");
        }
    }

    @OnClick({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
    void textMultipleClick() {
//        for (int i = 0; i < 3; i++) {
//            textViewList.get(i).setText(arrays2[i]);
//        }

        ButterKnife.apply(textViewList, initialText, arrays2);
    }

    @OnClick(R.id.button)
    void btnClick(View view) {
        int flag = progressBar.getVisibility();
        Log.e(TAG, "btnClick: flag = " + flag);
        if (flag == progressBar.VISIBLE) {
            progressBar.setVisibility(progressBar.INVISIBLE);
            ButterKnife.apply(textViewList, visible);
        } else {
            progressBar.setVisibility(progressBar.VISIBLE);
            ButterKnife.apply(textViewList, invisible);
        }
    }

    @OnClick({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
    void onCheckboxClicked(View view) {
        switch (view.getId()) {
            case R.id.checkBox:
                Toast.makeText(this, "you click checkbox + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.checkBox2:
                Toast.makeText(this, "you click checkbox2 + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.checkBox3:
                Toast.makeText(this, "you click checkbox3 + " + ((CheckBox) view).getText(), Toast.LENGTH_SHORT).show();
                break;
        }
    }

    @OnClick({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
    void onRadioClicked(View view) {
        switch (view.getId()) {
            case R.id.radioButton:
                Toast.makeText(this, "you click radiobutton + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.radioButton2:
                Toast.makeText(this, "you click radiobutton2 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.radioButton3:
                Toast.makeText(this, "you click radiobutton3 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
                break;
            case R.id.radioButton4:
                Toast.makeText(this, "you click radiobutton4 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
                break;
        }
    }

    @OnItemSelected(value = R.id.spinner, callback = OnItemSelected.Callback.ITEM_SELECTED)
    void onItemSel(AdapterView<?> parent, View view, int position, long id) {
        Toast.makeText(this, "position: " + position + " id: " + id, Toast.LENGTH_SHORT).show();
    }

    @OnClick(R.id.imageButton)
    void onImageBtnClicked() {
        Intent intent = new Intent(this, Main2Activity.class);
        intent.putExtra("image", "image");
        startActivity(intent);
    }
}
首先需要在 onCreate() 中调用 ButterKnife

注意:需要在 ‘setContentView’ 之后

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ButterKnife.bind(this);
    // TODO Use fields...
}
对于视图,可以单个绑定,也可以将多个视图同时进行绑定,生成 List 或者 Array 形式
@BindView(R.id.am_tv)
TextView textView;

@BindView(R.id.progressBar)
ProgressBar progressBar;

@BindViews({R.id.ll_tv1, R.id.ll_tv2, R.id.ll_tv3})
List<TextView> textViewList;

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

@BindViews({R.id.checkBox, R.id.checkBox2, R.id.checkBox3})
List<CheckBox> checkBoxList;

@BindViews({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
List<RadioButton> radioButtonList;

@BindView(R.id.spinner)
Spinner spinner;

@BindView(R.id.imageButton)
ImageButton imageButton;

Note:这样操作之后,就不需要再使用 findViewById

使用 ButterKnife 同时可以对资源进行绑定:

@BindString(R.string.app_name)
String appName;

@BindArray(R.array.array)
String[] arrays;

@BindArray(R.array.array2)
String[] arrays2;

@BindArray(R.array.array3)
String[] arrays3;

不仅可以进行字符串,字符串数组绑定,还可以进行颜色,图像等其他资源绑定

当多个视图同时绑定,生成 List 或者 Array 形式后,ButterKnife 还提供了同时赋值和属性设置的功能

参考:ButterKnife使用详解

赋值函数:

  /** A setter that can apply a value to a list of views. */
  public interface Setter<T extends View, V> {
    /** Set the {@code value} on the {@code view} which is at {@code index} in the list. */
    @UiThread
    void set(@NonNull T view, V value, int index);
  }

属性设置函数:

   /** An action that can be applied to a list of views. */
  public interface Action<T extends View> {
    /** Apply the action on the {@code view} which is at {@code index} in the list. */
    @UiThread
    void apply(@NonNull T view, int index);
  }

应用函数:

There are three convenience methods for working with view collections:
apply(List, Action) – Applies an action to each view.
apply(List, Setter, Object) – Applies a setter value to each view.
apply(List, Property, Object) – Applies a property value to each view.
对于视图而言,还可以对接口事件进行绑定

比如对于 TextView 来说,可以进行点击事件的绑定:

@OnClick(R.id.am_tv)
void textViewClick() {
    ...
}

函数名自定义,可以根据需求添加原本接口函数的参数:

@OnClick(R.id.button)
void btnClick(View view) {
    ...
}

如果接口事件中有多个函数,需要进行指定:

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

如果多个视图都要进行同一事件的操作,可以同时绑定:

@OnClick({R.id.radioButton, R.id.radioButton2, R.id.radioButton3, R.id.radioButton4})
void onRadioClicked(View view) {
    switch (view.getId()) {
        case R.id.radioButton:
            Toast.makeText(this, "you click radiobutton + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.radioButton2:
            Toast.makeText(this, "you click radiobutton2 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.radioButton3:
            Toast.makeText(this, "you click radiobutton3 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
            break;
        case R.id.radioButton4:
            Toast.makeText(this, "you click radiobutton4 + " + ((RadioButton) view).getText(), Toast.LENGTH_SHORT).show();
            break;
    }
}

FragmentAdapter 中使用

ButterKnife 不仅可以用在 Activity 中,还可以使用在 FragmentAdapter 中,接下来实现一个 ViewPager + TabLayout + Fragment + RecyclerView 的组合

Main3Activity.java:

package com.uniview.butterknifedemo;

import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

import butterknife.BindView;
import butterknife.ButterKnife;

public class Main3Activity extends AppCompatActivity {

    @BindView(R.id.tab_layout)
    TabLayout tabLayout;

    @BindView(R.id.view_pager)
    ViewPager viewPager;

    private MyAdapter myAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main3);
        ButterKnife.bind(this);

        initView();
    }

    private void initView() {
        myAdapter = new MyAdapter(this, getSupportFragmentManager());

        viewPager.setAdapter(myAdapter);

        tabLayout.setTabMode(TabLayout.MODE_FIXED);
        tabLayout.setupWithViewPager(viewPager);
    }
}

activity_main3.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical"
    tools:context="com.uniview.butterknifedemo.Main3Activity">

    <android.support.design.widget.TabLayout
        android:id="@+id/tab_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

MyAdapter.java

package com.uniview.butterknifedemo;

import android.content.Context;
import android.support.design.widget.TabLayout;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

/**
 * Created by Lenovo on 2017/4/23.
 */

public class MyAdapter extends FragmentPagerAdapter {

    private final String Tabs[] = {"left", "middle", "right"};

    private Context context;

    public MyAdapter(Context context, FragmentManager fm) {
        super(fm);

        this.context = context;
    }

    @Override
    public Fragment getItem(int position) {
        return ViewPagerFragment.newInstance(position);
    }

    @Override
    public int getCount() {
        return Tabs.length;
    }

    @Override
    public CharSequence getPageTitle(int position) {
//        return super.getPageTitle(position);
        return Tabs[position];
    }
}

ViewPagerFragment.java

package com.uniview.butterknifedemo;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import butterknife.BindArray;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.Unbinder;

/**
 * Created by Lenovo on 2017/4/22.
 */

public class ViewPagerFragment extends Fragment {

    private int status;

    @BindView(R.id.text)
    TextView textView;

    @BindView(R.id.recycler_view)
    RecyclerView recyclerView;

    @BindArray(R.array.array)
    String[] arrays;

    @BindArray(R.array.array2)
    String[] arrays2;

    private Unbinder unbinder;

    private DisplayAdapter displayAdapter;
    private LinearLayoutManager linearLayoutManager;

    public static ViewPagerFragment newInstance(int status) {
        ViewPagerFragment viewPagerFragment = new ViewPagerFragment();

        Bundle args = new Bundle();
        args.putInt("status", status);
        viewPagerFragment.setArguments(args);

        return viewPagerFragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        status = getArguments() != null ? getArguments().getInt("status") : 1;
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//        return super.onCreateView(inflater, container, savedInstanceState);
        View v = inflater.inflate(R.layout.fragment_view, container, false);
        unbinder = ButterKnife.bind(this, v);

        textView.setText("statu: " + status);

        linearLayoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(linearLayoutManager);

        if (status == 0 || status == 2) {
            displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays));
        } else {
            displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays2));
        }
        recyclerView.setAdapter(displayAdapter);
        return v;
    }

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

fragment_view.xml

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

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="@string/app_name"
        android:textSize="24sp" />

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1" />

</LinearLayout>

DisplayAdapter.java

package com.uniview.butterknifedemo;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;

/**
 * Created by Lenovo on 2017/4/24.
 */

public class DisplayAdapter extends RecyclerView.Adapter<DisplayAdapter.MyViewHolder> {
    private static final String TAG = DisplayAdapter.class.getSimpleName();

    private Context context;
    private List<String> arrays = new ArrayList<>();

    public DisplayAdapter(Context context, List<String> arrs) {
        this.context = context;
        arrays.addAll(arrs);
    }

    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
//        return null;
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_recycler_view, parent, false);

        MyViewHolder vh = new MyViewHolder(v);

        return vh;
    }

    @Override
    public void onBindViewHolder(MyViewHolder holder, int position) {
        holder.textView.setText(arrays.get(position));
    }

    @Override
    public int getItemCount() {
        return arrays.size();
    }

    static class MyViewHolder extends RecyclerView.ViewHolder {
        @BindView(R.id.text)
        TextView textView;

        public MyViewHolder(View itemView) {
            super(itemView);
            ButterKnife.bind(this, itemView);
        }
    }
}

layout_recycler_view.xml

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

    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:minHeight="?android:attr/listPreferredItemHeightSmall"
        android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
        android:paddingStart="?android:attr/listPreferredItemPaddingStart"
        android:text="@string/app_name"
        android:textAppearance="?android:attr/textAppearanceListItemSmall" />

    <View
        android:layout_width="match_parent"
        android:layout_height="1px"
        android:background="#000000" />

</LinearLayout>

绑定 fragment 格式如下:

  @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;
  }

在绑定自身的同时还需要指明父视图。同时,由于 fragment 有一个不同的生命周期,需要在 onDestroyView 方法中解绑 ButterKnife,具体用法如下:

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

当前代码操作如下:

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//        return super.onCreateView(inflater, container, savedInstanceState);
    View v = inflater.inflate(R.layout.fragment_view, container, false);
    unbinder = ButterKnife.bind(this, v);

    textView.setText("statu: " + status);

    linearLayoutManager = new LinearLayoutManager(getContext());
    recyclerView.setLayoutManager(linearLayoutManager);

    if (status == 0 || status == 2) {
        displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays));
    } else {
        displayAdapter = new DisplayAdapter(getActivity(), java.util.Arrays.asList(arrays2));
    }
    recyclerView.setAdapter(displayAdapter);
    return v;
}

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

使用 RecyclerView 或者 ListView 时,经常会使用 ViewHolder 模型来优化,ButterKnife 也提供了在 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);
    }
  }
}

当前代码中 ViewHolder 操作如下:

static class MyViewHolder extends RecyclerView.ViewHolder {
    @BindView(R.id.text)
    TextView textView;

    public MyViewHolder(View itemView) {
        super(itemView);
        ButterKnife.bind(this, itemView);
    }
}

Android Studio 插件 android-butterknife-zelezny 使用

参考:

avast/android-butterknife-zelezny

AS ButterKnife 插件的引入,爬坑。

Android Studio 上有关于 ButterKnife 的插件,推荐 android-butterknife-zelezny,非常有用

安装方法不再介绍,下面提醒一下使用时需要注意的事情:

安装完成后,需要点击在 xml 文件上,鼠标右键点击 Generate...,才会出现 ButterKnife 的选项

这里写图片描述

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值