Goal
Use View Binding and Data Binding by Android Studio 3.6 above
Use Shared ViewModel between Activity and child Fragment
Preparation (build.gradle)
apply plugin: 'com.android.application' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' apply plugin: 'kotlin-kapt' android { compileSdkVersion 29 buildToolsVersion "29.0.1" defaultConfig { applicationId "com.daiji110.viewbinding" minSdkVersion 21 targetSdkVersion 29 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } dataBinding { enabled = true } viewBinding { enabled = true } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'androidx.appcompat:appcompat:1.1.0' implementation 'androidx.core:core-ktx:1.2.0' implementation "androidx.fragment:fragment-ktx:1.2.4" implementation 'androidx.constraintlayout:constraintlayout:1.1.3' testImplementation 'junit:junit:4.12' androidTestImplementation 'androidx.test.ext:junit:1.1.1' androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' }
comipleOptions, and kotlinOptions are for Java 8 definition
androidx.fragment:fragment-ktx is to write ViewModel management easily
dataBinding and viewBinding is On
Sample
Prepare button on Activity and everytime, press button switch Fragment Vibisility
activity_main.xml
This is Activity layout codes
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools"> <data> <variable name="viewModel" type="com.daiji110.viewbinding.viewmodel.GlobalViewModel" /> </data> <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!" /> <Button android:id="@+id/button" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Click me"/> <fragment android:id="@+id/childman" android:name="com.daiji110.viewbinding.fragment.ChildFragment" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> </layout>
Add ViewModel as data and Child fragment is under this layout
fragment_childfragment.xml
This is Fragment Layout xml
<?xml version="1.0" encoding="utf-8"?> <layout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <data> <import type="android.view.View"/> <variable name="parentViewModel" type="com.daiji110.viewbinding.viewmodel.GlobalViewModel" /> </data> <androidx.constraintlayout.widget.ConstraintLayout android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/parentView" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:visibility="@{parentViewModel.child ? View.VISIBLE : View.GONE}" android:text="I am child"> </TextView> </LinearLayout> </androidx.constraintlayout.widget.ConstraintLayout> </layout>
GlobalViewModel.kt
Shared ViewModel codes
class GlobalViewModel : ViewModel() { var child : ObservableBoolean = ObservableBoolean(false) fun switchVisible() { child.set(!child.get()) } }
MainActivity.kt
class MainActivity : AppCompatActivity() { private val viewModel : GlobalViewModel by viewModels<GlobalViewModel>() var binding : ActivityMainBinding? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding?.root) binding?.button?.setOnClickListener { viewModel.switchVisible() } binding?.lifecycleOwner = this } }
Create ViewModel as LocalViewModel
Prepare binding
Add event listener
ChildFragment.kt
class ChildFragment : Fragment() { private var binding : FragmentChildfragmentBinding? = null val parentViewModel by activityViewModels<GlobalViewModel>() override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { binding = FragmentChildfragmentBinding.inflate(inflater, container, false) binding?.parentViewModel = parentViewModel return binding?.root } override fun onDestroyView() { super.onDestroyView() binding = null } }
コメント