【发布时间】:2019-11-16 13:06:43
【问题描述】:
我有一个带有 TabLayout 的应用程序,它有一个处理选项卡的 ViewPager。这两个选项卡实例化了不同的片段。
我想要实现的是在同一个选项卡中切换片段。由于同一选项卡中的每个片段都有不同的布局(因为它依赖于特定的用户流),使用 FrameLayout 并切换其内容,只会在前一个片段的顶部创建新片段的布局。
我应该用容器创建一个通用片段并用每个片段替换它吗?如果是这样,我是否需要在运行时为每个片段构建布局?
我在网上和 SO 中进行了搜索,但未能找到专门针对我的场景的解决方案。
有没有办法实现这一点,或者我应该从不同的角度解决这个问题?
一些代码供参考:
MainActivtiy XML:
<?xml version="1.0" encoding="utf-8"?> <androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Main2Activity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary" />
</com.google.android.material.appbar.AppBarLayout>
<androidx.viewpager.widget.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>
第一个片段的 XML:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
android:layout_gravity="center"
android:orientation="vertical"
android:id="@+id/container">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:gravity="center"
></TextView>
<ProgressBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleLarge"
android:id="@+id/progress_bar"
android:layout_gravity="center">
</ProgressBar>
<GridView
android:rowCount="3"
android:numColumns="2"
android:gravity="center"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:layout_marginLeft="40dp"
>
</GridView>
</FrameLayout>
第二个片段的 XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:layout_gravity="center"
android:layout_marginBottom="5dp">
</TextView>
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:id="@+id/myRadioGroup"
android:orientation="horizontal">
</RadioGroup>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:inputType="numberDecimal">
</EditText>
<androidx.appcompat.widget.AppCompatButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:text="Submit"
android:id="@+id/submit_btn">
</androidx.appcompat.widget.AppCompatButton>
</LinearLayout>
-- 编辑--
我用来在片段之间切换的代码(在第一个片段中找到)是这样的(虽然我也尝试了其他各种方法):
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.container,secondFragment, "secondFragment")
.addToBackStack(null)
.commit();
-- 编辑#2--
下面是 FragmentPagerAdapter 代码:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
@StringRes
private static final int[] TAB_TITLES = new int[]{R.string.tab_text_1, R.string.tab_text_2};
private final Context mContext;
public SectionsPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mContext = context;
}
@Override
public Fragment getItem(int position) {
// getItem is called to instantiate the fragment for the given page.
// Return a PlaceholderFragment (defined as a static inner class below).
if (position == 1) {
return firstFragment.newInstance("One", "Two");
}
return PlaceholderFragment.newInstance(position + 1);
}
@Nullable
@Override
public CharSequence getPageTitle(int position) {
return mContext.getResources().getString(TAB_TITLES[position]);
}
@Override
public int getCount() {
// Show 2 total pages.
return 2;
}
}
这段代码来自mainActivity:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
ViewPager viewPager = findViewById(R.id.view_pager);
viewPager.setAdapter(sectionsPagerAdapter);
TabLayout tabs = findViewById(R.id.tabs);
tabs.setupWithViewPager(viewPager);
}
【问题讨论】:
-
请同时贴出你用来切换片段的代码
-
帮助我理解切换背后的意图。您想通过单击按钮从 FirstFragment 导航到 SecondFragment 吗?或者你想显示 SecondFragment 直接跳过 FirstFragment 吗?无论如何,您是否希望保留片段的后台堆栈?
-
@JavaGhost - 没有提到跳过任何片段。流程非常基本,我在问题中对其进行了概述。您有一个选项卡布局。它有两个选项卡。每个选项卡都是一个片段。为简单起见,假设第一个包含片段 A 的选项卡有一个编辑文本和一个按钮。当用户按下按钮时,片段 A 切换到片段 B。选项卡不会更改或正在加载任何其他选项卡。
-
我根据你的评论更新了我的答案
-
@tomerpacific 为您提供了多种解决方案。请说明为什么建议的解决方案不适合您。
标签: android android-fragments android-tablayout