Android 中选项卡式视图寻呼机的单独后退导航
Separate Back Navigation for a Tabbed View Pager in Android
我想要的
在选项卡滑动菜单上下文中,我想将一个片段替换为选项卡内的另一个片段,并维护选项卡菜单以及当前选项卡。当滑动到另一个选项卡并 returning 到原始时,我希望显示最后一个片段。
例如,我有 tab_a
和 Fragment_1
,tab_b
和 Fragment_4
以及 tab_c
和 Fragment_7
。现在我想要 Fragment_1
中的一个按钮来打开我 Fragment_2
,但我希望能够滑动到 tab_b
和 tab_c
的片段。而当我return到tab_a时,必须显示Fragment_2
。
MainActivity
|
|
ContainerFragment
|
|
|_ _ _ Tab A
| |_ _ _ Fragment 1
| |
| |_ _ _ Fragment 2
| |
| |_ _ _ Fragment 3
| |
| |_ _ _ ...
|
|_ _ _ Tab B
| |_ _ _ Fragment 4
| |
| |_ _ _ Fragment 5
| |
| |_ _ _ Fragment 6
| |
| |_ _ _ ...
|
|_ _ _ Tab C
| |_ _ _ Fragment 7
| |
| |_ _ _ Fragment 8
| |
| |_ _ _ Fragment 8
| |
| |_ _ _ ...
我目前的主要activity.
Xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
代码
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private final static int[] tabIcons = {
R.drawable.ic_tab_a,
R.drawable.ic_tab_b,
R.drawable.ic_tab_c
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new Fragment1());
adapter.addFrag(new Fragment4());
adapter.addFrag(new Fragment7());
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
void addFrag(Fragment fragment) {
mFragmentList.add(fragment);
}
}
}
碎片
Xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/holo_blue_light"
android:id="@+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="myContext">
<Button
android:text="Go to next Fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/button_nextFrag" />
<FrameLayout
android:id="@+id/tab1_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
代码
public class Fragment1 extends Fragment {
private void goNextFragment() {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.tab1_container, new Fragment2());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment.
View root = inflater.inflate(R.layout.fragment_1, container, false);
// Go to next Fragment Button.
final Button nextFrag = (Button) root.findViewById(R.id.button_nextFrag);
nextFrag .setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goNextFragment();
}
});
return root;
}
}
编辑:
我有一些解决方案,但 none 是完美的。如果我在 MainActivity 中放置一个 Framelayaout,Fragment_1
被正确替换为 Fragment_2
,但它也在 tab_b
和 tab_c
中。如果FrameLayout在Fragment_1
,我可以正确滑动其他选项卡,但替换不成功,因为Fragment_2
打开了,但Fragment_1
也在。
根据你的解释,我执行以下操作:
1- 在您的 Activity 中创建您的 Tabs
和 ViewPager
:
mPager = (ViewPager) findViewById(R.id.vp_pager);
mPager.setOffscreenPageLimit(3);
PagerAdapter mAdapter = new PagerAdapter(getSupportFragmentManager(), getContext());
mPager.setAdapter(mAdapter);
//tab.setupWithViewPager(mPager);
2- 在每个选项卡中创建 ViewPager
(我假设你想要 tabs
中的选项卡,如果你不需要选项卡只是删除它们),每个 fragment
的实现将是像:
ViewPager mPager = (ViewPager) rootView.findViewById(R.id.vp_pager);
mPager.setOffscreenPageLimit(3);
CategoryAdapter mAdapter = new CategoryAdapter(getChildFragmentManager());//make sure this ChildFragmentManager
mPager.setAdapter(mAdapter);
还在片段中创建一个按钮,当点击它时会转到另一个片段:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPager.setCurrentItem(1); // go to second fragment
}
});
最终结果将如下所示,如果您转到 Home 选项卡,然后返回到 Category 选项卡,您你的 Fragment
位置没有改变。
有两点你要记住:
- 设置
mPager.setOffscreenPageLimit(3);
如果你不想破坏你的片段
- 在内部片段中传递
getChildFragmentManager()
而不是 FragmentManager()
如果您不需要 Inner ViewPager
并且您只想加载一个 Fragment 实例,这里是另一种选择:
1- 执行前面方法的第一项。
2- 在您的片段中 xml 放置 FrameContainer 并在其中加载您的片段:
CategoryResultFragment f = CategoryResultFragment.newInstance();
getFragmentManager().beginTransaction()
.replace(R.id.frame_result_container, f)
.commit();
编辑: 这不是最佳方法,但我认为可以解决您的问题:
1- 在您的 MainActivity
中创建一个静态字段,如下所示:
static String[] type = new String[3];
2- 当您在片段中调用 onClick 时,更新 MainActivity
中的 String
值。
public static update currentType(int pos,String type);
第一个值是 ViewPager 位置,第二个值是你的内部 Fragment 类型(例如:fragment_d);
3- 在您的 ViewPager 中
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: // first tab
if(type[position] == "fragment_d")
return new Fragment_D();
else
return new Fragment_B();
}
}
您可以更改页面片段内的片段。例如TAB_A实现了拾取片段1或2的逻辑,并在里面显示拾取的片段。
层次结构如下:
ViewPager -> TAB_A -> 片段 1 或 2(显示在 TAB_A 内)。
您还应该使用 getChildFragmentManager() 来管理 TAB_A 中的片段。
您可以将 ViewPager
与 TabLayout
一起使用。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
然后创建一个扩展 FragmentStatePagerAdapter
的 class 以使用您的初始 Fragment
s:
初始化 ViewPager
public class CustomPagerAdapter extends FragmentStatePagerAdapter {
private final List<String> tabTitles = new ArrayList<String>() {{
add("Fragment 1");
add("Fragment 4");
add("Fragment 7");
}};
private List<Fragment> tabs = new ArrayList<>();
public CustomPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
initializeTabs();
}
private void initializeTabs() {
tabs.add(HostFragment.newInstance(new Fragment1()));
tabs.add(HostFragment.newInstance(new Fragment4()));
tabs.add(HostFragment.newInstance(new Fragment7()));
}
@Override
public Fragment getItem(int position) {
return tabs.get(position);
}
@Override
public int getCount() {
return tabs.size();
}
@Override
public CharSequence getPageTitle(int position) {
return tabTitles.get(position);
}
}
包含实际内容的片段应由 HostFragment
包裹,如果您想导航,它使用其子 FragmentManager
将当前片段替换为新片段,或者弹出片段堆栈中的最后一个片段。调用其 replaceFragment
进行导航:
public class HostFragment extends BackStackFragment {
private Fragment fragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.host_fragment, container, false);
if (fragment != null) {
replaceFragment(fragment, false);
}
return view;
}
public void replaceFragment(Fragment fragment, boolean addToBackstack) {
if (addToBackstack) {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).commit();
}
}
public static HostFragment newInstance(Fragment fragment) {
HostFragment hostFragment = new HostFragment();
hostFragment.fragment = fragment;
return hostFragment;
}
}
HostFragment 应该扩展抽象 class BackstackFragment
public abstract class BackStackFragment extends Fragment {
public static boolean handleBackPressed(FragmentManager fm)
{
if(fm.getFragments() != null){
for(Fragment frag : fm.getFragments()){
if(frag != null && frag.isVisible() && frag instanceof BackStackFragment){
if(((BackStackFragment)frag).onBackPressed()){
return true;
}
}
}
}
return false;
}
protected boolean onBackPressed()
{
FragmentManager fm = getChildFragmentManager();
if(handleBackPressed(fm)){
return true;
} else if(getUserVisibleHint() && fm.getBackStackEntryCount() > 0){
fm.popBackStack();
return true;
}
return false;
}
}
连接 MainActivity
中的所有内容:
public class MainActivity extends AppCompatActivity {
private CustomPagerAdapter customPagerAdapter;
private ViewPager viewPager;
private TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
customPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
// 2 is enough for us; increase if you have more tabs!
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(customPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onBackPressed()
{
if(!BackStackFragment.handleBackPressed(getSupportFragmentManager())){
super.onBackPressed();
}
}
public void openNextFragment() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
// your logic to change the fragments...
}
}
这个解决方案当然不完美,但可以完成工作。在我的 blog post 中阅读有关此问题的更多信息。
我想要的
在选项卡滑动菜单上下文中,我想将一个片段替换为选项卡内的另一个片段,并维护选项卡菜单以及当前选项卡。当滑动到另一个选项卡并 returning 到原始时,我希望显示最后一个片段。
例如,我有 tab_a
和 Fragment_1
,tab_b
和 Fragment_4
以及 tab_c
和 Fragment_7
。现在我想要 Fragment_1
中的一个按钮来打开我 Fragment_2
,但我希望能够滑动到 tab_b
和 tab_c
的片段。而当我return到tab_a时,必须显示Fragment_2
。
MainActivity
|
|
ContainerFragment
|
|
|_ _ _ Tab A
| |_ _ _ Fragment 1
| |
| |_ _ _ Fragment 2
| |
| |_ _ _ Fragment 3
| |
| |_ _ _ ...
|
|_ _ _ Tab B
| |_ _ _ Fragment 4
| |
| |_ _ _ Fragment 5
| |
| |_ _ _ Fragment 6
| |
| |_ _ _ ...
|
|_ _ _ Tab C
| |_ _ _ Fragment 7
| |
| |_ _ _ Fragment 8
| |
| |_ _ _ Fragment 8
| |
| |_ _ _ ...
我目前的主要activity.
Xml
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="fixed"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</android.support.design.widget.CoordinatorLayout>
代码
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private final static int[] tabIcons = {
R.drawable.ic_tab_a,
R.drawable.ic_tab_b,
R.drawable.ic_tab_c
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
setupTabIcons();
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
tabLayout.getTabAt(1).setIcon(tabIcons[1]);
tabLayout.getTabAt(2).setIcon(tabIcons[2]);
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
adapter.addFrag(new Fragment1());
adapter.addFrag(new Fragment4());
adapter.addFrag(new Fragment7());
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
void addFrag(Fragment fragment) {
mFragmentList.add(fragment);
}
}
}
碎片
Xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:background="@android:color/holo_blue_light"
android:id="@+id/fragment_1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="myContext">
<Button
android:text="Go to next Fragment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:id="@+id/button_nextFrag" />
<FrameLayout
android:id="@+id/tab1_container"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</RelativeLayout>
代码
public class Fragment1 extends Fragment {
private void goNextFragment() {
FragmentTransaction trans = getFragmentManager().beginTransaction();
trans.replace(R.id.tab1_container, new Fragment2());
trans.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
trans.addToBackStack(null);
trans.commit();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment.
View root = inflater.inflate(R.layout.fragment_1, container, false);
// Go to next Fragment Button.
final Button nextFrag = (Button) root.findViewById(R.id.button_nextFrag);
nextFrag .setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
goNextFragment();
}
});
return root;
}
}
编辑:
我有一些解决方案,但 none 是完美的。如果我在 MainActivity 中放置一个 Framelayaout,Fragment_1
被正确替换为 Fragment_2
,但它也在 tab_b
和 tab_c
中。如果FrameLayout在Fragment_1
,我可以正确滑动其他选项卡,但替换不成功,因为Fragment_2
打开了,但Fragment_1
也在。
根据你的解释,我执行以下操作:
1- 在您的 Activity 中创建您的 Tabs
和 ViewPager
:
mPager = (ViewPager) findViewById(R.id.vp_pager);
mPager.setOffscreenPageLimit(3);
PagerAdapter mAdapter = new PagerAdapter(getSupportFragmentManager(), getContext());
mPager.setAdapter(mAdapter);
//tab.setupWithViewPager(mPager);
2- 在每个选项卡中创建 ViewPager
(我假设你想要 tabs
中的选项卡,如果你不需要选项卡只是删除它们),每个 fragment
的实现将是像:
ViewPager mPager = (ViewPager) rootView.findViewById(R.id.vp_pager);
mPager.setOffscreenPageLimit(3);
CategoryAdapter mAdapter = new CategoryAdapter(getChildFragmentManager());//make sure this ChildFragmentManager
mPager.setAdapter(mAdapter);
还在片段中创建一个按钮,当点击它时会转到另一个片段:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mPager.setCurrentItem(1); // go to second fragment
}
});
最终结果将如下所示,如果您转到 Home 选项卡,然后返回到 Category 选项卡,您你的 Fragment
位置没有改变。
有两点你要记住:
- 设置
mPager.setOffscreenPageLimit(3);
如果你不想破坏你的片段 - 在内部片段中传递
getChildFragmentManager()
而不是FragmentManager()
如果您不需要 Inner ViewPager
并且您只想加载一个 Fragment 实例,这里是另一种选择:
1- 执行前面方法的第一项。
2- 在您的片段中 xml 放置 FrameContainer 并在其中加载您的片段:
CategoryResultFragment f = CategoryResultFragment.newInstance();
getFragmentManager().beginTransaction()
.replace(R.id.frame_result_container, f)
.commit();
编辑: 这不是最佳方法,但我认为可以解决您的问题:
1- 在您的 MainActivity
中创建一个静态字段,如下所示:
static String[] type = new String[3];
2- 当您在片段中调用 onClick 时,更新 MainActivity
中的 String
值。
public static update currentType(int pos,String type);
第一个值是 ViewPager 位置,第二个值是你的内部 Fragment 类型(例如:fragment_d);
3- 在您的 ViewPager 中
@Override
public Fragment getItem(int position) {
switch (position) {
case 0: // first tab
if(type[position] == "fragment_d")
return new Fragment_D();
else
return new Fragment_B();
}
}
您可以更改页面片段内的片段。例如TAB_A实现了拾取片段1或2的逻辑,并在里面显示拾取的片段。 层次结构如下:
ViewPager -> TAB_A -> 片段 1 或 2(显示在 TAB_A 内)。
您还应该使用 getChildFragmentManager() 来管理 TAB_A 中的片段。
您可以将 ViewPager
与 TabLayout
一起使用。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
然后创建一个扩展 FragmentStatePagerAdapter
的 class 以使用您的初始 Fragment
s:
ViewPager
public class CustomPagerAdapter extends FragmentStatePagerAdapter {
private final List<String> tabTitles = new ArrayList<String>() {{
add("Fragment 1");
add("Fragment 4");
add("Fragment 7");
}};
private List<Fragment> tabs = new ArrayList<>();
public CustomPagerAdapter(FragmentManager fragmentManager) {
super(fragmentManager);
initializeTabs();
}
private void initializeTabs() {
tabs.add(HostFragment.newInstance(new Fragment1()));
tabs.add(HostFragment.newInstance(new Fragment4()));
tabs.add(HostFragment.newInstance(new Fragment7()));
}
@Override
public Fragment getItem(int position) {
return tabs.get(position);
}
@Override
public int getCount() {
return tabs.size();
}
@Override
public CharSequence getPageTitle(int position) {
return tabTitles.get(position);
}
}
包含实际内容的片段应由 HostFragment
包裹,如果您想导航,它使用其子 FragmentManager
将当前片段替换为新片段,或者弹出片段堆栈中的最后一个片段。调用其 replaceFragment
进行导航:
public class HostFragment extends BackStackFragment {
private Fragment fragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.host_fragment, container, false);
if (fragment != null) {
replaceFragment(fragment, false);
}
return view;
}
public void replaceFragment(Fragment fragment, boolean addToBackstack) {
if (addToBackstack) {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).addToBackStack(null).commit();
} else {
getChildFragmentManager().beginTransaction().replace(R.id.hosted_fragment, fragment).commit();
}
}
public static HostFragment newInstance(Fragment fragment) {
HostFragment hostFragment = new HostFragment();
hostFragment.fragment = fragment;
return hostFragment;
}
}
HostFragment 应该扩展抽象 class BackstackFragment
public abstract class BackStackFragment extends Fragment {
public static boolean handleBackPressed(FragmentManager fm)
{
if(fm.getFragments() != null){
for(Fragment frag : fm.getFragments()){
if(frag != null && frag.isVisible() && frag instanceof BackStackFragment){
if(((BackStackFragment)frag).onBackPressed()){
return true;
}
}
}
}
return false;
}
protected boolean onBackPressed()
{
FragmentManager fm = getChildFragmentManager();
if(handleBackPressed(fm)){
return true;
} else if(getUserVisibleHint() && fm.getBackStackEntryCount() > 0){
fm.popBackStack();
return true;
}
return false;
}
}
连接 MainActivity
中的所有内容:
public class MainActivity extends AppCompatActivity {
private CustomPagerAdapter customPagerAdapter;
private ViewPager viewPager;
private TabLayout tabLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
viewPager = (ViewPager) findViewById(R.id.viewpager);
tabLayout = (TabLayout) findViewById(R.id.tablayout);
customPagerAdapter = new CustomPagerAdapter(getSupportFragmentManager());
// 2 is enough for us; increase if you have more tabs!
viewPager.setOffscreenPageLimit(2);
viewPager.setAdapter(customPagerAdapter);
tabLayout.setupWithViewPager(viewPager);
}
@Override
public void onBackPressed()
{
if(!BackStackFragment.handleBackPressed(getSupportFragmentManager())){
super.onBackPressed();
}
}
public void openNextFragment() {
HostFragment hostFragment = (HostFragment) customPagerAdapter.getItem(viewPager.getCurrentItem());
// your logic to change the fragments...
}
}
这个解决方案当然不完美,但可以完成工作。在我的 blog post 中阅读有关此问题的更多信息。