当前位置: 代码迷 >> Android >> 安卓开发懒鬼最爱之ButterKnife,依赖注入第三方是库,更上一层楼加速开发速度
  详细解决方案

安卓开发懒鬼最爱之ButterKnife,依赖注入第三方是库,更上一层楼加速开发速度

热度:58   发布时间:2016-04-27 23:32:45.0
安卓开发懒鬼最爱之ButterKnife,依赖注入第三方是库,进一步加速开发速度

转载请注明出处:王亟亟的大牛之路

还在烦躁一大堆findById的控件操作而烦恼么?

平时,我们的那一系列findById是一个“浩大的工程”样例如下

这是曾经一个项目的一个填童虎数据表单的一个Activity,这是一系列的声明

public class UserInfoActivity extends Activity implements OnClickListener {    TextView userNameTxt;    RelativeLayout sexLayout;    TextView sexTxt;    RelativeLayout birthdayLayout;    TextView birthdayTxt;    RelativeLayout provinceLayout;    TextView provinceTxt;    RelativeLayout cityLayout;    TextView cityTxt;    RelativeLayout hasCarCardLayout;    TextView hasCarCardTxt;    RelativeLayout hasCarLayout;    TextView hasCarTxt;    RelativeLayout buyCarTimeLayout;    TextView buyCarTimeTxt;    RelativeLayout carBrandLayout;    TextView carBrandTxt;    RelativeLayout carTypeLayout;    TextView carTypeTxt;    RelativeLayout carPriceLayout;    TextView carPriceTxt;    RelativeLayout carCardNumLayout;    TextView carCardNumTxt;    RelativeLayout carNumLayout;    TextView carNumTxt;    RelativeLayout familyIncomeLayout;    TextView familyIncomeTxt;    RelativeLayout carCarImgLayout;    ImageView carCarImg;    RelativeLayout drivingLicenseLayout;    ImageView drivingLicenseImg;    LinearLayout backLin;    LinearLayout saveBtn;    RelativeLayout userNameLayout;    LinearLayout sexLinLayout;    LinearLayout birthdayLinLayout;    LinearLayout provinceLinLayout;    LinearLayout cityLinLayout;    LinearLayout carCarLinLayout;    LinearLayout hasCarLinLayout;    LinearLayout buyCarTimeLinLayout;    LinearLayout carBrandLinLayout;    LinearLayout carTypeLinLayout;    LinearLayout carPriceLinLayout;    LinearLayout carCardNumLinLayout;    LinearLayout carNumLinLayout;    LinearLayout familiIncomeLinLayout;    LinearLayout carCardImageLinLayout;    LinearLayout drivindLicenseLinLayout;    LinearLayout professionLinLayout;    LinearLayout carInfoLayout;    TextView professionTv;

这是一大堆的findById

    backLin = (LinearLayout) titleView.findViewById(R.id.backLin);        saveBtn = (LinearLayout) titleView.findViewById(R.id.saveBtn);        userNameLayout = (RelativeLayout) contentView                .findViewById(R.id.userNameLayout);        userNameTxt = (TextView) contentView.findViewById(R.id.userNameTxt);        sexLayout = (RelativeLayout) contentView.findViewById(R.id.sexLayout);        sexTxt = (TextView) contentView.findViewById(R.id.sexTxt);        birthdayLayout = (RelativeLayout) contentView                .findViewById(R.id.birthdayLayout);        birthdayTxt = (TextView) contentView.findViewById(R.id.birthdayTxt);        provinceLayout = (RelativeLayout) contentView                .findViewById(R.id.provinceLayout);        provinceTxt = (TextView) contentView.findViewById(R.id.provinceTxt);        cityLayout = (RelativeLayout) contentView.findViewById(R.id.cityLayout);        cityTxt = (TextView) contentView.findViewById(R.id.cityTxt);        hasCarCardLayout = (RelativeLayout) contentView                .findViewById(R.id.carCardLayout);        hasCarCardTxt = (TextView) contentView.findViewById(R.id.carCardTxt);        hasCarLayout = (RelativeLayout) contentView                .findViewById(R.id.hasCarLayout);        hasCarTxt = (TextView) contentView.findViewById(R.id.hasCarTxt);        buyCarTimeLayout = (RelativeLayout) contentView                .findViewById(R.id.buyCarTimeLayout);        buyCarTimeTxt = (TextView) contentView.findViewById(R.id.buyCarTimeTxt);        carBrandLayout = (RelativeLayout) contentView                .findViewById(R.id.carBrandLayout);        carBrandTxt = (TextView) contentView.findViewById(R.id.carBrandTxt);        carTypeLayout = (RelativeLayout) contentView                .findViewById(R.id.carTypeLayout);        carTypeTxt = (TextView) contentView.findViewById(R.id.carTypeTxt);        carPriceLayout = (RelativeLayout) contentView                .findViewById(R.id.carPriceLayout);        carPriceTxt = (TextView) contentView.findViewById(R.id.carPriceTxt);        carCardNumLayout = (RelativeLayout) contentView                .findViewById(R.id.carCardNumLayout);        carCardNumTxt = (TextView) contentView.findViewById(R.id.carCardNumTxt);        carNumLayout = (RelativeLayout) contentView                .findViewById(R.id.carNumLayout);        carNumTxt = (TextView) contentView.findViewById(R.id.carNumTxt);        familyIncomeLayout = (RelativeLayout) contentView                .findViewById(R.id.familyIncomeLayout);        familyIncomeTxt = (TextView) contentView                .findViewById(R.id.familyIncomeTxt);        carCarImgLayout = (RelativeLayout) contentView                .findViewById(R.id.carCarImgLayout);        carCarImg = (ImageView) contentView.findViewById(R.id.carCarImg);        drivingLicenseLayout = (RelativeLayout) contentView                .findViewById(R.id.drivingLicenseLayout);        drivingLicenseImg = (ImageView) contentView                .findViewById(R.id.drivingLicenseImg);        sexLinLayout = (LinearLayout) contentView                .findViewById(R.id.sexLinLayout);        birthdayLinLayout = (LinearLayout) contentView                .findViewById(R.id.birthdayLinLayout);        provinceLinLayout = (LinearLayout) contentView                .findViewById(R.id.provinceLinLayout);        cityLinLayout = (LinearLayout) contentView                .findViewById(R.id.cityLinLayout);        carCarLinLayout = (LinearLayout) contentView                .findViewById(R.id.carCarLinLayout);        hasCarLinLayout = (LinearLayout) contentView                .findViewById(R.id.hasCarLinLayout);        buyCarTimeLinLayout = (LinearLayout) contentView                .findViewById(R.id.buyCarTimeLinLayout);        carBrandLinLayout = (LinearLayout) contentView                .findViewById(R.id.carBrandLinLayout);        carTypeLinLayout = (LinearLayout) contentView                .findViewById(R.id.carTypeLinLayout);        carPriceLinLayout = (LinearLayout) contentView                .findViewById(R.id.carPriceLinLayout);        carCardNumLinLayout = (LinearLayout) contentView                .findViewById(R.id.carCardNumLinLayout);        carNumLinLayout = (LinearLayout) contentView                .findViewById(R.id.carNumLinLayout);        familiIncomeLinLayout = (LinearLayout) contentView                .findViewById(R.id.familiIncomeLinLayout);        drivindLicenseLinLayout = (LinearLayout) contentView                .findViewById(R.id.drivindLicenseLinLayout);        carCardImageLinLayout = (LinearLayout) contentView                .findViewById(R.id.carCardImageLinLayout);        professionLinLayout = (LinearLayout) contentView                .findViewById(R.id.professionLinLayout);        carInfoLayout = (LinearLayout) contentView                .findViewById(R.id.carInfoLayout);        professionTv = (TextView) contentView.findViewById(R.id.professionTv);

看着看着蛋都碎了,简直不能忍,所以今天推荐一个简单易用的库,效果如图
这里写图片描述
不试试很快很猛?轻轻点两下,这一大堆玩意都能解决!

来来来,JAR包下载:butterknife-7.0.1
Maven:

<groupId>com.jakewharton</groupId>  <artifactId>butterknife</artifactId>  <version>7.0.1</version></dependency>

Gradle:

compile 'com.jakewharton:butterknife:7.0.1'

项目包下载地址:点击下载

Gif的功能只能在AndroidStudio使用,Eclipse的小伙伴只能手打了。。
操作方法:
Android Studio: go to Preferences → Plugins → Browse repositories and search for ButterKnife Zelezny
跟我们用图片做背景图一样,下载一个插件就好。

好,废话不多,开始拆作者的样例(楼主小学英文大致的理解讲述下):

Annotate fields with @Bind and a view ID for Butter Knife to find and automatically cast the corresponding view in your layout.
注释字段“绑定”和“ Butter Knife”的视图标识,并自动在布局中查看相应的视图。

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...  }}

分析:使用 @Bind 就可以对控件进行声明,已经findViewById的操作,然后在onCreate()方法中调用 ButterKnife.bind(this);使之生效,如果你觉得有必要的话可以在onDestory()方法中再调用ButterKnife.unbind(this);进行解绑操作

You can also perform binding on arbitrary objects by supplying your own view root.
可以通过提供您自己的视图根试图来执行任意对象的绑定。我们可以用在fragment等用到inflater的地方。

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

分析:这边与Activity的差别只是在调用的方法中需要传入被绑定的那个根试图而已。

Another use is simplifying the view holder pattern inside of a list adapter.
在ListView或者其他一些用到 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);    }  }}

You can group multiple views into a List or array
可以把一些控件放进一个集合或者数组中

@Bind({ R.id.first_name, R.id.middle_name, R.id.last_name })List<EditText> nameViews;

Listeners can also automatically be configured onto methods.
也可以自动将侦听器配置为方法。

@OnClick(R.id.submit)public void submit(View view) {  // TODO submit data to server...}

All arguments to the listener method are optional.
所有参数的侦听器方法是可选的。

@OnClick(R.id.submit)public void submit() {  // TODO submit data to server...}

Define a specific type and it will automatically be cast.
定义一个特定类型,它将自动被转换。

@OnClick(R.id.submit)public void sayHi(Button button) {  button.setText("Hello!");}

Specify multiple IDs in a single binding for common event handling.
指定多个身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();  }}

自己也写了一个Demo大致内容也和范例差不多,不过比较直观,可以看一下
MainActivity

public class MainActivity extends AppCompatActivity implements TestFragment.OnFragmentInteractionListener{    @Bind(R.id.textView)    TextView textview;    @Bind(R.id.button1)    Button button1;    @Bind(R.id.button2)    Button button2;    @Bind(R.id.button3)    Button button3;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        ButterKnife.bind(this);    }    @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);    }    @OnClick(R.id.button1)    public void button1click(Button btn){        btn.setText("BTN1");    }    @OnClick({R.id.button1, R.id.button2, R.id.button3 })    public void click(View v) {    switch (v.getId()){        case R.id.button1:            Toast.makeText(this, "button1", Toast.LENGTH_SHORT).show();            break;        case R.id.button2:            Toast.makeText(this, "button2",Toast.LENGTH_SHORT).show();            break;        case R.id.button3:            Toast.makeText(this, "button3",Toast.LENGTH_SHORT).show();            break;    }    }    @Override    public void onFragmentInteraction(Uri uri) {    }}

内部的fragment

public class TestFragment extends Fragment {    // TODO: Rename parameter arguments, choose names that match    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER    private static final String ARG_PARAM1 = "param1";    private static final String ARG_PARAM2 = "param2";    @Bind(R.id.fbtn)    Button fbtn;    // TODO: Rename and change types of parameters    private String mParam1;    private String mParam2;    private OnFragmentInteractionListener mListener;    /**     * Use this factory method to create a new instance of     * this fragment using the provided parameters.     *     * @param param1 Parameter 1.     * @param param2 Parameter 2.     * @return A new instance of fragment TestFragment.     */    // TODO: Rename and change types and number of parameters    public static TestFragment newInstance(String param1, String param2) {        TestFragment fragment = new TestFragment();        Bundle args = new Bundle();        args.putString(ARG_PARAM1, param1);        args.putString(ARG_PARAM2, param2);        fragment.setArguments(args);        return fragment;    }    public TestFragment() {        // Required empty public constructor    }    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        if (getArguments() != null) {            mParam1 = getArguments().getString(ARG_PARAM1);            mParam2 = getArguments().getString(ARG_PARAM2);        }    }    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container,                             Bundle savedInstanceState) {        View view = inflater.inflate(R.layout.fragment_test, container, false);        ButterKnife.bind(this, view);        return view;    }    @Override    public void onDestroyView() {        super.onDestroyView();        ButterKnife.unbind(this);    }    @OnClick(R.id.fbtn)    void fbtnClick() {        Toast.makeText(getActivity(), "Fragment", Toast.LENGTH_SHORT).show();        fbtn.setText("呵呵哒");        getView().setBackgroundColor(Color.RED);    }    // TODO: Rename method, update argument and hook method into UI event    public void onButtonPressed(Uri uri) {        if (mListener != null) {            mListener.onFragmentInteraction(uri);        }    }    @Override    public void onAttach(Activity activity) {        super.onAttach(activity);        try {            mListener = (OnFragmentInteractionListener) activity;        } catch (ClassCastException e) {            throw new ClassCastException(activity.toString()                    + " must implement OnFragmentInteractionListener");        }    }    @Override    public void onDetach() {        super.onDetach();        mListener = null;    }    /**     * This interface must be implemented by activities that contain this     * fragment to allow an interaction in this fragment to be communicated     * to the activity and potentially other fragments contained in that     * activity.     * <p/>     * See the Android Training lesson <a href=     * "http://developer.android.com/training/basics/fragments/communicating.html"     * >Communicating with Other Fragments</a> for more information.     */    public interface OnFragmentInteractionListener {        // TODO: Update argument type and name        public void onFragmentInteraction(Uri uri);    }}

主Activity的布局

<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:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:id="@+id/textView" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="button1"        android:id="@+id/button1"        android:layout_below="@+id/textView"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="button2"        android:id="@+id/button2"        android:layout_below="@+id/button1"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true" />    <Button        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="button3"        android:id="@+id/button3"        android:layout_below="@+id/button2"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true" />    <fragment        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:name="test.butterknife.com.testdemo.TestFragment"        android:id="@+id/fragment"        android:layout_alignParentRight="true"        android:layout_alignParentEnd="true"        android:layout_below="@+id/button3"        android:layout_alignParentLeft="true"        android:layout_alignParentStart="true"        android:layout_alignParentBottom="true" /></RelativeLayout>

大致就是如此,附上源码地址:http://yunpan.cn/cdPg8bUwJa8sv 访问密码 1845

有意参与一些开源项目,容易上手的Team可以找我聊聊,看看可以造福社会不,哈哈哈

1楼heotaeyoung昨天 15:27
PO主厉害哦!!!顶起