美文网首页
Android 获取控件id的三种方式

Android 获取控件id的三种方式

作者: 枫叶豆腐汤 | 来源:发表于2018-01-06 17:30 被阅读5256次

前言:

获取控件是入门的基本的,相信这个不用说就知道怎么得到资源文件中的控件id

  1. 有findViewbyid
  2. 有注解方式
  3. 反射的方式

通过findViewbyid获取

  • 原理

  • 我们点击进入Activity.java类中看源码,通过源码我们发现返回的是getWindow.findViewById,这个window是什么呢?我们再次点击进去看看,

···
/**
* Finds a view that was identified by the id attribute from the XML that
* was processed in {@link #onCreate}.
*
* @return The view if found or null otherwise.
*/
@Nullable
public View findViewById(@IdRes int id) {
return getWindow().findViewById(id);
}
···

  • 进入window发现是window,window是一个抽象类,window不能实现UI界面,那么这个getDecorView()返回的是一个VIew来管理Activity UI界面的
    /**
     * Finds a view that was identified by the id attribute from the XML that
     * was processed in {@link android.app.Activity#onCreate}.  This will
     * implicitly call {@link #getDecorView} for you, with all of the
     * associated side-effects.
     *
     * @return The view if found or null otherwise.
     */
    @Nullable
    public View findViewById(@IdRes int id) {
        return getDecorView().findViewById(id);
    }
//通过findViewbyid获取布局文件中的id
TextView tv=(TextView)findViewbyid(R.id.text);//

接下来我们看看注解方式
通过在线引用butterknife jar包就行了
//只需要在每个ID上设置对应的注解即可
@BindView(R.id.img1)
private ImageView img1;`对没有看错就是这么简单

 再来看看反射获取的
/**
     * 使用java反射机制
     * 设置Activity不用findViewbyid
     */
    private void smartInject() {
        try {
            Class<? extends Activity> clz = getClass();

            while (clz != BaseActivity.class) {
                Field[] fs = clz.getDeclaredFields();
                Resources res = getResources();
                String packageName = getPackageName();
                for (Field field : fs) {
                    if (!View.class.isAssignableFrom(field.getType())) {
                        continue;
                    }
                    int viewId = res.getIdentifier(field.getName(), "id", packageName);
                    if (viewId == 0)
                        continue;
                    field.setAccessible(true);
                    try {
                        View v = findViewById(viewId);
                        field.set(this, v);
                        Class<?> c = field.getType();
                        Method m = c.getMethod("setOnClickListener", View.OnClickListener.class);
                        m.invoke(v, this);
                    } catch (Throwable e) {
                    }
                    field.setAccessible(false);

                }
                clz = (Class<? extends Activity>) clz.getSuperclass();
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    //这是我项目中封装在BaseActivity的,可以直接在BaseActivity中放在onCreate就行了,具体的看自己BaseActivity怎么封装了0.0

那么在Activity或者fragment中怎么使用的呢,很简单、个人觉得比findViewbyid和注解bindView方便多了,只需要跟布局文件中的id相同就行了,有点类似kotlin那样,不过还是没有kotlin Android那样简洁方便
end

相关文章

网友评论

      本文标题:Android 获取控件id的三种方式

      本文链接:https://www.haomeiwen.com/subject/dzgynxtx.html