在Kotlin中,一个非常好用的特性是:可以直接使用控件 ID 对控件进行操作,而不需要像 Java 中那样先声明控件,使用 findViewById() 来找到控件,然后才能操作该控件。 反编译后可知,这种用法的原理是 Kotlin 会自动生成类似 findViewById() 的方法:findCachedViewById(),在这个方法里面创建一个 HashMap 缓存每次查找到的 View 在findCachedViewById()中,会先通过缓存 HashMap 的 get 方法来获取控件, get() 中传入的 key 即控件 ID,由于第一次 get 的值为 null ,因此会调用findViewById 可以看到, fragment 里面跟前面的基本原理类似,同样也是在findCachedViewById()中创建缓存 Map,区别在于 fragment 里面是通过getView()来 findViewById 好了,Kotlin 中不再使用 findViewById、而是直接使用控件 ID 来操作控件 的原理就说到这里。
---- 前言 今天我们一块来聊聊项目常用的findViewById,这个东西可以简单理解为: 初始化控件,实例化控件,方便进行其他操作 一般来说,我们通常这么写: private void ,但是在实际项目中,每个Activity,Fragment或者Adapter中有n个控件,每个控件都需要我们实例化控件,才能对其进行操作,一次次的findViewById,感觉好烦呐~! 当然有很多种方式,但是我们要找适合自己项目的,下面将会为大家依次举例说明~ 变迁路 漫漫其修远兮 通过注解方式简化findViewById 在前几年,Xutils比较火爆,火爆的原因有很多,简单列举下, LZ更看好Xutils使用方便,至少为我们封装了很多常用的工具,就好比常用的恶心的图片处理,Xutils有很好的支持,同样,Xutils也支持注解方式去简化findViewById,简单举例如下: // 通过泛型来简化findViewById ? 抽取泛型方法为公共类 ? ? 谷歌爸爸的DataBinding ? ? ? ? ? ? ? ? ? ?
从 Android Studio 3.6 开始,视图绑定能够通过生成绑定对象来替代 findViewById,从而可以帮您简化代码、移除 bug,并且从 findViewById 的模版代码中解脱出来 findViewById(R.id.image) 这样的,导致类型转换错误的代码。 视图绑定生成的代码是怎样的 如前文所说,视图绑定会生成一个包含替代 findViewById 功能的 Java 类。 (R.id.button); TextView subtext = rootView.findViewById(R.id.subtext); TextView title = rootView.findViewById " 二者都是目前十分成功的组件库,有许多应用使用它们解决 findViewById 的问题。
在搜索框中输入findViewByMe,找到它并安装 重启Android studio 在写好的xml文件 中,右击找到findViewByMe(记住是在xml文件中进行该步操作),然后就可以快速获得findViewById
但是在这个findViewById方法中到底发生了什么? 为什么要传入一个资源 id? 为什么会有另外一个括号强制转换呢? ,并且传入一个资源 id,findViewById 方法会找到与传入的 id 相对应的 View,Activity 在 XML 的视图层次结构中搜索这个视图,再在 onCreate 方法中处理它,这个 然后 findViewById 方法遍历它,找到那个视图层次结构中的某个 View,这个方法的返回值是 View 类型的对象。 这就意味着在 activity 代码中 我们可以调用 findViewById传入我们所需 View 的资源 id,然后它就会返回一个 View 对象,我们就可以把它当做变量存在 activity 中( TextView textView = (TextView) findViewById(R.id.textview); 不报错了!
安卓扩展是 IntelliJ IDEA 与 Android Studio 的 Kotlin 插件的组成之一,因此不需要再单独安装额外插件。
也可以认作是本人对它的理解和认识 1.问题引入 我们现在需要实现findViewById,通常是这么写的 TextView tv = (TextView) view.findViewById(R.id.tv_name ); 要实现findViewById,需要四个参数(控件类型,控件变量名,宿主view(通常是activity,我们一般省去),以及控件id) BindView 通常是如下使用的 @BindView( R.id.tv_name) TextView mTv; 此时,四个参数中已经有了三个参数,最后一个宿主参数可以另外传进去 2.具体实现细节 (1)ViewFinder和它的实现类ActivityViewFinder就是实现findViewById
开发小窍门 我相信在移动开发最重要的一件事,也是相当麻烦的一件事就是写布局,对于Android开发者来说,写布局耗费了大量时间,然后初始化控件,写findViewById去类型转换也是耽误了很多时间,今天就告诉你一个小窍门 ,通过泛型来简化findViewById类型转换。 protected <T extends View> T generateFindViewById(int id) { //return返回view时,加上泛型T return (T) findViewById 自己写的Activity都去继承BaseActivity 之后我们自己写的每一个Activity都去继承BaseActivity,然后在初始化控件时直接使用generateFindViewById来代替findViewById
在一些需要后续变动的 View,都会使用一个变量将 View 存起来,就是为了避免每次都调用 findViewById()。 看似没有任何问题,我们可以放心使用,但是实际上还有一些场景,可能会导致频繁的调用 findViewById(),引发效率问题。 本文就这个问题,展开讨论 Kotlin 通过 View ID 访问 View 的原理,以及频繁调用 findViewById() 的问题。 二. Kotlin 虽然干掉了 findViewById(),并且实现上还有一些优化,但是使用 view.view 的操作方式,依然会回归到原始的 findViewById(),从而对性能造成影响。 以及它内部是如何实现的,它会利用一个 HashMap 结构,实现了缓存,避免 findViewById() 被重复调用。
(this); this.channelButton = (TextView) findViewById; View findViewById2 = findViewById = (TextView) findViewById2; View findViewById3 = findViewById(R.id.recording_restart_btn); ; View findViewById4 = findViewById(R.id.recording_finish_btn); ((TextView) findViewById4 = findViewById(R.id.recording_finish_btn); ((TextView) findViewById5).setOnClickListener(this ); this.switchCameraButton = (TextView) findViewById5; View findViewById6 = findViewById
(R.id.item1); View item2 = view.findViewById(R.id.item2); TextView item1_tv1,item1_tv2,item1_tv3,item1 (R.id.tv1); item1_tv2 = item1.findViewById(R.id.tv2); item1_tv3 = item1.findViewById(R.id.tv3); item1 _tv4 = item1.findViewById(R.id.tv4); item1_tv5 = item1.findViewById(R.id.tv5); item1_tv6 = item1.findViewById (R.id.tv1); item2_tv2 = item2.findViewById(R.id.tv2); item2_tv3 = item2.findViewById(R.id.tv3); item2 _tv4 = item2.findViewById(R.id.tv4); item2_tv5 = item2.findViewById(R.id.tv5); item2_tv6 = item2.findViewById
调用View中的findViewById()方法获取一次控件的实例,这也是一个很耗时的操作,可以进行优化。 version = (TextView)convertView.findViewById(R.id.version); TextView size = (TextView)convertView.findViewById = (TextView)convertView.findViewById(R.id.version); holder.size = (TextView)convertView.findViewById .当ConvertView被重新利用的时候,ViewHolder也随之取出,从而可以直接给各个控件赋值,而无需再次调用findViewById方法。 结论: 无论总量是多少,findViewById方法最多可以调用N+1组(N为一屏可以显示的item的数量) 通过ViewHolder的方法,可以将所有的控件进行缓存,不需要每次通过findViewById
) view.findViewById(R.id.tv_pass1); tvList[1] = (TextView) view.findViewById(R.id.tv_pass2); tvList [2] = (TextView) view.findViewById(R.id.tv_pass3); tvList[3] = (TextView) view.findViewById(R.id.tv_pass4 ); tvList[4] = (TextView) view.findViewById(R.id.tv_pass5); tvList[5] = (TextView) view.findViewById ) view.findViewById(R.id.tv_pass1); tvList[1] = (TextView) view.findViewById(R.id.tv_pass2); tvList ); tvList[4] = (TextView) view.findViewById(R.id.tv_pass5); tvList[5] = (TextView) view.findViewById
所以学习ListView的优化很重要,而本节针对的是BaseAdapter的优化,优化的两点有,复用convertView 以及使用ViewHolder重用组件,不用每次都findViewById,我们具体通过代码来体会吧 txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); img_icon.setBackgroundResource txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); img_icon.setBackgroundResource ); TextView text_aName = convertView.findViewById(R.id.txt_aName); TextView text_aSpeak = convertView.findViewById holder.txt_aSpeak = (TextView) convertView.findViewById(R.id.txt_aSpeak); convertView.setTag(
概述 是不是厌烦了重复的findViewbyId,这里我们介绍一个Android Studio 插件 –Android Layout ID Converter 下载及安装 下载 github-OffingHarbor 变量前面的标识: 第一个是 直接就是你xml文件中id的名称 第二个是加个m 第三个是加个_ 按照个人编码选择即可 Conversion Format: 转换格式 : 第一个就是普通的findViewbyId = (Button) findViewById(R.id.btnSingleChoiceList); mBtnMultiChoiceList = (Button) findViewById(R.id.btnMultiChoiceList ); mBtnRemoveDialog = (Button) findViewById(R.id.btnRemoveDialog); } 注意事项:在Fragment或者动态加载布局使用View 的地方,需要在findViewById前手动添加view.
(R.id.button1); 13 textView=(TextView)findViewById(R.id.text1); 14 myToggle=(ToggleButton )findViewById(R.id.toggleButton1); 15 myCheck=(CheckBox)findViewById(R.id.checkBox1); 16 RadioButton radio=(RadioButton)findViewById(R.id.radioButton2); 17 RadioButton radio1=(RadioButton)findViewById .setChecked(isChecked); 46 radio1=(RadioButton)findViewById(R.id.radioButton2); 47 radio1 isChecked); 48 49 } 这里我们通过findViewById()来获取控件,并实现了控件的监听 setonCheckedChangeListener; 2.CheckBox
(R.id.ivcpu); ivcm=(ImageView) findViewById(R.id.ivcm); tvshow=(TextView)findViewById (R.id.tvshow); edtcm=(EditText) findViewById(R.id.edtcm); btnok=(Button)findViewById( )findViewById(R.id.tvshow); edtcm=(EditText) findViewById(R.id.edtcm); btnok=(Button)findViewById(R.id.buttonok); lvcmsjs=(ListView) findViewById(R.id.lvcmsz btnok=(Button)findViewById(R.id.buttonok); lvcmsjs=(ListView) findViewById(R.id.lvcmsz
1 首先想到的就是使用泛型函数实现 public <T extends View> T findViewById(int resId){ return (T)itemView.findViewById public <T extends View> T dingViewById(int resId, Class<T> cla ){ return cla.cast(itemView.findViewById (resId)); }另一种实现 public <T extends View> T findViewById(int resId, Class<? extends T> cla) { return cla.cast(itemView.findViewById(resId)); } 我们看看怎么使用 dingViewById(R.id.holder_desc ); 当然了这个在Java中就是个鸡肋,但是到了Kotlin就十分有用,因为Java没有扩展而Kotlin使用extension的我们可以直接给Activity/View添加扩展函数实现即可方便的实现findViewById
在实际开发中LayoutInflater这个类还是非常有用的,它的作用类似于findViewById()。 不同点是LayoutInflater是用来找res/layout/下的xml布局文件,并且实例化;而findViewById()是找xml布局文件下的具体widget控件(如Button、TextView 2、对于一个已经载入的界面,就可以使用Activiyt.findViewById()方法来获得其中的界面元素。 = (EditText)view.findViewById(R.id.content); 对于上面代码,指定了第二个参数 ViewGroup root,当然你也可以设置为 null 值。 注意: ·inflate方法与 findViewById 方法不同; ·inflater 是用来找 res/layout下的 xml 布局文件,并且实例化; ·findViewById() 是找具体 xml
(R.id.comment_author_image); authorName = itemView.findViewById(R.id.comment_author_name) ; praiseNum = itemView.findViewById(R.id.comment_praise_nums); commontContent = itemView.findViewById(R.id.comment_content); touchGood = itemView.findViewById(R.id.touch_good (R.id.colopedia_recycler); commentSubmit = (TextView) findViewById(R.id.comment_submit); editText = (EditText) findViewById(R.id.colopedia_comment_content); commentSubmit.setOnClickListener(this