How to keep only first added Fragment in back stack (fragment overlapping)?

前端 未结 5 1976
盖世英雄少女心
盖世英雄少女心 2020-12-03 18:06

Scenario what i\'m trying to achieve:

  1. Loading activity with two frame containers (for list of items and for details).
  2. At the app launch time add listF
5条回答
  •  自闭症患者
    2020-12-03 18:59

    The problem is that the transaction that you're backing from have two steps:

    • remove infoFrag
    • add detailsFrag (that is the first1 detail container that was added)

    (we know that because the documentation This is essentially the same as calling remove(Fragment) for all currently added fragments that were added with the same containerViewId and then add(int, Fragment, String) with the same arguments given here. )

    So whenever the system is reverting that one transaction is reverting exactly those 2 steps, and it say nothing about the last detailFrag that was added to it, so it doesn't do anything with it.

    There're two possible work arounds I can think on your case:

    1. Keep a reference on your activity to the last detailsFrag used and use the BackStackChange listener to whenever the value change from 1 to 0 (you'll have to keep track of previous values) you also remove that one remaining fragment

    2. on every click listener you'll have to popBackStackImmediatly() (to remove the previous transaction) and addToBackStack() on all transactions. On this workaround you can also use some setCustomAnimation magic to make sure it all looks nice on the screen (e.g. use a alpha animation from 0 to 0 duration 1 to avoid previous fragment appearing and disappearing again.

    ps. I agree that the fragment manager/transaction should be a bit more clever to the way it handles back stack on .replace() actions, but that's the way it does it.

    edit:

    what is happening is like this (I'm adding numbers to the details to make it more clear). Remember that .replace() = .remove().add()

    Transaction.remove(info).add(detail1).addToBackStack(null) // 1st time
    Transaction.remove(detail1).add(detail2) // 2nd time
    Transaction.remove(detail2).add(detail3) // 3rd time
    Transaction.remove(detail3).add(detail4) // 4th time
    

    so now we have detail4 on the layout:

    < Press back button >
         System pops the back stack and find the following back entry to be reversed
             remove(info).add(detail1);
         so the system makes that transaction backward.
         tries to remove detail1 (is not there, so it ignores)
         re-add(info) // OVERLAP !!!
    

    so the problem is that the system doesn't realise that there's a detail4 and that the transaction was .replace() that it was supposed to replace whatever is in there.

提交回复
热议问题