安卓-ViewPager未显示片段

4
我正在使用一个tablayout在一个fragment中,TabLayout有两个fragment:一个显示日历,另一个是简单的纯文本,我可以正确地在选项卡之间切换而不触发任何错误,问题是内容(内部fragment)没有显示,它们只是“不存在”!
  • 我尝试查看其他在StackoverFlow上遇到相同问题的线程,但大多数人都遇到了NPE(空指针例外)错误的问题,这不是我的情况。

  • 我尝试使用:getChildFragmentManager()getFragmentManager()代替getSupportFragmentManager()

  • 请记住,我正在使用嵌套片段(片段中的片段)

  • 我正在使用AndroidHive的文档,我以前使用过它,但只是用简单的片段而不是嵌套的片段,它完美地工作

  • 我尝试使用布局检查器工具。

问:我错过了什么,应该怎么做才能让它正常运行?!

以下是我的代码:

XML: MainFragment

<LinearLayout
   android:orientation="vertical"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">
   <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.v4.view.ViewPager
           android:id="@+id/viewpager"
           android:layout_height="match_parent"
           android:layout_width="match_parent"
           app:layout_behavior="@string/appbar_scrolling_view_behavior">
       </android.support.v4.view.ViewPager>
</LinearLayout>

XML:日历片段

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:animateLayoutChanges="true"
    android:id="@+id/main_content"
    tools:context=".Tabs.CalendarTab">
    <com.github.sundeepk.compactcalendarview.CompactCalendarView
        android:visibility="visible"
        android:id="@+id/compact_calendar"
        android:layout_width="match_parent"
        android:paddingRight="6dp"
        android:paddingLeft="6dp"
        android:layout_height="250dp"
        app:compactCalendarTargetHeight="250dp"
        app:compactCalendarTextSize="12sp"
        app:compactCalendarBackgroundColor="@color/colorWhite"
        app:compactCalendarTextColor="@color/colorDarkGrey"
        app:compactCalendarCurrentDayBackgroundColor="@color/color13"
        app:compactCalendarMultiEventIndicatorColor="@color/textColor2"
        app:compactCalendarShouldSelectFirstDayOfMonthOnScroll="true"
        app:compactCalendarCurrentDayIndicatorStyle="fill_large_indicator"/>
</RelativeLayout>

XML列表片段

<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="250dp"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".Tabs.FullListTab">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:text="You Are In Tab 2"
        android:id="@+id/textView"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>

MainFragment JAVA

private TabLayout tabLayout;
private ViewPager viewPager;

//onCreate Method:
viewPager = (ViewPager) view.findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
/*** end onCreate() ***/

private void setupViewPager(ViewPager viewPager) {
    ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());
    adapter.addFragment(new CalendarTab(), "Calendar");
    adapter.addFragment(new FullListTab(), "List");
    viewPager.setAdapter(adapter);
}

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();
    private final List<String> mFragmentTitleList = new ArrayList<>();

    public ViewPagerAdapter(FragmentManager manager) {
        super(manager);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragmentList.get(position);
    }

    @Override
    public int getCount() {
        return mFragmentList.size();
    }

    public void addFragment(Fragment fragment, String title) {
        mFragmentList.add(fragment);
        mFragmentTitleList.add(title);
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitleList.get(position);
    }
}
3个回答

2
adapter.addFragment(new CalendarTab(), "Calendar");
adapter.addFragment(new FullListTab(), "List");

...

class ViewPagerAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragmentList = new ArrayList<>();

不要这样做,永远不要。这可能导致非常难以理解的错误。你必须从getItem()内部返回新的Fragment实例,而不是从其他地方返回。



至于你的实际问题,

XML: MainFragment

<LinearLayout
   android:orientation="vertical"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content">
将这个改为match_parentmatch_parent。最初的回答。

我正在使用类似于你的答案的东西。 ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager(); adapter.AddFragment(new FragmentHistory(), ""); adapter.AddFragment(new FragmentBookmark(), ""); adapter.AddFragment(new FragmentSettings(), ""); mViewPager.setAdapter(adapter); mTabLayout.setupWithViewPager(mViewPager);。 为什么您说永远不要这样做,有另一种实现方式吗? - TheCoderGuy
@Spritzig 如果你这样做,就会遇到这个问题:https://dev59.com/NLPma4cB1Zd3GeqPpFkd#55754360 (但你也可以在 https://stackoverflow.com/q/53978606/2413303 找到同样的问题) - EpicPandaForce
@EpicPandaForce,非常感谢您提供的有用提示,我会努力改进!但是将宽度和高度更改为“match_parent”并没有解决问题,就像视图的可见性设置为“Gone”,除了选项卡标题之外什么也没有!此外,您是否记得所有这些都在另一个父片段中? - Thorvald
它位于另一个父片段中的问题应该已经通过使用 getChildFragmentManager() 解决了。这听起来像是布局大小的问题。然而,它不是我所想象的那样,因此你可能需要考虑使用 Layout Inspector 工具查看哪个视图的大小为 0,0 而不是你实际期望的大小。 - EpicPandaForce
@Spritzig 只有在测试这种情况时才会以明显的方式出现:https://dev59.com/sVUM5IYBdhLWcg3wSetQ#49107399 - EpicPandaForce
显示剩余3条评论

1

我曾经遇到过类似的问题。我通过将TabLayout嵌套在ViewPager中来解决它,可以在文档中看到:

<LinearLayout
  android:orientation="vertical"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content">

  <android.support.v4.view.ViewPager
    android:id="@+id/viewpager"
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior">

    <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.v4.view.ViewPager>
</LinearLayout>

1
什么?不,你不这样做。 - EpicPandaForce
几周前我遇到了这个问题,通过嵌套TabLayout解决了它。除非是另一个bug被这样做“修复”了:P 无论如何,我遵循了文档:https://developer.android.com/reference/android/support/design/widget/TabLayout#viewpager-integration - Ricardo Costeira
嗯,“作为ViewPager的装饰的一部分”...我想知道那是什么意思。但是,显然你可以把它放在ViewPager里面。不过我认为你不必这样做,即使不放在里面也能工作。 - EpicPandaForce
1
是的,一开始我也没有嵌套它,因为大多数在线示例也不是这样做的。我也不太理解 "decor" 部分,但我尝试了嵌套它并解决了我的问题。我的问题与 OP 的类似,因此需要“嵌套”。我想我会编辑答案以让它更清晰明了。 - Ricardo Costeira
@RicardoCosteira 可能不是那个问题,我尝试了但没有成功。 - Thorvald

1
我使用一个名为SPager的第三方库解决了这个问题,这里是完整文档的Github链接SPager不使用适配器,实现起来更容易更快速。

然而,我仍在寻找另一种方法,而不使用第三方库

这就是我实际上所做的(如他们在Github中提到的):

实施

implementation 'com.github.alfianyusufabdullah:spager:1.2.0'

在XML布局文件中。
<com.alfianyusufabdullah.SPager
   android:id="@+id/mPager"
   android:layout_width="match_parent"
   android:layout_height="match_parent" />

在我的JAVA课程中。
private SPager myViewPager;

//...

myViewPager = view.findViewById(R.id.mPager);

//...

myViewPager.initFragmentManager(getChildFragmentManager());
myViewPager.addPages("Inner fragment 1", new IFragOne());
myViewPager.addPages("Inner fragment 2", new IFragTwo());
myViewPager.build();

如果您正在使用 tabLayout,可以像这样将其与 SPager 绑定:

IF

myViewPager.addTabLayout(tabLayout);

我还应该提到,SPagerKotlin 兼容。

我决定发帖,可能对其他人有用。对于我的情况,这是一个临时解决办法,直到有人回答这个帖子!


这已经足以解决我的问题了!我刚刚提交了 +50 的奖励!愉快的编码 :) - Metronom

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接