Android開発者向けのデータバインディングカスタムビュー双方向バインディング

一緒に書く習慣を身につけましょう!「ナゲッツデイリーニュープラン・4月アップデートチャレンジ」に参加して3日目です。クリックしてイベントの詳細をご覧ください

序文

この記事のデフォルトの読者は、データバインディングについてある程度理解しています。よくわからない場合は、DataBindingを使用するための最も完全な手順を参照してください。多くの人がデータバインディングを拒否しますが、一部の人はそれを使用したいと考えています。それは物議を醸すものですが、それは私たちが学び、理解することを妨げるものではありません。
この記事では、カスタムビューがデータを両方向にバインドする方法について説明します。これにより、xmlでカスタマイズを使用して、app:customvalue = "@={userName}"の効果を実現することもできます。

app:xx = "@ {userName}"一方向バインディング
app:xx = "@={userName}"双方向バインディング

Databingdingを紹介します

1.最初のステップはkaptプラグイン
を導入することです。2。2image.png番目のステップはデータバインディングを
有効です(新しいバージョンのgradleと古いバージョンの違いは、特定のバージョンであり、それを知っている人はコメントエリアで教えてください)新しいバージョンのgradle

buildFeatures.dataBinding = true
复制代码

image.png古いバージョンのgradle

android{
/.../ 
    dataBinding { 
        enabled = true;
    } 
}
复制代码

実装コード

ここで提供される実装方法は、間違いなく最適なソリューションまたは最良のソリューションではありませんが、他の人を引き付けるための少しの知識としてはより適しています。

1.プロジェクト全体のディレクトリを見てみましょう

image.png

2.まず、デモンストレーションとしてTextViewとEditTextを使用して新しいCustomViewを作成します。

class CustomView(mContext: Context, attributeSet: AttributeSet?) :
    LinearLayout(mContext, attributeSet) {
    private var onChangeListener: InverseBindingListener? = null
    private var onInputChangeListener: InverseBindingListener? = null
    private var itemInput: EditText? = null
    private var itemText: TextView? = null
    var etInput = ""
        set(value) {
            val oldValue = field
            if (value == oldValue) {
                return;
            }
            field = value
            onInputChangeListener?.onChange()
        }

    var tvValue = ""
        set(value) {
            val oldValue = field
            if (value == oldValue) {
                return;
            }
            field = value
            onChangeListener?.onChange()
        }

    init {
        initView(mContext, attributeSet)
    }


    private fun initView(mContext: Context, attributeSet: AttributeSet?) {
        val view = inflate(mContext, R.layout.widget_custom_view, this)
        itemInput = view.findViewById(R.id.et_input)
        itemText = view.findViewById(R.id.tv_value)
        itemText?.setOnClickListener {
            tvValue = System.currentTimeMillis().toString()
            itemText?.text = tvValue
        }
        itemInput?.doOnTextChanged { text, start, before, count ->
            etInput = text.toString()
        }
    }

    internal fun setOnInputChangeListener(listener: InverseBindingListener) {
        if (onInputChangeListener == null) {
            this.onInputChangeListener = listener
        }
    }

    internal fun setOnValueChangeListener(listener: InverseBindingListener) {
        if (onChangeListener == null) {
            this.onChangeListener = listener
        }
    }
}
复制代码

widget_custom_view.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="100dp"
  android:orientation="vertical">

  <TextView
    android:id="@+id/tv_value"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/purple_200"
    android:gravity="center"
    android:hint="请选择"
    android:textColor="@color/white"
    android:textColorHint="@color/white"
    android:textSize="16dp" />

  <EditText
    android:id="@+id/et_input"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:background="@color/teal_700"
    android:gravity="center"
    android:hint="请输入"
    android:textColor="@color/white"
    android:textColorHint="@color/white"
    android:textSize="16dp" />
</LinearLayout>
复制代码

3.新しいBindAdapter管理クラスDatabindComponentクラスを作成して、関連する使用法を管理するか、BindMethodによってCustomViewにコードを記述します。

object DataBindComponent {

    @BindingAdapter("itemInput")
    @JvmStatic
    fun CustomView.setItemInputParams(value: String) {
        etInput = value
    }

    @InverseBindingAdapter(attribute = "itemInput", event = "itemInputAttrChanged")
    @JvmStatic
    fun getItemInputParams(view: CustomView): String {
        return view.etInput
    }

    @BindingAdapter(value = ["itemInputAttrChanged"], requireAll = false)
    @JvmStatic
    fun CustomView.itemPutChange(textAttrChanged: InverseBindingListener) {
        setOnInputChangeListener(textAttrChanged)
    }

    @BindingAdapter("itemValue")
    @JvmStatic
    fun CustomView.setItemValueParams(value: String) {
        tvValue = value
    }

    @InverseBindingAdapter(attribute = "itemValue", event = "itemValueAttrChanged")
    @JvmStatic
    fun getItemValueParams(view: CustomView): String {
        return view.tvValue
    }

    @BindingAdapter(value = ["itemValueAttrChanged"], requireAll = false)
    @JvmStatic
    fun CustomView.itemValueChange(textAttrChanged: InverseBindingListener) {
        setOnValueChangeListener(textAttrChanged)
    }
}
复制代码

4. xmlにCustomViewを追加し、データの監視とバインドのために2つのObservableFieldsを追加します

image.png

image.png

要約する

GitHubコードリポジトリが投稿されない理由は、これらのサンプルコードがMoudleを介してプロジェクトで記述されており、一部はリリースに適していないためです。すべてのキーコードが解除され、一部の使用済みコードのみが写真で表示されます。カスタムビューを両方向にバインドする必要がある場合は、上記の例が完全に役立ちます。より良い書き方がある場合は、コメント領域で教えてください。

おすすめ

転載: juejin.im/post/7086001692860219428