问题
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)
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);
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);
}
}
}
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>
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.
回答1:
This is not a good idea.
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.
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.
You might be able to get around that by having different IDs for the different positions, but I wouldn't recommend it.
回答2:
Try to change your root view group from framelayout to linear layout to stop the views from being drawn on each other.
来源:https://stackoverflow.com/questions/36046940/fragments-as-a-recyclerviews-viewholder