{"id":1622,"date":"2022-12-14T14:15:21","date_gmt":"2022-12-14T06:15:21","guid":{"rendered":"https:\/\/badgameshow.com\/fly\/?p=1622"},"modified":"2023-02-03T11:33:24","modified_gmt":"2023-02-03T03:33:24","slug":"%e3%80%90jetpack%e3%80%91android-databinding-%e6%95%b8%e6%93%9a%e7%b6%81%e5%ae%9a-%e7%af%84%e4%be%8b","status":"publish","type":"post","link":"https:\/\/badgameshow.com\/fly\/%e3%80%90jetpack%e3%80%91android-databinding-%e6%95%b8%e6%93%9a%e7%b6%81%e5%ae%9a-%e7%af%84%e4%be%8b\/","title":{"rendered":"\ud83d\udd00\u3010Jetpack\u3011Android DataBinding \u6578\u64da\u7d81\u5b9a \u7bc4\u4f8b\ud83d\udd27"},"content":{"rendered":"<h1>\ud83d\udd00\u3010Jetpack\u3011Android DataBinding \u6578\u64da\u7d81\u5b9a \u7bc4\u4f8b\ud83d\udd27<\/h1>\n<h4>Android Databinding \u662f Android \u5e73\u53f0\u4e0a\u63d0\u4f9b\u7684\u4e00\u500b\u58d3\u7e2e\u958b\u767c\u6d41\u7a0b\u548c\u63d0\u5347\u53ef\u7dad\u8b77\u6027\u7684\u8cc7\u6599\u7d81\u5b9a\u6a5f\u5236\uff0c\u5176\u4e3b\u8981\u529f\u80fd\u70ba\u7c21\u5316 Android \u5c0d\u61c9\u7528\u7a0b\u5e8f UI \u7684\u6578\u64da\u7e6b\u7d50\u548c\u8cc7\u6599\u6d41\u50b3\u905e\uff0c\u4f8b\u5982\u5c07\u529f\u80fd\u63a7\u4ef6\u8207\u8cc7\u6599\u6a21\u578b\u4e2d\u5b58\u5132\u7684\u6578\u64da\u7e6b\u7d50\u5728\u4e00\u8d77\uff0c\u4f7f\u61c9\u7528\u7a0b\u5e8f\u7684\u6700\u7d42\u7528\u6236\u53ef\u4ee5\u7528\u4e00\u500b\u76f8\u5c0d\u7c21\u6f54\u7684\u8a9e\u6cd5\u5c07\u529f\u80fd\u63a7\u4ef6\u7684\u6578\u64da\uff08\u5c6c\u6027\uff09\u8207\u8cc7\u6599\u6a21\u578b\u7e6b\u7d50\u5728\u4e00\u8d77\uff0c\u7b26\u5408\u4f4e\u8026\u5408\u548c\u9ad8\u53ef\u64f4\u5c55\u6027\u7684\u539f\u5247\uff0c\u964d\u4f4e\u7a0b\u5e8f\u7684\u958b\u767c\u3001\u7dad\u8b77\u548c\u6e2c\u8a66\u7684\u6210\u672c\uff0c\u63d0\u9ad8\u958b\u767c\u7684\u6548\u7387\u3002<\/h4>\n<hr \/>\n<h4>\u6587\u7ae0\u76ee\u9304<\/h4>\n<ol>\n<li><a href=\"#a\">DataBinding &#038; Fragment KTX \u5c0e\u5165<\/a><\/li>\n<li><a href=\"#b\">DataBinding<\/a><\/li>\n<li><a href=\"#c\">DataBinding StateFlow \u914d\u5408 ViewModel \u66f4\u65b0 UI<\/a><\/li>\n<li><a href=\"#d\">DataBinding \u81ea\u5b9a\u7fa9\u55ae\u53c3\u6578\u5c6c\u6027<\/a><\/li>\n<li><a href=\"#e\">DataBinding \u81ea\u5b9a\u7fa9\u591a\u53c3\u6578\u5c6c\u6027<\/a><\/li>\n<li><a href=\"#f\">DataBinding \u5c0e\u5165 View \u5beb\u5224\u65b7<\/a><\/li>\n<li><a href=\"#g\">Developer Documents DataBinding<\/a><\/li>\n<\/ol>\n<hr \/>\n<p><a id=\"a\"><\/a><\/p>\n<h4>1.DataBinding &amp; Fragment KTX \u5c0e\u5165<\/h4>\n<h5>build.gradle<\/h5>\n<pre><code class=\"language-groovy line-numbers\">android {\n\n    buildFeatures {\n        dataBinding true\n    }\n}\n\ndependencies {\n    def fragment_version = \"1.5.5\"\n    implementation \"androidx.fragment:fragment-ktx:$fragment_version\"\n}\n<\/code><\/pre>\n<p><a id=\"b\"><\/a><\/p>\n<h4>2.DataBinding<\/h4>\n<h5>activity_main.xml<\/h5>\n<pre data-language=XML><code class=\"language-markup line-numbers\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;layout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\n\n    &lt;data&gt;\n        &lt;variable\n            name=\"name\"\n            type=\"String\" \/&gt;\n\n        &lt;variable\n            name=\"age\"\n            type=\"Integer\" \/&gt;\n    &lt;\/data&gt;\n\n    &lt;androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\".MainActivity\"&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:text=\"@{name + '\\n' + age}\"\n            android:textSize=\"50sp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" \/&gt;\n\n    &lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\n&lt;\/layout&gt;\n<\/code><\/pre>\n<h5>MainActivity.kt<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">class MainActivity : AppCompatActivity() {\n\n    lateinit var binding: ActivityMainBinding\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)\n\n        binding.name = \"Wade\"\n        binding.age = 26\n    }\n}\n<\/code><\/pre>\n<p><a id=\"c\"><\/a><\/p>\n<h4>3.DataBinding StateFlow \u914d\u5408 ViewModel \u66f4\u65b0 UI<\/h4>\n<h5>PersonViewModel.kt<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">class PersonViewModel : ViewModel() {\n\n    private val _name = MutableStateFlow(\"Fly\")\n    val name = _name.asStateFlow()\n\n    private val _age = MutableStateFlow(20)\n    val age = _age.asStateFlow()\n\n    fun changeData() {\n        viewModelScope.launch {\n            _name.emit(\"Wade\")\n            _age.emit(26)\n        }\n    }\n}\n<\/code><\/pre>\n<h5>activity_main.xml<\/h5>\n<pre data-language=XML><code class=\"language-markup line-numbers\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;layout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\n\n    &lt;data&gt;\n\n        &lt;variable\n            name=\"viewModel\"\n            type=\"com.example.jetpackdemo.PersonViewModel\" \/&gt;\n    &lt;\/data&gt;\n\n    &lt;androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\".MainActivity\"&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:onClick=\"@{() -&gt; viewModel.changeData()}\"\n            android:text=\"@{viewModel.name + '\\n' + viewModel.age}\"\n            android:textSize=\"50sp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" \/&gt;\n\n    &lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\n&lt;\/layout&gt;\n<\/code><\/pre>\n<h5>MainActivity.kt<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">class MainActivity : AppCompatActivity() {\n\n    private lateinit var binding: ActivityMainBinding\n    private val viewModel: PersonViewModel by viewModels()\n\n    override fun onCreate(savedInstanceState: Bundle?) {\n        super.onCreate(savedInstanceState)\n        setContentView(R.layout.activity_main)\n\n        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)\n        binding.viewModel = viewModel\n        binding.lifecycleOwner = this\n\n    }\n}\n<\/code><\/pre>\n<p><a id=\"d\"><\/a><\/p>\n<h4>4.DataBinding \u81ea\u5b9a\u7fa9\u55ae\u53c3\u6578\u5c6c\u6027<\/h4>\n<h5>build.gradle<\/h5>\n<pre><code class=\"language-groovy line-numbers\">plugins {\n    id 'kotlin-kapt'\n}\n<\/code><\/pre>\n<h5>BindingAdapters<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">object BindingAdapters {\n\n    @JvmStatic\n    @BindingAdapter(\"app:hideIfZero\")\n    fun hideIfZero(view: View, name: String) {\n        view.isVisible = name == \"Wade\"\n    }\n}\n<\/code><\/pre>\n<h5>activity_main.xml<\/h5>\n<pre data-language=XML><code class=\"language-markup line-numbers\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;layout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\n\n    &lt;data&gt;\n\n        &lt;variable\n            name=\"viewModel\"\n            type=\"com.example.jetpackdemo.PersonViewModel\" \/&gt;\n    &lt;\/data&gt;\n\n    &lt;androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\".MainActivity\"&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id\/appCompatTextView\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:onClick=\"@{() -&gt; viewModel.changeData()}\"\n            android:text=\"@{viewModel.name + '\\n' + viewModel.age}\"\n            android:textSize=\"50sp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" \/&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Hi\"\n            android:textSize=\"60sp\"\n            app:hideIfZero=\"@{viewModel.name}\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toBottomOf=\"@+id\/appCompatTextView\" \/&gt;\n\n    &lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\n&lt;\/layout&gt;\n<\/code><\/pre>\n<p><a id=\"e\"><\/a><\/p>\n<h4>5.DataBinding \u81ea\u5b9a\u7fa9\u591a\u53c3\u6578\u5c6c\u6027<\/h4>\n<h5>BindingAdapters<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">object BindingAdapters {\n\n    @JvmStatic\n    @BindingAdapter(value = [\"app:realText\", \"app:realTextColor\"], requireAll = true)\n    fun setRealText(view: AppCompatTextView, text: String, color: String) {\n        view.text = text\n        view.setTextColor(Color.parseColor(color))\n    }\n}\n<\/code><\/pre>\n<h5>PersonViewModel.kt<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">class PersonViewModel : ViewModel() {\n\n    private val _name = MutableStateFlow(\"Fly\")\n    private val _age = MutableStateFlow(20)\n    private val _hello = MutableStateFlow(\"Hi\")\n    private val _helloColor = MutableStateFlow(\"#FF0000\")\n\n    val name = _name.asStateFlow()\n    val age = _age.asStateFlow()\n    val hello = _hello.asStateFlow()\n    val helloColor = _helloColor.asStateFlow()\n\n    fun changeData() {\n        viewModelScope.launch {\n            _name.emit(\"Wade\")\n            _age.emit(26)\n            _hello.emit(\"Hello\")\n            _helloColor.emit(\"#FF00FF\")\n        }\n    }\n}\n<\/code><\/pre>\n<h5>activity_main.xml<\/h5>\n<pre data-language=XML><code class=\"language-markup line-numbers\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;layout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\n\n    &lt;data&gt;\n\n        &lt;variable\n            name=\"viewModel\"\n            type=\"com.example.jetpackdemo.PersonViewModel\" \/&gt;\n    &lt;\/data&gt;\n\n    &lt;androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\".MainActivity\"&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id\/appCompatTextView\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:onClick=\"@{() -&gt; viewModel.changeData()}\"\n            android:text=\"@{viewModel.name + '\\n' + viewModel.age}\"\n            android:textSize=\"50sp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" \/&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Hi\"\n            android:textSize=\"60sp\"\n            app:realText=\"@{viewModel.hello}\"\n            app:realTextColor=\"@{viewModel.helloColor}\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toBottomOf=\"@+id\/appCompatTextView\" \/&gt;\n\n    &lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\n&lt;\/layout&gt;\n<\/code><\/pre>\n<p><a id=\"f\"><\/a><\/p>\n<h4>6.DataBinding \u5c0e\u5165 View \u5beb\u5224\u65b7<\/h4>\n<h5>PersonViewModel<\/h5>\n<pre><code class=\"language-kotlin line-numbers\">class PersonViewModel : ViewModel() {\n\n    private val _name = MutableStateFlow(\"Fly\")\n    private val _age = MutableStateFlow(20)\n    private val _nameVisible = MutableStateFlow(true)\n\n    val name = _name.asStateFlow()\n    val age = _age.asStateFlow()\n    val nameVisible = _nameVisible.asStateFlow()\n\n\n    fun changeData() {\n        viewModelScope.launch {\n            _name.emit(\"Wade\")\n            _age.emit(26)\n            _nameVisible.emit(false)\n        }\n    }\n}\n<\/code><\/pre>\n<h5>activity_main.xml<\/h5>\n<pre data-language=XML><code class=\"language-markup line-numbers\">&lt;?xml version=\"1.0\" encoding=\"utf-8\"?&gt;\n&lt;layout xmlns:android=\"http:\/\/schemas.android.com\/apk\/res\/android\"\n    xmlns:app=\"http:\/\/schemas.android.com\/apk\/res-auto\"\n    xmlns:tools=\"http:\/\/schemas.android.com\/tools\"&gt;\n\n    &lt;data&gt;\n        &lt;import type=\"android.view.View\" alias=\"AndroidView\"\/&gt;\n\n        &lt;variable\n            name=\"viewModel\"\n            type=\"com.example.jetpackdemo.PersonViewModel\" \/&gt;\n    &lt;\/data&gt;\n\n    &lt;androidx.constraintlayout.widget.ConstraintLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\".MainActivity\"&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:id=\"@+id\/appCompatTextView\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:gravity=\"center\"\n            android:onClick=\"@{() -&gt; viewModel.changeData()}\"\n            android:text=\"@{viewModel.name + '\\n' + viewModel.age}\"\n            android:textSize=\"50sp\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toTopOf=\"parent\" \/&gt;\n\n        &lt;androidx.appcompat.widget.AppCompatTextView\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:text=\"Hi\"\n            android:textSize=\"60sp\"\n            android:visibility=\"@{viewModel.nameVisible ? AndroidView.VISIBLE : AndroidView.GONE }\"\n            app:layout_constraintBottom_toBottomOf=\"parent\"\n            app:layout_constraintEnd_toEndOf=\"parent\"\n            app:layout_constraintStart_toStartOf=\"parent\"\n            app:layout_constraintTop_toBottomOf=\"@+id\/appCompatTextView\" \/&gt;\n\n    &lt;\/androidx.constraintlayout.widget.ConstraintLayout&gt;\n&lt;\/layout&gt;\n<\/code><\/pre>\n<p><a id=\"g\"><\/a><\/p>\n<h4>7.Developer Documents DataBinding<\/h4>\n<p><a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/developer.android.com\/topic\/libraries\/data-binding\" title=\"Open in Documents DataBinding\" target=\"_blank\" rel=\"noopener\">Open in Documents DataBinding<\/a><\/p>\n\n<div style=\"font-size: 0px; height: 0px; line-height: 0px; margin: 0; padding: 0; clear: both;\"><\/div>","protected":false},"excerpt":{"rendered":"<p>\ud83d\udd00\u3010Jetpack\u3011Android DataBinding \u6578\u64da\u7d81\u5b9a \u7bc4\u4f8b\ud83d\udd27 Android Databind &hellip; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"pgc_sgb_lightbox_settings":"","footnotes":""},"categories":[106],"tags":[13,221,107],"class_list":["post-1622","post","type-post","status-publish","format-standard","hentry","category-jetpack","tag-android","tag-databinding","tag-jetpack"],"_links":{"self":[{"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/posts\/1622","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/comments?post=1622"}],"version-history":[{"count":4,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/posts\/1622\/revisions"}],"predecessor-version":[{"id":1844,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/posts\/1622\/revisions\/1844"}],"wp:attachment":[{"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/media?parent=1622"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/categories?post=1622"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/badgameshow.com\/fly\/wp-json\/wp\/v2\/tags?post=1622"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}