日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Butter Knife:一个安卓视图注入框架

發(fā)布時(shí)間:2025/4/16 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Butter Knife:一个安卓视图注入框架 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Butter Knife:一個(gè)安卓視圖注入框架

2014年5月8日 星期四

14:52

官網(wǎng): http://jakewharton.github.io/butterknife/

GitHub地址: https://github.com/JakeWharton/butterknife

JavaDocs地址: http://jakewharton.github.io/butterknife/javadoc/

?注:本隨筆翻譯自官網(wǎng),做了一些整理和注釋。來(lái)自我的OneNote筆記

大綱:

  • @InjectView (ActivityFragment)
  • @InjectViews
  • apply
  • @OnClick
  • reset
  • @Optional
  • @OnItemSelected
  • TextView firstName = ButterKnife.findById(view, R.id.first_name);
  • ?

    ?

    ?

    ?

    Activity的注入方法:

    //基本使用方法:在onCreate方法中調(diào)用ButterKnife.inject(this),然后就可以調(diào)用注解了

    class ExampleActivity extends Activity {

    ??@InjectView(R.id.title) TextView title;

    ??@InjectView(R.id.subtitle) TextView subtitle;

    ??@InjectView(R.id.footer) TextView footer;

    ?

    ??@Override public void onCreate(Bundle savedInstanceState) {

    ????super.onCreate(savedInstanceState);

    ????setContentView(R.layout.simple_activity);

    ????ButterKnife.inject(this);

    ????// TODO Use "injected" views...

    ??}

    }

    這個(gè)注入不是通過(guò)反射實(shí)現(xiàn)了(反射比較慢),而是直接生成代碼。上面的三個(gè)注入最后生成如下的代碼

    public void inject(ExampleActivity activity) {

    ??activity.subtitle = (android.widget.TextView) activity.findViewById(2130968578);

    ??activity.footer = (android.widget.TextView) activity.findViewById(2130968579);

    ??activity.title = (android.widget.TextView) activity.findViewById(2130968577);

    }

    Fragment的注入方法

    public class FancyFragment extends Fragment {

    ??@InjectView(R.id.button1) Button button1;

    ??@InjectView(R.id.button2) Button button2;

    ?

    ??@Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    ????View view = inflater.inflate(R.layout.fancy_fragment, container, false);

    ? ??//僅僅是這里的區(qū)別

    ????ButterKnife.inject(this, view);

    ????// TODO Use "injected" views...

    ????return view;

    ??}

    }

    簡(jiǎn)化ViewHolder的使用?

    public class MyAdapter extends BaseAdapter {

    ??@Override public View getView(int position, View view, ViewGroup parent) {

    ????//ViewHolder是一個(gè)普通的類(lèi),這個(gè)類(lèi)包含了一個(gè)Adapter需要的所有View,然后設(shè)置到了tag中,方便復(fù)用

    ????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 convertView;

    ??}

    //這里是ViewHolder:可以這樣進(jìn)行注入

    ??static class ViewHolder {

    ????@InjectView(R.id.title) TextView name;

    ????@InjectView(R.id.job_title) TextView jobTitle;

    ?

    ????public ViewHolder(View view) {

    ??????ButterKnife.inject(this, view);

    ????}

    ??}

    }

    注入一個(gè)View列表:@InjectViews

    //注入一個(gè)View列表

    @InjectViews({ R.id.first_name, R.id.middle_name, R.id.last_name })

    List<EditText> nameViews;

    //調(diào)用apply方法批量給View設(shè)置屬性

    ButterKnife.apply(nameViews, DISABLE);

    ButterKnife.apply(nameViews, ENABLED, false);

    //其中,DISABLE和ENABLED是兩個(gè)接口的實(shí)現(xiàn):Action,Setter

    static final Action<View> DISABLE = new Action<>() {

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

    ????view.setEnabled(false);

    ??}

    }

    static final Setter<View, Boolean> ENABLED = new Setter<>() {

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

    ????view.setEnabled(value);

    ??}

    }

    View所有的屬性都可以在apply方法中調(diào)用

    ButterKnife.apply(nameViews, View.ALPHA, 0);

    ?

    點(diǎn)擊監(jiān)聽(tīng)器的注入:OnClickListener -> @OnClick

    //簡(jiǎn)單使用

    @OnClick(R.id.submit)ren

    public void submit() {

    ??// TODO submit data to server...

    }

    //你可以傳入一個(gè)參數(shù),Butter Knife會(huì)自動(dòng)將注入的View轉(zhuǎn)換為對(duì)應(yīng)的類(lèi)型

    @OnClick(R.id.submit)

    public void sayHi(Button button) {

    ??button.setText("Hello!");

    }

    //當(dāng)然,也可以指定多個(gè)視圖的IDs,用來(lái)進(jìn)行通用的處理

    @OnClick({ R.id.door1, R.id.door2, R.id.door3 })

    public void pickDoor(DoorView door) {

    ??if (door.hasPrizeBehind()) {

    ????Toast.makeText(this, "You win!", LENGTH_SHORT).show();

    ??} else {

    ????Toast.makeText(this, "Try again", LENGTH_SHORT).show();

    ??}

    }

    注入的重置:reset

    Fragment中,我們需要在onDestroyView中設(shè)置這些Viewnull,但是只要調(diào)用reset方法,Butter Knife會(huì)自動(dòng)執(zhí)行這個(gè)步驟。

    public class FancyFragment extends Fragment {

    ??@InjectView(R.id.button1) Button button1;

    ??@InjectView(R.id.button2) Button button2;

    ?

    ??@Override View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    ????View view = inflater.inflate(R.layout.fancy_fragment, container, false);

    ????ButterKnife.inject(this, view);

    ????// TODO Use "injected" views...

    ????return view;

    ??}

    ?

    ??@Override void onDestroyView() {

    ????super.onDestroyView();

    ????ButterKnife.reset(this);

    ??}

    }

    可選的注入 @Optional

    默認(rèn)情況下,@InjectView@OnClick注入是必須了,所以,如果找不到目標(biāo)View就會(huì)拋出異常。如果想抑制這種情況,可以通過(guò)@Optional注解:

    @Optional @InjectView(R.id.might_not_be_there) TextView mightNotBeThere;

    ?

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

    ??// TODO ...

    }

    多方法的監(jiān)聽(tīng)@OnItemSelected

    有些監(jiān)聽(tīng)注解響應(yīng)的方法有多個(gè)回調(diào)函數(shù),所以,我們可以通過(guò)指定回調(diào)參數(shù)來(lái)實(shí)現(xiàn)多個(gè)回調(diào)方法的綁定。

    @OnItemSelected(R.id.list_view)

    void onItemSelected(int position) {

    ??// TODO ...

    }

    ?

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

    void onNothingSelected() {

    ??// TODO ...

    }

    BONUS:其實(shí)就是一個(gè)方便的靜態(tài)方法而已

    一般我們實(shí)例化一個(gè)View的時(shí)候是通過(guò)findById(id),然后強(qiáng)制轉(zhuǎn)換實(shí)現(xiàn)的,這樣的代碼看著不雅觀。所以,ButterKnife有一個(gè)方法自動(dòng)幫我們進(jìn)行這樣的轉(zhuǎn)換(Context可以為ViewActivity),如下面的例子:

    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);

    ?

    最新版本:5.0.1

    ?

    ?

    集成方法

    Maven

    <dependency>

    ??<groupId>com.jakewharton</groupId>

    ??<artifactId>butterknife</artifactId>

    ??<version>5.0.1</version>

    </dependency>

    Gradle

  • 添加依賴
  • compile 'com.jakewharton:butterknife:5.0.1'

  • 消除lint warning
  • lintOptions {

    ??disable 'InvalidPackage'

    }

  • Some configurations may also require additional exclusions.
  • packagingOptions {

    ??exclude 'META-INF/services/javax.annotation.processing.Processor'

    }

    ?

    Procuard配置:(這個(gè)配置是為了打包apk的時(shí)候不至于把你的那些貌似沒(méi)有用過(guò)的程序片段給刪掉了)

    -dontwarn butterknife.internal.**

    -keep class **$$ViewInjector { *; }

    -keepnames class * { @butterknife.InjectView *;}

    ?

    轉(zhuǎn)載于:https://www.cnblogs.com/leo-lsw/p/butterknife.html

    總結(jié)

    以上是生活随笔為你收集整理的Butter Knife:一个安卓视图注入框架的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。