新版Databinding基础教程

前言:
不得不说AS更新到3.4后修复了一些隐藏的Bug并加入了一些新东西,如Bundle打包,DataBinding的写法改动 等等,这些突然让笔者觉得陌生,但历史的车轮滚滚向前,没办法只能跟紧脚步,落后就只能被淘汰,这里着重讲一下Databinding改动后的一些写法。

加入了generateStubs,不需要再引入databinding了
build_gradle写法

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'

android {
    ···
    defaultConfig {
  ·		  ···
    }
    
    dataBinding {
        enabled true
    }

}
kapt {
    generateStubs = true
}

可以看到

  1. ActivityMainBinding是编译器生成的
  2. 使用的androidx的包
  3. 没有熟悉的setContentView()了

Activity 用法

import androidx.appcompat.app.AppCompatActivity
import xxx.xxx.xxx.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(ActivityMainBinding.inflate(layoutInflater, null, false).root)
    }
}

Fragment 用法

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import xxx.xxx.xxx.databinding.FragmentNiceBinding

class NiceFragment : Fragment() {
    private lateinit var binding: FragmentNiceBinding
    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        binding = FragmentNiceBinding.inflate(inflater, container, false)
        binding.setLifecycleOwner(viewLifecycleOwner)
        binding.executePendingBindings()
        return binding.root
    }
}

那么有人会问:那setContentView没有了 是怎么关联布局文件的呢?
查看源码可以知道

  1. activity_main.xml文件已经被封装到ActivityMainBinding 这个类里面了
  2. inflate封装的正是DataBindingUtil,也就是进一步简化了代码
  3. ActivityMainBinding的名字也是根据activity_main来的
    因此你会发现无论
    ActivityxxxBinding inflate 到 xxxFragment
    还是
    FragmentxxxBinding inflate 到 xxxActivity
    都没毛病

Activity的inflate

  @NonNull
  public static ActivityMainBinding inflate(@NonNull LayoutInflater inflater,
      @Nullable ViewGroup root, boolean attachToRoot, @Nullable DataBindingComponent component) {
    return DataBindingUtil.<ActivityMainBinding>inflate(inflater, dae.rounder.R.layout.activity_main, root, attachToRoot, component);
  }

Fragment的inflate

  @NonNull
  public static FragmentPBinding inflate(@NonNull LayoutInflater inflater, @Nullable ViewGroup root,
      boolean attachToRoot, @Nullable DataBindingComponent component) {
    return DataBindingUtil.<FragmentPBinding>inflate(inflater, dae.rounder.R.layout.fragment_p, root, attachToRoot, component);
  }

剩下对之前文章的补充

onclick的三种写法

<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <import type="xxx.MainViewModel"/>

        <variable
                name="mainViewModel"
                type="MainViewModel"/>
    </data>

    <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:onClick="@{mainViewModel::expend}"
            android:orientation="vertical">
        <TextView android:layout_width="match_parent"
                  android:onClick="@{() -> mainViewModel.expend_()}"
                  android:layout_height="300dp" android:text="第一部分"/>
        <TextView android:layout_width="match_parent"
                  android:onClick="@{(v) -> mainViewModel.expend__(v)}"
                  android:layout_height="300dp" android:text="第二部分"/>
    </LinearLayout>
</layout>

可以发现

扫描二维码关注公众号,回复: 9075635 查看本文章
  1. 第二种方法可避免编译器未使用的警告
  2. 第三种方法则可以传参
    fun expend(v: View) {
        Timber.e("expend" + v::class.java.simpleName)
    }

    fun expend_() {
        Timber.e("expend_")
    }

    fun expend__(v: View) {
        Timber.e("expend__${(v as TextView).text}")
    }
发布了141 篇原创文章 · 获赞 40 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/qq_20330595/article/details/90024971