问题描述
我有X,A,B片段,并且我正在使用导航体系结构组件在它们之间进行导航.
I have Fragments X, A, B, and i'm using Navigation architecture component to navigate between them.
特定于片段A,B,但是片段X可以是any(C,D,...);
Fragments A, B specific, but Fragment X can be any(C,D,...);
底部导航中的片段A和B及其导航图标"始终显示在屏幕上,这意味着用户可以随时从任何片段(包括A和B)转到A或B:
Fragments A and B from Bottom Navigation and their "navigations icons" always on the screen, it means user can go to A or B anytime from any Fragment(include A and B):
X -> A -> B
X -> B -> A
A -> B -> X
A -> B -> A
//another ways
我在这种情况下的问题:
My problem about this case:
X -> A -> B -> A -> B -> ?
如果用户从X
开始,到达?
并通过返回"按钮开始返回,则他会多次抛出A
,B
:
If user started from X
, reached ?
and begin to go back by "back" button, he goes throw A
,B
several times:
用户已按下:
? -> B -> A -> B -> A -> X
但是我想从堆栈中排除"碎片,如果它们已经存在的话:
But I want "to exclude" fragments from backstack if they already on it:
? -> A -> B -> X
如果用户导航:
X -> A -> B -> A
我想看:
A -> B -> X
不是:
A -> B -> A -> X
我正在尝试使用Pop To做它,但是它只能使我回到一个具体的片段上.我需要返回开始的X片段,而不是硬编码.包容性和单身"顶部不是这个问题.
I'm trying to do it with Pop To, but it can return me on one one concrete Fragment only. I need to return on my started X Fragment, not hardcoded. Inclusive and Single top is not about it.
我不确定我可以使用基本的导航组件来做到这一点,所以我需要您的建议.如果我做不到,应该使用哪种方式?有什么好的做法吗?
I'm not sure i can do it with basic Navigation component, so i need your advice. If i can't do it, what way should i use? Is there any good practices about it?
UPD:
我正在使用全局点在片段之间导航.这就是我的导航样子:
I'm using global points to navigate between Fragments. It's how my navigation looks like:
右边的底部链是X,我可以使用底部导航从其中任何一个导航到不被搅动的片段.它是单项活动应用,用于我仅使用的导航方式:
The right|bottom chain is X, i can navigate from any of it to to not chanied fragments using bottom navigation. It's Single Activity app, to navigate i'm using just:
//Using global points
findNavController(R.id.host).navigate(R.id.toLibrary)
推荐答案
以下解决方案使用片段可见性技术来管理片段事务onBackPressed()
.
Following Solution uses Fragment Visibility Technique in order to manage Fragments Transaction onBackPressed()
.
第一步,当每个片段称为&为了能够识别哪些片段已经被添加到Backstack中而被调用.通过下面的代码,我们为将被称为&的片段分配标签.交易.
In the first step, We assign a tag to each fragment when it's called & invoked in order to be able to recognize which fragments already have been added to Backstack.by code below, we assign a tag to a fragment that is going to be called & transacted.
fragmentManager.beginTransaction()
.replace(R.id.FragmentHolder, Fragment_A OR Fragment_B OR Fragment_ANY, "A or B or ANY")
.addToBackStack(tag).commit();
请记住,您必须为要调用的任何片段分配一个标签.
在第二个中,我们将处理public void onBackPressed()
.
您必须忽略super.onBackPressed();
,因为我们不想默认 onBackPressed函数影响Backstack(按原样),而我们想处理Backstack自己.
You MUST ignore super.onBackPressed();
as becuase, we don't want to defualt onBackPressed function to impact Backstack(as it is) and we are want to handle Backstack ourselves.
你在这里
@Override
public void onBackPressed() {
if(isVisible("A")) { //Go some where else you wanna go }
else if(isVisible("B")){ //Go some where else you wanna go }
else if(isVisible("X or any"){ //Go some where else you wanna go }
else { //Go default page }
}
public boolean isVisible(String tag){
try {
Fragment fragment = fragmentManager.findFragmentByTag(tag);
if (fragment != null && fragment.isVisible())
return true;
else
return false;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
按下后退按钮时,我们将检查哪个片段已经可见,并将用户重定向到相应的片段.
When back button is pressed, We check which fragment is already visible and do redirect user to corresponding Fragment.
例如:A - > B
或A -> X
或X -> B
我正在将此技术用于大型应用程序,并且一切都很好. AF受助人
I am using this Technique for a big application and all good. Mr.AF grantee
这篇关于使用导航组件从Backstack中解开片段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!