DataBinding

در ادامه فیلم قسمت دوم، از دیتابایندینگ استفاده خواهیم کرد!

استفاده از DataBinding:

برای استفاده از DataBinding، ابتدا پروژه را make کنید تا برای ما کلاس ActivityMainBinding تشکیل شود.

Make project:

Build>Make project

بعد از انجام این کار، به کلاس MainActivity.kt رجوع کنید و متغیر binding را تعریف کنید:

private lateinit var binding: ActivityMainBinding

اما همانطور که مشاهده می کنید، کلاس ActivityMainBinding ناشناخته می باشد! چرا؟؟؟ به این دلیل که شما باید در فایل activity_main.xml نیز تغییراتی اعمال کنید! پس به فایل مذکور رجوع کنید:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".MainActivity">

                <TextView
                android:id="@+id/helloWorldTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>
</android.support.constraint.ConstraintLayout>

لایه را در یک layout قرار دهید:

<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                android:id="@+id/helloWorldTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

    </android.support.constraint.ConstraintLayout>
</layout>

حالا دوباره پروژه را Make کنید؛ به کلاس MainActivity.kt برگردید و دوباره متغیر binding را تعریف کنید و همانطور که خواهید دید، کلاس ActivityMainBinding دیگر ناشناخته نیست:

private lateinit var binding: ActivityMainBinding

قدم های بعدی:

در متود onCreate نیز باید تغییراتی اعمال شود:

setContentView(R.layout.activity_main)

به :

binding = DataBindingUtil.setContentView(this,R.layout.activity_main)

تبدیل شود.

مثال ساده:

اگر دقت کرده باشید در لایه MainActivity دارای یک TextView می باشد! حال میخواهیم متن آن را تغییر دهیم:

<TextView
                android:id="@+id/helloWorldTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="Hello World"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

در متود onCreate کلاس MainActivity کدی خواهیم نوشت که بعد از سه ثانیه متن  helloWorldTextView را تغییر دهد:

ابتدا از کلاس Handler استفاده خواهیم کرد:

Handler().postDelayed({
            //Code here
        },3000)

حالا با استفاده از کد زیر متن را تغییر می دهیم:

binding.apply {
helloWorldTextView.text = "salam donya"
}

و در آخر کد ما به این صورت خواهید بود:

Handler().postDelayed({
            binding.apply {
                 helloWorldTextView.text = "salam donya"
            }
        },3000)

اگر توجه کرده باشید ما شئ helloWroldTextView را اصلأ تعریف نکرده بودیم! پس از کجا همچین متغییری وجود داشت؟ جواب ساده است! از کلاس ActivityMainBinding! هر عنصری از UI که داخل هر اکتیویتی ساخته می شود، در کلاس dataBinding مربوطه نیز تعریف خواهد شد بدون اینکه از متود درد آور findViewById استفاده شود!

مثال پیشرفته:

یک کلاس کاتلین به نام User بسازید به این صورت:

data class User(val name: String)

کلاس User حاوی مقداری به نام name می باشد و حالا قصد داریم که از این دیتاکلاس خود در برنامه استفاده کنیم.

ابتدا در activity_main.xml، یک تگ دیتا با نوع User تشکلیل بدهید به این صورت:

<data>
        <variable name="user"
                  type="moeindeveloper.kotlinmvvm.User"/>
    </data>

و حالا می خواهیم از مقدار name در کلاس User برای مقدار Text شئ helloWorldTextView استفاده کنیم! در helloWorldTextView مقدار Text را اینگونه تنظیم کنید:

android:text="@{user.name}"

و در آخر به این گونه خواهد بود:

<?xml version="1.0" encoding="utf-8"?>
<layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    <data>
        <variable name="user"
                  type="moeindeveloper.kotlinmvvm.User"/>
    </data>
    <android.support.constraint.ConstraintLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".MainActivity">

        <TextView
                android:id="@+id/helloWorldTextView"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@{user.name}"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toTopOf="parent"/>

    </android.support.constraint.ConstraintLayout>
</layout>

حال دوباره به MainActivity.kt بر گردید و قبل از تغییر کد، ابتدا پروژه Make کنید تا دیتابایندینگ، شئ های جدید را شناسایی و تعریف کند!

حال به کدی که در مثال ساده نوشتیم دقت کنید:

Handler().postDelayed({
            binding.apply {
                 helloWorldTextView.text = "salam donya"
            }
        },3000)

حالا کد را به این صورت تغییر بدهید:

Handler().postDelayed({
            val user = User("Moein")
            binding.user = user
            binding.executePendingBindings()
        },3000)

در اینجا، یک کلاس User ساخته شد و به مقدار user در binding نسبت داده شد اما برای ثبت تغییرات اعمال شده در binding، با دستور زیر تغییرات را اعمال خواهیم کرد:

binding.executePendingBindings()

به کلاس MainActivity دقت کنید:

import android.databinding.DataBindingUtil
import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import android.os.Handler
import moeindeveloper.kotlinmvvm.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this,R.layout.activity_main)
        Handler().postDelayed({
            val user = User("Moein")
            binding.user = user
            binding.executePendingBindings()
        },3000)
    }
}

کد کمتر، و خوانا تر!

Last updated