android - 作为 RecyclerView 的 ViewHolder 的 fragment ?

标签 android android-fragments android-recyclerview

如何创建一个 RecyclerView,其 ViewHolder 子级实际上是 Fragments?

当前示例(不起作用, View 堆叠在彼此之上)

这是一个 Fragment 的 onResume(),它是 Activity 的主要内容

// onResume() in FragmentA (main content of an Activity)
recyclerView.addItemDecoration(new VerticalSpaceItemDecoration(5));
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
List<Fragment> fragments = new LinkedList<>();
fragments.add(FeaturedRecyclerFragment.newInstance(R.string.recycler_title_featured));
fragments.add(TrendingRecyclerFragment.newInstance(R.string.recycler_title_trending));
FeedsAdapter recyclerAdapter = new FeedsAdapter(getContext(), getFragmentManager(), fragments);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(recyclerAdapter);

这是 RecyclerView 适配器代码:

public class FeedsAdapter extends RecyclerView.Adapter<FeedsAdapter.FeedsViewHolder> {

    private static final String TAG = FeedsAdapter.class.getSimpleName();

    private final Context context;
    private FragmentManager fragmentManager;
    private final List<Fragment> fragments;

    public FeedsAdapter(Context context, FragmentManager fragmentManager, List<Fragment> fragments) {
        this.context = context;
        this.fragmentManager = fragmentManager;
        this.fragments = fragments;
    }

    @Override
    public FeedsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Log.d(TAG, "onCreateViewHolder()");
        View itemView = LayoutInflater.from(context).inflate(R.layout.feeds_view_holder, parent, false);
        return new FeedsViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(FeedsViewHolder holder, int position) {
        Log.d(TAG, "onBindViewHolder() " + position);
        if (fragmentManager == null) {
            throw new IllegalArgumentException("LoaderManager null, cannot bind view holder");
        }

        Fragment fragment = fragments.get(position);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(holder.itemView.getId(), fragment, TAG + "pos" + position);
        transaction.commit();
    }

    @Override
    public int getItemCount() {
        Log.d(TAG, "getItemCount()");
        return fragments.size();
    }

    static class FeedsViewHolder extends RecyclerView.ViewHolder {

        public FeedsViewHolder(View itemView) {
            super(itemView);
        }
    }
}

最后,这是在 FeedsAdapter 中膨胀的 feeds_view_holder 布局:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/recycler_fragment_container">

</FrameLayout>

基本上,问题是 RecyclerView 没有以预期的方式加载它的子项(ViewHolders)。他们在彼此之上。我希望 RecyclerView 将 fragment 加载为 View 而不是绑定(bind)的典型 View 。这可能吗?我想我可以放弃 RecyclerView,但加载的内容相当动态(例如,有一个“最喜欢的提要”部分,但如果您没有任何最喜欢的内容,则不会显示)。当我将 RecyclerView 与包含 RecyclerView 的 ViewHolder 子级一起使用时,一切正常,但我想尽可能使用 Fragment。

最佳答案

这不是个好主意。

由于您永远不会回收或删除当前设计中的 fragment ,因此最好使用 ScrollView围绕 LinearLayout fragment 被加载到。与使用 RecyclerView 相比, fragment 的加载速度稍快,但您不必与所有未利用的回收基础设施作斗争。

fragment 正在彼此叠加加载,因为当您提交事务时,您实际上并没有更改 View 。你是在告诉 fragment 管理器,“嘿,有机会的话你能把这个 fragment 连接到这个 ViewGroup ID 吗?” fragment 管理器与它找到的该 View ID 的第一个实例一起使用,因此它们被加载到彼此之上。

您可以通过为不同的职位设置不同的 ID 来解决这个问题,但我不推荐这样做。

关于android - 作为 RecyclerView 的 ViewHolder 的 fragment ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36046940/

相关文章:

java - 重用执行异步代码并回发到 UI 线程的代码

android - Android中选项卡的生命周期

android - 如何在android中显示 fragment

java - RecyclerView 中的复选框变为 'sticky'

android - 如何在recyclerview android中用 child 填充项目

java - RxJava - 将列表和请求转换为 map

java - 从解析中检索数组

android - 权限拒绝 : receiving Intent { act=com. google.android.c2dm.intent.REGISTRATION

android-fragments - 我如何初始化片段中onViewCreated之外的viewModel

android - RecyclerView - 填充动画 -> 将所有元素从一个原点移动到目标位置