赞
踩
最近在通过阅读《第一行代码》第三版的方式去学习Android开发,但是因为成书时间与Android发展,书上有些内容已经发现改变。改动较为明显的一个便是在AS1.4.2之后的版本中viewBinding将逐步替代kotlin-android-extensions去实现对View的实例化。
具体官方文章如下:Kotlin Android Extensions 的未来计划
于是在后续的学习中我也选择了使用viewBinding去绑定控件。
在书中4.2.2章节使用了接口的方式来注册监听器
1.使用接口注册监听器并在监听器中调用其他view
class MainActivity : AppCompatActivity(), View.OnClickListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) button.setOnClickListener(this) } override fun onClick(v: View?) { when (v?.id) { R.id.button -> { val inputText = editText.text.toString() Toast.makeText(this, inputText, Toast.LENGTH_SHORT).show() } } } }
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <TextView android:id="@+id/textView" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="#00ff00" android:textSize="24sp" android:text="This is TextView" android:gravity="center" /> <!--android:gravity 指定文字样式--> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Button" android:textAllCaps="false"/> <EditText android:id="@+id/editText" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="这是一段提示" android:maxLines="2"/> <!--<ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@mipmap/pic1"/>--> <ProgressBar android:id="@+id/progressBar" android:layout_width="match_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:max="100" /> </LinearLayout>
实现的功能很简单就是获取文本框中输入的内容并将其打到toast上。
如果改用viewBinding去做,首先发现以为viewBinding是创建在onCreate方法中的,无法在onCLick方法中获得
首先想到的解决方式是直接在onClick中再创建一个viewBinding实例不就好了。
这样改动以后代码不报错了。
运行之后发现虽然调用了toast,但是无法正确显示输入的文本内容,原因是因为绑定了两次视图的缘故,更深层的原因还在研究
那么在这种使用场景之下,我们该如何使用viewBinding去实现对视图的一次绑定,并且可以在别的方法中调用,实现功能呢?
选择将viewBinding设置为全局变量,用懒加载的方式实现实例化,具体操作如下。
class MainActivity : AppCompatActivity(), View.OnClickListener { private lateinit var viewbinding:ActivityMainBinding override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) viewbinding = ActivityMainBinding.inflate(layoutInflater) setContentView(viewbinding.root) viewbinding.button.setOnClickListener(this) } override fun onClick(v: View?) { when (v?.id) { R.id.button -> { val inputText = viewbinding.editText.text.toString() Toast.makeText(this, inputText, Toast.LENGTH_SHORT).show()//viewbinding.imageView.setImageResource(R.mipmap.pic2) //viewbinding.progressBar.progress += 10 /*if(viewbinding.progressBar.visibility == View.VISIBLE) { viewbinding.progressBar.visibility = View.GONE } else { viewbinding.progressBar.visibility = View.VISIBLE }*/ /*AlertDialog.Builder(this).apply { setTitle("This is Dialog") setMessage("Something important") setCancelable(false) setPositiveButton("ok") { dialog,which -> } setNegativeButton("Cancel") {dialog, which ->} show() }*/ } } } }
第二种用法:viewBinding在自定义控件中的使用
首先推荐我学习时参考的一篇博文:【JetPack】视图绑定 ( ViewBinding ) 各种应用 ( 视图绑定两种方式 | Activity 布局 | 对话框布局 | 自定义组件布局 | RecyclerView 列表布局 )
在学习到《第一行代码》的4.4.2的时候,作者使用了自定义控件的形式去注册按钮,代码如下:
class TitleLayout(context: Context, attrs: AttributeSet) : LinearLayout(context, attrs) {
init {
LayoutInflater.from(context).inflate(R.layout.title, this)
titleBack.setOnClickListener {
val activity = context as Activity
activity.finish()
}
titleEdit.setOnClickListener {
Toast.makeText(context, "You clicked Edit button", Toast.LENGTH_SHORT).show()
}
}
}
点击Back销毁Activity,点击EDIT将一段文本以toast的形式输出到屏幕,同样如果使用ko-an-ex插件的话直接可以完成注册
如果是用viewBinding,并且使用第一种用法中的懒加载,发现无法通过setContextView的方式将根视图注册进去,因为setContextView是Activity的方法而TitleLayout继承自LinearLayout,LinearLayout继承自ViewGroup,ViewGroup继承自View。绕来绕去一句话说明白就是这个类他是个视图。
难道说在自定义组件中我们就要使用findViewById<>()方法去注册视图了吗?
我们点开app\build\generated\data_binding_base_class_source_out下生成的TitleBinding.java文件,发现有两个inflate方法,一个是之前使用的一个参数的,另一个则是三个参数的方法,并且第二个参数的类型是ViewGrop,第三个参数输入的是attachToParent,输入一个boolean类型参数表示是否连接到父View
那么我们可以对我们的代码做出如下修改
class TitleLayout(context: Context, attributeSet: AttributeSet): LinearLayout(context, attributeSet) {
private lateinit var titleBinding: TitleBinding
init {
titleBinding = TitleBinding.inflate(LayoutInflater.from(context),this,true)
titleBinding.titleBack.setOnClickListener {
val activity = context as Activity
activity.finish()
}
titleBinding.titleEdit.setOnClickListener {
Toast.makeText(context, "You clicked Edit button", Toast.LENGTH_SHORT).show()
}
}
}
运行效果:
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。