简体   繁体   中英

How to reflect a common value from a bottom sheet to a fragment?

I'm currently developing an application using android-studio with Kotlin.

This app has

  • a common value I can use through fragments

  • a fragment class for main content

  • a fragment class for bottom sheet

I want to show a new value on the main fragment view right after I change the common value at edittext in bottom sheet.

But in the case of my codes, the common value doesn't change when I' back to the main fragment view from the bottom sheet...

How can I solve this situation?


Here are the codes:

build.gradle

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.sample.bottomsheetvalue"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    implementation 'androidx.legacy:legacy-support-v4:1.0.0-beta01'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0-alpha4'

    implementation "androidx.fragment:fragment-ktx:1.3.0-alpha04"
    implementation "com.google.android.material:material:1.1.0-alpha06"

}

AppState.kt

package com.sample.bottomsheetvalue

import androidx.lifecycle.ViewModel

class AppState: ViewModel()  {

    var value:String = "initialValue"
}

MainActivity.kt

package com.sample.bottomsheetvalue

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

    }
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
    <fragment
            android:id="@+id/main_fragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:name="com.tomato_love.bottomsheetvalue.MainFragment"
    />

</androidx.constraintlayout.widget.ConstraintLayout>

MainFragment.kt

package com.sample.bottomsheetvalue

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider

class MainFragment : Fragment() {

    lateinit var appState: AppState

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        activity?.run {
            appState = ViewModelProvider(this).get(AppState::class.java)
        }
        val view = inflater.inflate(R.layout.fragment_main, container, false)

        val button = view.findViewById<Button>(R.id.button)
        val textView = view.findViewById<TextView>(R.id.textView)

        textView.text = appState.value

        button.setOnClickListener {

            val fm = activity!!.supportFragmentManager
            val bottomSheet =BottomSheet()
            bottomSheet.show(fm, "navigation_bottom_sheet")
        }
        return view
    }
}

fragment_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        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"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainFragment"
        android:id="@+id/constraintLayoutFragment">

    <Button
            android:id="@+id/button"
            android:text="show bottom sheet"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="32dp"
            app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
    />
    <TextView
            android:id="@+id/textView"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="32sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            android:layout_marginTop="32dp"
            app:layout_constraintTop_toBottomOf="@+id/button"/>
</androidx.constraintlayout.widget.ConstraintLayout>

BottomSheet.kt

package com.sample.bottomsheetvalue

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.EditorInfo
import android.widget.EditText
import androidx.lifecycle.ViewModelProvider
import com.google.android.material.bottomsheet.BottomSheetDialogFragment

class BottomSheet : BottomSheetDialogFragment() {

    lateinit var appState: AppState

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        activity?.run {
            appState = ViewModelProvider(this).get(AppState::class.java)
        }

        val view = inflater.inflate(R.layout.fragment_bottom_sheet, container, false)

        val editText = view.findViewById<EditText>(R.id.editText)

        editText.setOnEditorActionListener { v, actionId, event ->
            when (actionId) {
                EditorInfo.IME_ACTION_DONE -> {
                    appState.value = editText.text.toString()
                    println(appState.value)
                    true
                }
                else -> false
            }
        }
        return view
    }
}

fragment_bottom_sheet.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             xmlns:tools="http://schemas.android.com/tools"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
             tools:context=".BottomSheet">
    <EditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="500dp"
            android:inputType="textPersonName"
            android:ems="10"
            android:imeOptions="actionDone"
    />
</FrameLayout>

Android Studio : 3.3.2

Add a Livedata to your view model class:

val data: MutableLiveData<String> = MutableLiveData("Initial Value")

And observe that in your fragment:

appState.data.observe(viewLifecycleOwner, Observer {
            // Update your ui here
})

And also in your bottom sheet update the data:

data.postValue("newValue")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM