데이터 바인딩은 정보(데이터)를 일부 시각적 사용자 입력 요소에 붙일 때 사용되는 기술입니다. 이 프로세스에서 입력이 업데이트될 때마다 그 뒤에 있는 데이터도 업데이트됩니다.
이것은 새로운 개념과는 거리가 멀고 이를 디자인에 통합한 프레임워크(AngularJS/React/Vue 등)가 너무 많습니다.
이 기사에서 우리의 관심은 프론트 엔드 프레임워크가 아니라 모바일 개발에 있습니다. Google은 Android Jetpack의 일부인 Android에 데이터 바인딩 라이브러리를 도입했습니다.
Jetpack 라이브러리 제품군에 익숙하지 않은 경우 Google에서 지원 라이브러리에 대한 개발을 중단할 것이라고 발표했기 때문일 수 있습니다. 대신 지원하는 AndroidX 라이브러리(지원 라이브러리의 최신 버전)로 이동합니다.
어댑터를 사용하여 데이터 바인딩을 사용하는 방법을 설명하는 많은 기사가 있다는 것을 알고 있지만 이 기사에서는 이에 초점을 맞추지 않을 것입니다. 대신 작성해야 하는 코드의 양을 최소화하여 시간을 절약할 수 있는 데이터 바인딩에 대한 최소한의 접근 방식을 보여드리겠습니다.
데이터 바인딩을 사용하는 이유
아직 판매되지 않았다면 잠시 시간을 내어 예제를 통해 데이터 바인딩 사용의 이점을 설명하겠습니다. 세 개의 사용자 정의 버튼이 있는 메뉴가 있다고 가정해 보겠습니다. 각 버튼은 그 자체의 레이아웃입니다.
이 모든 것을 생성하는 한 가지 방법은 4가지 다른 XML 레이아웃을 사용하는 것입니다. 하나는 기본 레이아웃용이고 다른 하나는 세 개의 버튼용입니다.
각 버튼은 사용자를 애플리케이션의 다른 부분으로 안내하므로 다른 텍스트와 다른 이미지가 필요하므로 이 작업을 수행해야 합니다.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
<ImageView
android:id="@+id/imageView"
android:layout_height="100dp"
android:layout_width="100dp"
android:src="@drawable/image_name"
android:adjustViewBounds="true"
android:scaleType="centerInside"
/>
<TextView
android:id="@+id/textView"
android:gravity="center_horizontal"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Image Text"
android:textSize="16sp" />
</LinearLayout>
물론 세 가지 레이아웃만 처리하므로 코드 중복이 많지 않습니다. 하지만 생각해보면 그 모든 코드를 처리하는 것은 시간 낭비입니다. 제품과 해당 이미지를 보여줄 수 있는 레이아웃이 더 복잡한 애플리케이션을 고려하면 지루한 코드 복제가 많이 발생할 수 있습니다.
데이터 바인딩을 사용하면 모든 버튼에서 사용할 XML 레이아웃을 하나만 만들 수 있습니다.
어디서 시작해야 합니까?
프로젝트에서 데이터 바인딩을 활성화해야 합니다. 이를 위해 dataBinding
를 추가해야 합니다. 애플리케이션의 build.gradle
요소 파일:
android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.tomerpacific.example"
minSdkVersion 15
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
dataBinding { //<-------
enabled = true
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
프로젝트를 동기화한 후 레이아웃을 바인딩하는 데 사용할 데이터 클래스를 생성합니다.
package com.tomerpacific.example
import android.graphics.drawable.Drawable
data class ButtonData(val buttonText: String, val buttonImageSrc : Drawable)
ButtonData
에 두 개의 필드가 있다는 사실에 주목하세요. 클래스:
buttonText
— 이것은 이미지 아래에 표시될 텍스트입니다.buttonImageSrc
— 이것은 버튼의 이미지를 담당합니다.
더 많은 데이터를 원하면 데이터 클래스에 필드를 더 추가하면 됩니다.
실제 바인딩
다음으로, 사용할 수 있도록 레이아웃에서 변수 속성을 선언해야 합니다. 이 변수는 우리가 만든 데이터 클래스에 바인딩됩니다. 이렇게 하려면 두 가지 작업을 수행해야 합니다.
- 루트 레이아웃 요소를 레이아웃 태그로 묶습니다.
- 변수 선언을 포함할 데이터 태그를 추가합니다(
buttonData
).
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="https://schemas.android.com/apk/res/android"> // <---- 1
<data>
<variable name="buttonData" type="com.tomerpacific.example.ButtonData"/> // <---- 2
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="https://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Example"
android:textSize="30dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@drawable/android">
</ImageButton>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Image Text"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintVertical_bias="0.504">
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@drawable/android_p_logo">
</ImageButton>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Image Text"
android:textSize="16sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/linearLayout2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.200"
app:layout_constraintStart_toEndOf="@+id/linearLayout3"
app:layout_constraintTop_toBottomOf="@+id/textView2"
app:layout_constraintVertical_bias="0.504">
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@drawable/android_studio_icon">
</ImageButton>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Image Text"
android:textSize="16sp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
루트 레이아웃 태그로 이동한 이전 기본 레이아웃에서 스키마를 제거할 수 있습니다. 또한 추가한 변수는 데이터 클래스에 직접 연결됩니다.
MainActivity
에서 파일에 바인딩을 처리하는 코드를 추가해야 합니다.
package com.tomerpacific.example
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.tomerpacific.example.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
binding.buttonData = ButtonData("First", resources.getDrawable(R.drawable.android))
}
}
레이아웃 내부에 변수를 생성할 때마다 해당 레이아웃에 대한 바인딩 클래스가 자동으로 생성됩니다. 우리의 경우 레이아웃은 activity_main
입니다. , 따라서 바인딩 클래스의 이름은 ActivityMainBinding
이 됩니다. .
규칙은 항상 바인딩이 있는 레이아웃의 이름입니다. 끝에 추가되었습니다.
buttonData
을 선언했기 때문에 레이아웃의 변수로 바인딩 개체에 추가되고 ButtonData
의 새 인스턴스를 할당할 수 있습니다. 수업.
모든 작업을 수행한 후 레이아웃에서 방금 바인딩한 데이터를 마침내 사용할 수 있습니다.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@{buttonData.buttonImageSrc}"> // <----
</ImageButton>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{buttonData.buttonText}" // <----
android:textSize="16sp" />
결과는 다음과 같습니다.
잠시만...
세 개의 버튼이 있고 데이터 클래스는 하나의 버튼에만 사용할 수 있습니다. 그렇다면 이 문제를 어떻게 해결할 수 있을까요?
package com.tomerpacific.example
data class ButtonsData(val buttonsData : List<ButtonData>) {
fun get(index: Int) : ButtonData {
return buttonsData.get(index)
}
}
get
을 재정의해야 했습니다. 레이아웃에서 사용할 때 인식해야 하는 메서드입니다.
그런 다음 activity_main.xml
에서 참조를 변경해야 합니다. :
<data>
<variable name="buttonsData" type="com.tomerpacific.example.ButtonsData"/>
</data>
그리고 새 데이터 클래스에 대한 새 바인딩을 만들어야 합니다.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val binding: ActivityMainBinding = DataBindingUtil.setContentView(
this, R.layout.activity_main)
val firstButton : ButtonData = ButtonData("First", resources.getDrawable(R.drawable.android))
val secondButton : ButtonData = ButtonData("Second", resources.getDrawable(R.drawable.android_p_logo))
val thirdButton : ButtonData = ButtonData("Third", resources.getDrawable(R.drawable.android_studio_icon))
val buttonsData : ButtonsData = ButtonsData(listOf(firstButton, secondButton, thirdButton))
binding.buttonsData = buttonsData
}
ButtonData
의 세 가지 인스턴스를 만듭니다. 수업. 그런 다음 ButtonsData
를 인스턴스화합니다. 개체를 만들고 바인딩 개체에 연결합니다.
마지막으로 이제 레이아웃에서 데이터 클래스를 올바르게 사용할 수 있습니다.
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/linearLayout3"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView2">
<ImageButton
android:layout_width="100dp"
android:layout_height="100dp"
android:adjustViewBounds="true"
android:scaleType="centerInside"
android:src="@{buttonsData.get(0).buttonImageSrc}"> // <-------
</ImageButton>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="@{buttonsData.get(0).buttonText}" // <--------
android:textSize="16sp" />
</LinearLayout>
이 기사는 다음 애플리케이션을 개발한 경험으로 작성되었습니다.
(당신은 결코 알지 못합니다, 그것은 유용할 수 있습니다)
세탁 기호 - Google Play의 앱 이 세탁 기호의 의미를 파악하는 데 어려움을 겪었습니까? 글쎄, 당신은 운이 좋다! 이 앱에는 사용하기 쉬운 인터페이스와 사진과 함께 이상하게 보이는 모든 기호에 대한 설명이 포함되어 있습니다. Google Play의 tomerpacificApps여기에서 전체 소스 코드를 볼 수 있습니다.
TomerPacific/LaundrySymbols설명과 함께 다양한 세탁 기호를 표시하는 Kotlin으로 작성된 애플리케이션:cyclone:- TomerPacific/LaundrySymbols TomerPacificGitHub