View注入框架:Butterknife简单使用

View注入框架 下载地址

1.Activity Binging

通过@Bind注释字段, Butter Knife可以通过View的ID自动找到并把相应的视图布局。
class ExampleActivity extends Activity {
   @Bind(R.id.title) TextView title;
   @Bind(R.id.subtitle) TextView subtitle;
   @Bind(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...
   }
}
替换了缓慢的反射,通过自动生成代码来执行查询, 你可以看到或者Debug调用 @Bind 的对象来生成代码,下图为上图所生成的代码。
public void bind(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);
}

2.Non Activity Binging

你可以指定Root View,从它中找到你 @Bind的View
public class FancyFragment extends Fragment {
   @Bind(R.id.button1) Button button1;
   @Bind(R.id.button2) Button button2;
 
   @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.fancy_fragment, container,  false );
     ButterKnife.bind( this , view);
     // TODO Use fields...
     return  view;
   }
}

3.Use in Adapter

在适配器列表中简化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 {
     @Bind(R.id.title) TextView name;
     @Bind(R.id.job_title) TextView jobTitle;
 
     public ViewHolder(View view) {
       ButterKnife.bind( this , view);
     }
   }
}

4.View List

你可以将多个View分组存储到List或者Array中
@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })
List<EditText> nameViews;
The apply method allows you to act on all the views  in  a list at once.
 
ButterKnife.apply(nameViews, DISABLE);
ButterKnife.apply(nameViews, ENABLED,  false );
Action and Setter interfaces allow specifying simple behavior.
 
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);
   }
};
一个Android属性同样可以使用 apply  方法
ButterKnife.apply(nameViews, View.ALPHA, 0.0f);

5.Listener Binging

Listeners也可以自动配置方法
@OnClick(R.id.submit)
public void submit(View view) {
   // TODO submit data to server...
}
所有的Listener的参数是可选的
@OnClick(R.id.submit)
public void submit() {
   // TODO submit data to server...
}
定义一个特定的类型它可以自动的转换
@OnClick(R.id.submit)
public void sayHi(Button button) {
   button.setText( "Hello!" );
}
在同一个绑定事件处理中可以指定多个ID
@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();
   }
}
自定义视图可以绑定自己的事件监听并且不指定ID
public class FancyButton extends Button {
   @OnClick
   public void onClick() {
     // TODO do something!
   }
}

6.Binging Reset

Fragments 比Activity有不同的View生命周期,在Fragmrnt 的 onCreateView方法中绑定,onDestroyView方法中销毁Views。Butter Knife有unbind 方法自动去做。
public class FancyFragment extends Fragment {
   @Bind(R.id.button1) Button button1;
   @Bind(R.id.button2) Button button2;
 
   @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
     View view = inflater.inflate(R.layout.fancy_fragment, container,  false );
     ButterKnife.bind( this , view);
     // TODO Use fields...
     return  view;
   }
 
   @Override public void onDestroyView() {
     super .onDestroyView();
     ButterKnife.unbind( this );
   }
}

7.Optional Binging

默认情况下,@Bind和侦听器绑定都是必需的。如果目标View无法找到它将 抛出一个异常
为了抑制这种习惯常见了可选绑定, @Nullable注解添加到字段或者方法中
笔记: 如何注解前都支持 @Nullable注解(官方鼓励这样的行为)
@Nullable @Bind(R.id.might_not_be_there) TextView mightNotBeThere;
 
@Nullable @OnClick(R.id.maybe_missing) void onMaybeMissingClicked() {
   // TODO ...
}

8.Multi-Method Listeners

方法注释相应的监听器有多个回调可以绑定到任何其中之一。每一个注释都 绑定到 一个默认的回调。 使用callback 参数 指定一个替代
@OnItemSelected(R.id.list_view)
void onItemSelected(int position) {
  // TODO ...
}
@OnItemSelected(value = R.id.maybe_missing, callback = NOTHING_SELECTED)
void onNothingSelected() {
  // TODO ...
}

9.Bonus

还包含findById方法的简化依然需要知道Views在哪个view、Activity、Dialog。它使用泛型来推断返回类型,并自动执行。
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);

注意:
使用Android Studio 需要在 Gradle文件中添加
compile  'com.jakewharton:butterknife:(insert latest version)'

混淆编译的时候需要在proguard文件中添加
-keep class butterknife.** { *; }
-dontwarn butterknife.internal.**
-keep class **$$ViewBinder { *; }

-keepclasseswithmembernames class * {
    @butterknife.* <fields>;
}

-keepclasseswithmembernames class * {
    @butterknife.* <methods>;
}

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

你可能感兴趣的:(Android开发,butterknife)