在ViewPager中看不到碎片

时间:2017-12-28 15:19:19

标签: android android-viewpager fragment

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

仅供参考 - 我有一个使用ViewPager的标签的活动。在第一个标签/片段中,我有以下代码。基本上,我有一个带ViewPager的应用程序控制选项卡,其中一个选项卡中的另一个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>

2 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

乍一看可能并不明显,但不会尝试缓存或准备片段适配器的片段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线程。

  3. FragmentPagerAdapterFragmentStatePagerAdapter都未考虑更新而构建

    1. 请勿尝试修改userImages列表。
    2. 如果图像发生变化,请更换并重新连接整个适配器。