片段作为RecyclerView的ViewHolder? [英] Fragments as a RecyclerView's ViewHolder?

查看:71
本文介绍了片段作为RecyclerView的ViewHolder?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How would one go about creating a RecyclerView who's ViewHolder children are actually Fragments?

当前示例(无效,视图彼此堆叠)

current example (does not work, views are stacked on top of eachother)

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

Here is the onResume() for a Fragment which is the main content of an 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适配器代码:

Here is the RecyclerView adapter code:

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布局:

Finally, here is the feeds_view_holder layout that is inflated in the FeedsAdapter:

<?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将片段加载为视图,而不是绑定的典型视图.这有可能吗?我想我可以抛弃RecyclerView,但是加载的内容是相当动态的(例如,有一个收藏夹提要"部分,但是如果您没有任何收藏夹,则不会显示它).当我将RecyclerView与ViewHolder子项一起使用时,一切运行正常,但是如果可能的话,我想使用Fragments.

Basically the issue is that the RecyclerView isn't loading it's children (the ViewHolders) in the expected manner. They are on top of each other. I would like the RecyclerView to load fragments as the views instead of typical views that are bound. Is this even possible? I suppose I could ditch the RecyclerView but the content loaded is fairly dynamic (for example there is a "favorite feeds" section, but if you don't have any favorites then it isn't displayed). Things were working fine when I was using a RecyclerView with ViewHolder children that held RecyclerViews within them, but I want to use Fragments if possible.

推荐答案

这不是一个好主意.

由于您从未在当前设计中回收或删除碎片,因此最好使用 LinearLayout ScrollView >将片段加载到其中.这些片段的加载时间比使用RecyclerView稍早一些,但您不必与所有未利用的再循环基础结构进行抗争.

Since you're not ever recycling or removing the fragments in the current design, you'd be better off using a ScrollView around a LinearLayout that the fragments are loaded into. The fragments will be loaded slightly sooner than with a RecyclerView, but you won't have to fight all the recycling infrastructure that you're not taking advantage of.

这些片段会彼此叠加,因为在提交事务时,您实际上并没有更改视图.您告诉片段管理器:嘿,当您有机会将这个片段连接到此ViewGroup ID上时?"片段管理器会附带它找到的该视图ID的第一个实例,因此它们会相互加载.

The fragments are being loaded on top of each other because when you commit the transaction, you're not actually changing the view. You're telling the fragment manager, "Hey, when you get a chance can you hook up this fragment to this ViewGroup ID?" The fragment manager goes with the first instance of that view ID that it finds, and so they get loaded on top of each other.

您可能可以通过为不同职位使用不同的ID来解决此问题,但我不建议这样做.

You might be able to get around that by having different IDs for the different positions, but I wouldn't recommend it.

这篇关于片段作为RecyclerView的ViewHolder?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆