欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-03-05 16:17:00
最近在通过阅读《第一行代码》第三版的方式去学习Android开发,但是因为成书时间与Android发展,书上有些内容已经发现改变。改动较为明显的一个便是在AS1.4.2之后的版本中viewBinding将逐步替代kotlin-android-extensions去实现对View的实例化。具体官方文章如下:......

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

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的两种用法

如果是用viewBinding,并且使用第一种用法中的懒加载,发现无法通过setContextView的方式将根视图注册进去,因为setContextView是Activity的方法而TitleLayout继承自LinearLayout,LinearLayout继承自ViewGroup,ViewGroup继承自View。绕来绕去一句话说明白就是这个类他是个视图。
Android Studio1.4.2后使用viewBindin替代kotlin-android-extensions的两种用法
难道说在自定义组件中我们就要使用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的两种用法
那么我们可以对我们的代码做出如下修改

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的两种用法

本文地址:https://blog.csdn.net/wobuyaoshiye/article/details/112602587