Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
279 views
in Technique[技术] by (71.8m points)

android - Two fragments are displaying at the same time after pressing back button on added last fragment which wasn't added to back stack

For example I have one activity and three fragments (1, 2, 3).

I show first fragment, then second fragment (adding it to back stack) and third fragment (no adding it to back stack because when pressing the back button I want to go to the first fragment from the current third one instead of going to the second fragment)

This logic works but when it go back to first fragment, third fragment is still visible (two fragments are displayed at the same time)

Here's the full flow example and the full code when Fragment 1 and Fragment 3 are displayed at the same time

enter image description here

enter image description here

enter image description here

enter image description here

Activity:

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

        showFragment(
            addToBackStack = false,
            backStackName = null,
            fragmentNumber = 1,
            tag = "FRAGMENT_FIRST"
        )

        // simulate going to other fragments sequentially
        val mainHandler = Handler(Looper.getMainLooper())

        mainHandler.postDelayed(
            {
                showFragment(
                    addToBackStack = true,
                    backStackName = null,
                    fragmentNumber = 2,
                    tag = "FRAGMENT_SECOND"
                )
            },
            1000L
        )

        mainHandler.postDelayed(
            {
                showFragment(
                    addToBackStack = false, // when back pressing from third fragment I want it to get back to first fragment, not second
                    backStackName = null,
                    fragmentNumber = 3,
                    tag = "FRAGMENT_THIRD"
                )
            },
            2000L
        )
    }

    private fun showFragment(
        addToBackStack: Boolean,
        backStackName: String?,
        fragmentNumber: Int,
        tag: String
    ) {
        val transaction = supportFragmentManager.beginTransaction()

        var fragment =
            supportFragmentManager.findFragmentByTag(tag) as FragmentGeneral?
        if (fragment == null) {
            fragment = FragmentGeneral.newInstance(number = fragmentNumber)
            transaction.replace(R.id.fragment_container, fragment, tag)
            if (addToBackStack) {
                transaction.addToBackStack(backStackName)
            }
        } else {
            transaction.show(fragment)
        }

        transaction.commit()
    }
}

class FragmentGeneral : Fragment() {

    private lateinit var binding: FragmentGeneralBinding

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ) = FragmentGeneralBinding.inflate(layoutInflater, container, false).apply {
        binding = this
    }.root

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        arguments?.getInt(ARG_FRAGMENT_NUMBER)?.let { number ->
            binding.fragmentNumber = number

            // set different position of the text so we could clearly see overlapping of two fragments
            binding.textView.gravity = when (number) {
                1 -> Gravity.TOP
                2 -> Gravity.CENTER_VERTICAL
                3 -> Gravity.BOTTOM
                else -> return
            }

            // simulate pressing back button pressing
            if (number == 3) {
                // should go to first fragment because it wasn't added to backstack
                Handler(Looper.getMainLooper()).postDelayed(
                    { activity?.onBackPressed() },
                    1000L
                )
            }
        }
    }

    companion object {
        private const val ARG_FRAGMENT_NUMBER = "ARG_FRAGMENT_NUMBER"

        fun newInstance(number: Int) =
            FragmentGeneral().apply {
                arguments = bundleOf(ARG_FRAGMENT_NUMBER to number)
            }
    }
}

activity_main.xml:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <FrameLayout
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>
</layout>

fragment_general.xml:

<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".FragmentGeneral">

    <data>
        <variable
            name="fragmentNumber"
            type="int" />
    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/text_view"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:text='@{"Fragment #" + fragmentNumber}'
            android:textColor="@android:color/black"
            android:textSize="64sp"
            tools:text="Fragment #?" />
    </FrameLayout>
</layout>

So why third fragment is still visible? How to fix this issue and what is correct way to handle such transactions?

Developers usually would not notice such issues if their fragments are not transparent, but in my example it's transparent, so the white background - it's activity background


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神答复

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...