All Editexts be replace by same value after pop a Fragment

末鹿安然 提交于 2019-12-02 13:56:14

You're not adding to the back stack, you're replacing, try this to open the second fragment, this will keep the state of FirstFragment intact and in stack

btn_next.setOnClickListener {
            val transaction = requireActivity().supportFragmentManager!!.beginTransaction()
                .add(R.id.contentFrame, SecondFragment(), "")
            commitTransaction(transaction, true, -1)
        }

Also both of your EditTexts have the same ids android:id="@+id/edt" thus the synthesizer function which runs findViewById will point to the same object of EditText

Finally I find out the root cause and the solution, Thanks @abhradeep ghosh, @Eselfar, @MadScientist and another one else who response this post.

Cause: view IDs should be unique! Otherwise your state will be overwritten by another view with the same ID. In my case I have 2 views with id @id/edt, so my states container holds only 1 instance of it - whichever came last during state store process.

Here is my solution, (from this post),

First, create new class for save sate of view

class SavedState(superState: Parcelable) : View.BaseSavedState(superState) {
    var childrenStates: SparseArray<Any>? = null

    override fun writeToParcel(out: Parcel, flags: Int) {
        super.writeToParcel(out, flags)
        childrenStates?.let {
            out.writeSparseArray(it)
        }
    }
}

And in my CustomView

@Suppress("UNCHECKED_CAST")
    public override fun onSaveInstanceState(): Parcelable? {
        val superState = super.onSaveInstanceState()
        val ss = SavedState(superState)
        ss.childrenStates = SparseArray()
        for (i in 0 until childCount) {
            getChildAt(i).saveHierarchyState(ss.childrenStates as SparseArray<Parcelable>)
        }
        return ss
    }

    @Suppress("UNCHECKED_CAST")
    public override fun onRestoreInstanceState(state: Parcelable) {
        val ss = state as SavedState
        super.onRestoreInstanceState(ss.superState)
        for (i in 0 until childCount) {
            getChildAt(i).restoreHierarchyState(ss.childrenStates as SparseArray<Parcelable>)
        }
    }

    override fun dispatchSaveInstanceState(container: SparseArray<Parcelable>) {
        dispatchFreezeSelfOnly(container)
    }

    override fun dispatchRestoreInstanceState(container: SparseArray<Parcelable>) {
        dispatchThawSelfOnly(container)
    }

I would try adding a different ID to each of your custom views in the layout. Like :

com.sogia.replacefragmentdemo.CustomView
    android:id="@+id/custom1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
/>

com.sogia.replacefragmentdemo.CustomView
    android:id="@+id/custom2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

Having same id can be a problem as managing state could get messy. Check this one for an solution: Restore fragment with two views having the same id

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!