美文网首页
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