使用Fragments为BottomNavigationView Android中的每个选项卡分离后退堆栈 [英] Separate Back Stack for each tab in BottomNavigationView Android using Fragments
问题描述
我正在实现BottomNavigationView
以便在Android应用中进行导航.我正在使用片段设置每个标签的内容.
I'm implementing BottomNavigationView
for navigation in an Android app. I am using Fragments to set the content for each tab.
我知道如何为每个选项卡设置一个片段,然后在单击选项卡时切换片段.但是,如何为每个选项卡设置单独的后置堆栈呢? 这是设置一个片段的代码:
I know how to set up one fragment for each tab and then switch fragments when a tab is clicked. But how can I have a separate back stack for each tab? Here is the code to set up one fragment:
Fragment selectedFragment = ItemsFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.content, selectedFragment);
transaction.commit();
例如,Fragment
A和B将在选项卡1下,而Fragment
C和D将在选项卡2下.启动应用程序时,将显示片段A,并选择了选项卡1.然后Fragment
B.此时,应该可以使用后退"按钮显示片段A.
For an example, Fragment
A and B would be under Tab 1 and Fragment
C and D under Tab 2. When the app is started Fragment A is shown and Tab 1 is selected. Then Fragment
A might be replaced with Fragment B. When Tab 2 is selected Fragment C should be displayed. If Tab 1 is then selected Fragment
B should once again be displayed. At this point, it should be possible to use the back button to show Fragment A.
这是在同一标签中设置下一个fragment
的代码:
And Here is the code to set up next fragment
in the same tab:
Fragment selectedFragment = ItemsFragment.newInstance();
FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.replace(R.id.content, selectedFragment);
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.addToBackStack(null);
ft.commit();
推荐答案
最后,我找到了解决方案,它的灵感来自于StackOverflow的先前答案:
Finally, I found the solution, it was inspired by a previous answer on StackOverflow: Separate Back Stack for each tab in Android using Fragments
I only have replaced TabHost with BottomNavigationView and here is the code:
Main Activity
public class MainActivity extends AppCompatActivity {
private HashMap<String, Stack<Fragment>> mStacks;
public static final String TAB_HOME = "tab_home";
public static final String TAB_DASHBOARD = "tab_dashboard";
public static final String TAB_NOTIFICATIONS = "tab_notifications";
private String mCurrentTab;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put(TAB_HOME, new Stack<Fragment>());
mStacks.put(TAB_DASHBOARD, new Stack<Fragment>());
mStacks.put(TAB_NOTIFICATIONS, new Stack<Fragment>());
navigation.setSelectedItemId(R.id.navigation_home);
}
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
selectedTab(TAB_HOME);
return true;
case R.id.navigation_dashboard:
selectedTab(TAB_DASHBOARD);
return true;
case R.id.navigation_notifications:
selectedTab(TAB_NOTIFICATIONS);
return true;
}
return false;
}
};
private void gotoFragment(Fragment selectedFragment)
{
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content, selectedFragment);
fragmentTransaction.commit();
}
private void selectedTab(String tabId)
{
mCurrentTab = tabId;
if(mStacks.get(tabId).size() == 0){
/*
* First time this tab is selected. So add first fragment of that tab.
* Dont need animation, so that argument is false.
* We are adding a new fragment which is not present in stack. So add to stack is true.
*/
if(tabId.equals(TAB_HOME)){
pushFragments(tabId, new HomeFragment(),true);
}else if(tabId.equals(TAB_DASHBOARD)){
pushFragments(tabId, new DashboardFragment(),true);
}else if(tabId.equals(TAB_NOTIFICATIONS)){
pushFragments(tabId, new NotificationsFragment(),true);
}
}else {
/*
* We are switching tabs, and target tab is already has atleast one fragment.
* No need of animation, no need of stack pushing. Just show the target fragment
*/
pushFragments(tabId, mStacks.get(tabId).lastElement(),false);
}
}
public void pushFragments(String tag, Fragment fragment, boolean shouldAdd){
if(shouldAdd)
mStacks.get(tag).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
public void popFragments(){
/*
* Select the second last fragment in current tab's stack..
* which will be shown after the fragment transaction given below
*/
Fragment fragment = mStacks.get(mCurrentTab).elementAt(mStacks.get(mCurrentTab).size() - 2);
/*pop current fragment from stack.. */
mStacks.get(mCurrentTab).pop();
/* We have the target fragment in hand.. Just show it.. Show a standard navigation animation*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.replace(R.id.content, fragment);
ft.commit();
}
@Override
public void onBackPressed() {
if(mStacks.get(mCurrentTab).size() == 1){
// We are already showing first fragment of current tab, so when back pressed, we will finish this activity..
finish();
return;
}
/* Goto previous fragment in navigation stack of this tab */
popFragments();
}
}
家庭片段示例
public class HomeFragment extends Fragment {
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_home, container, false);
Button gotoNextFragment = (Button) view.findViewById(R.id.gotoHome2);
gotoNextFragment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
((MainActivity)getActivity()).pushFragments(MainActivity.TAB_HOME, new Home2Fragment(),true);
}
});
return view;
}
}
这篇关于使用Fragments为BottomNavigationView Android中的每个选项卡分离后退堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!