Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法

最近在通过阅读《第一行代码》第三版的方式去学习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()
            }
        }
    }

}


<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" />
    
    <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"/>

    
    <ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"
        android:max="100"
        />
LinearLayout>

实现的功能很简单就是获取文本框中输入的内容并将其打到toast上。
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第1张图片
如果改用viewBinding去做,首先发现以为viewBinding是创建在onCreate方法中的,无法在onCLick方法中获得
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第2张图片
首先想到的解决方式是直接在onClick中再创建一个viewBinding实例不就好了。
这样改动以后代码不报错了。
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第3张图片
运行之后发现虽然调用了toast,但是无法正确显示输入的文本内容,原因是因为绑定了两次视图的缘故,更深层的原因还在研究Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第4张图片
那么在这种使用场景之下,我们该如何使用viewBinding去实现对视图的一次绑定,并且可以在别的方法中调用,实现功能呢?
选择将viewBinding设置为全局变量,用懒加载的方式实现实例化,具体操作如下。
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第5张图片

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插件的话直接可以完成注册
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第6张图片

如果是用viewBinding,并且使用第一种用法中的懒加载,发现无法通过setContextView的方式将根视图注册进去,因为setContextView是Activity的方法而TitleLayout继承自LinearLayout,LinearLayout继承自ViewGroup,ViewGroup继承自View。绕来绕去一句话说明白就是这个类他是个视图。
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第7张图片
难道说在自定义组件中我们就要使用findViewById<>()方法去注册视图了吗?
我们点开app\build\generated\data_binding_base_class_source_out下生成的TitleBinding.java文件,发现有两个inflate方法,一个是之前使用的一个参数的,另一个则是三个参数的方法,并且第二个参数的类型是ViewGrop,第三个参数输入的是attachToParent,输入一个boolean类型参数表示是否连接到父View
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第8张图片
那么我们可以对我们的代码做出如下修改

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()
        }
    }
}

运行效果:

Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法_第9张图片

你可能感兴趣的:(Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法)