在ViewPager中看不到碎片

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在ViewPager中看不到碎片相关的知识,希望对你有一定的参考价值。

虽然我可以在ViewPager中滚动,但物理碎片本身由于某种原因是不可见的。

仅供参考 - 我有一个使用ViewPager的标签活动。在第一个标签/片段中,我有下面的代码。基本上,我有一个带有ViewPager的App控制选项卡,其中一个选项卡中有另一个ViewPager来控制一堆图像。我已经测试了有问题的片段,将它放在顶层视图寻呼机中,它完全正常!只有当我把它放在有问题的视图寻呼机中时它才会呈现任何东西......

因此,这是更好理解的层次结构:

MainActivity has a ...
  ViewPager (3 fragments showing the tab content) has a ...
    1st TabFragment has a ...
      ViewPager (3 fragments showing images) <--- I can't see these, but I can swipe on them for some reason.

不幸的是......没有任何片段是可见的,但是......我仍然可以将某些原因刷到最后一个片段......只是没有任何明显的显示......

内置ViewPager的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v4.view.ViewPager
        android:id="@+id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

使用ViewPager编写代码

final List<Fragment> imageFragments = new ArrayList<>();

for (final UserImage userImage : user.getImages()) {
    final SizeImage processed = userImage.getProcessed();
    imageFragments.add(UserImageFragment.newInstance(processed.getFullsize()));
}

final ImagesPagerAdapter imagesAdapter = new ImagesPagerAdapter(getFragmentManager(), imageFragments);
viewPager.setAdapter(imagesAdapter);

PagerAdapter:

public class ImagesPagerAdapter extends FragmentStatePagerAdapter {

@NonNull
private List<Fragment> fragments;

public ImagesPagerAdapter(@NonNull final FragmentManager fragmentManager,
                          @NonNull final List<Fragment> fragments) {
    super(fragmentManager);
    this.fragments = fragments;
}

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

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

片段:

public class UserImageFragment extends Fragment {

@BindView(R.id.image_view)
ImageView imageView;

public static UserImageFragment newInstance(final String url) {
    final UserImageFragment fragment = new UserImageFragment();

    Bundle args = new Bundle();
    args.putString("url", url);
    fragment.setArguments(args);

    return fragment;
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.fragment_user_image, container, false);

    ButterKnife.bind(this, view);

    final Bundle arguments = getArguments();

    if (arguments != null) {
        final String url = arguments.getString("url", null);
        if (url != null) {
            final Uri uri = Uri.parse(url);

            Picasso.with(getActivity()).load(url).into(imageView, new Callback() {
                @Override
                public void onSuccess() {
                    Toast.makeText(getActivity(), "Success", Toast.LENGTH_SHORT).show();
                }

                @Override
                public void onError() {
                    Toast.makeText(getActivity(), "Fail", Toast.LENGTH_SHORT).show();
                }
            });
          }
        }
      return view;
     }
   }

这是xml代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/md_red_900">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:background="@color/md_yellow_500" />

</RelativeLayout>
答案

要在另一个片段中显示片段,请使用getChildFragmentManager()而不是getFragmentManager()

final ImagesPagerAdapter imagesAdapter = new 
 ImagesPagerAdapter(getChildFragmentManager(), imageFragments);
   viewPager.setAdapter(imagesAdapter);
另一答案

乍一看可能并不明显,但不要尝试缓存或准备片段适配器的片段。 Fragment(State)PagerAdapter.getItem必须返回一个新项目,并且调用该方法时由适配器在内部进行管理。

让片段适配器具有在正确的时间构建片段所需的数据:

final List<UserImage> userImages = user.getImages();
final ImagesPagerAdapter imagesAdapter = new ImagesPagerAdapter(getFragmentManager(), userImages);
viewPager.setAdapter(imagesAdapter);

并实现片段适配器,以便getItem返回一个新片段:

public class ImagesPagerAdapter extends FragmentStatePagerAdapter {

    @NonNull
    private List<UserImage> userImages;

    public ImagesPagerAdapter(@NonNull final FragmentManager fragmentManager,
                              @NonNull final List<UserImage> userImages) {
        super(fragmentManager);
        this.userImages = userImages;
    }

    @Override
    public Fragment getItem(final int position) {
        final UserImage userImage = userImages.get(position);
        final SizeImage processed = userImage.getProcessed();
        return UserImageFragment.newInstance(processed.getFullsize())
    }

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

在这里,我看到两个改进的选择:

  1. List<UserImage>List<SizeImage>替换List<whatever getFullSize returns>。泄漏到适配器的实现细节越少越好。
  2. 如果userImage.getProcessed().getFullsize()需要时间(访问磁盘,执行计算),请在UserImageFragment生命周期方法之一中异步执行 - 按照需要时间并且不阻止UI线程。

FragmentPagerAdapterFragmentStatePagerAdapter都没有考虑更新

  1. 不要试图修改userImages列表。
  2. 如果图像更改,请更换并重新连接整个适配器。

以上是关于在ViewPager中看不到碎片的主要内容,如果未能解决你的问题,请参考以下文章

在 Android Studio 中看不到对话框片段

我在片段中看不到选项菜单

带有recyclerviews的碎片需要很长时间才能加载

如何以编程方式从片段内部设置ViewPager选项卡?

动态中心对齐 ViewPager

选项卡执行android中下一个片段中存在的代码