安卓开发懒鬼最爱之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可以找我聊聊,看看可以造福社会不,哈哈哈

目录
相关文章
|
5天前
|
Linux 编译器 Android开发
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
在Linux环境下,本文指导如何交叉编译x265的so库以适应Android。首先,需安装cmake和下载android-ndk-r21e。接着,下载x265源码,修改crosscompile.cmake的编译器设置。配置x265源码,使用指定的NDK路径,并在配置界面修改相关选项。随后,修改编译规则,编译并安装x265,调整pc描述文件并更新PKG_CONFIG_PATH。最后,修改FFmpeg配置脚本启用x265支持,编译安装FFmpeg,将生成的so文件导入Android工程,调整gradle配置以确保顺利运行。
24 1
FFmpeg开发笔记(九)Linux交叉编译Android的x265库
|
28天前
|
Java Android开发
Android 开发获取通知栏权限时会出现两个应用图标
Android 开发获取通知栏权限时会出现两个应用图标
14 0
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
103 0
|
1月前
|
设计模式 人工智能 开发工具
安卓应用开发:构建未来移动体验
【2月更文挑战第17天】 随着智能手机的普及和移动互联网技术的不断进步,安卓应用开发已成为一个热门领域。本文将深入探讨安卓平台的应用开发流程、关键技术以及未来发展趋势。通过分析安卓系统的架构、开发工具和框架,本文旨在为开发者提供全面的技术指导,帮助他们构建高效、创新的移动应用,以满足不断变化的市场需求。
18 1
|
1月前
|
机器学习/深度学习 调度 Android开发
安卓应用开发:打造高效通知管理系统
【2月更文挑战第14天】 在移动操作系统中,通知管理是影响用户体验的关键因素之一。本文将探讨如何在安卓平台上构建一个高效的通知管理系统,包括服务、频道和通知的优化策略。我们将讨论最新的安卓开发工具和技术,以及如何通过这些工具提高通知的可见性和用户互动性,同时确保不会对用户造成干扰。
33 1
|
2天前
|
数据库 Android开发 开发者
安卓应用开发:构建高效用户界面的策略
【4月更文挑战第24天】 在竞争激烈的移动应用市场中,一个流畅且响应迅速的用户界面(UI)是吸引和保留用户的关键。针对安卓平台,开发者面临着多样化的设备和系统版本,这增加了构建高效UI的复杂性。本文将深入分析安卓平台上构建高效用户界面的最佳实践,包括布局优化、资源管理和绘制性能的考量,旨在为开发者提供实用的技术指南,帮助他们创建更流畅的用户体验。
|
19天前
|
XML 开发工具 Android开发
构建高效的安卓应用:使用Jetpack Compose优化UI开发
【4月更文挑战第7天】 随着Android开发不断进化,开发者面临着提高应用性能与简化UI构建流程的双重挑战。本文将探讨如何使用Jetpack Compose这一现代UI工具包来优化安卓应用的开发流程,并提升用户界面的流畅性与一致性。通过介绍Jetpack Compose的核心概念、与传统方法的区别以及实际集成步骤,我们旨在提供一种高效且可靠的解决方案,以帮助开发者构建响应迅速且用户体验优良的安卓应用。
|
21天前
|
监控 算法 Android开发
安卓应用开发:打造高效启动流程
【4月更文挑战第5天】 在移动应用的世界中,用户的第一印象至关重要。特别是对于安卓应用而言,启动时间是用户体验的关键指标之一。本文将深入探讨如何优化安卓应用的启动流程,从而减少启动时间,提升用户满意度。我们将从分析应用启动流程的各个阶段入手,提出一系列实用的技术策略,包括代码层面的优化、资源加载的管理以及异步初始化等,帮助开发者构建快速响应的安卓应用。
|
21天前
|
Java Android开发
Android开发之使用OpenGL实现翻书动画
本文讲述了如何使用OpenGL实现更平滑、逼真的电子书翻页动画,以解决传统贝塞尔曲线方法存在的卡顿和阴影问题。作者分享了一个改造后的外国代码示例,提供了从前往后和从后往前的翻页效果动图。文章附带了`GlTurnActivity`的Java代码片段,展示如何加载和显示书籍图片。完整工程代码可在作者的GitHub找到:https://github.com/aqi00/note/tree/master/ExmOpenGL。
23 1
Android开发之使用OpenGL实现翻书动画
|
21天前
|
Android开发 开发者
Android开发之OpenGL的画笔工具GL10
这篇文章简述了OpenGL通过GL10进行三维图形绘制,强调颜色取值范围为0.0到1.0,背景和画笔颜色设置方法;介绍了三维坐标系及与之相关的旋转、平移和缩放操作;最后探讨了坐标矩阵变换,包括设置绘图区域、调整镜头参数和改变观测方位。示例代码展示了如何使用这些方法创建简单的三维立方体。
18 1
Android开发之OpenGL的画笔工具GL10