垂直 RecyclerView 内的水平 RecyclerView
Posted
技术标签:
【中文标题】垂直 RecyclerView 内的水平 RecyclerView【英文标题】:Horizontal RecyclerView inside Vertical RecyclerView 【发布时间】:2017-01-18 08:57:11 【问题描述】:我正在尝试制作这样的东西。
所以我的想法是我有一个带有通道的垂直 recyclerview,在通道的第二个位置我应该有一个带有 relives 的水平 recyclerview。
我不知道我应该怎么做,我试着弄乱了视图,我想我应该在我的 channel_details 布局中只创建一个 recyclerview,另一个作为 item_channel_details 中的项目,但我无法做到工作。
这是我的代码。
ChannelDetailsActivity:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_channel_details);
ImageView coverPhoto = (ImageView) findViewById(R.id.image_cover_details);
final HexagonImageView avatarPhoto = (HexagonImageView) findViewById(R.id.img_hex);
TextView toolbarText = (TextView) findViewById(R.id.txt_toolbar_title);
final Bundle b = getIntent().getExtras();
final MNetworkChannel parcelChannel =
b.getParcelable(Const.IntentData.H_CHANNEL_LIST);
final MVideosForChannel parcelVideosForChannel = b.getParcelable(Const.IntentData.D_VIDEOS_LIST);
setChannelsView();
setVideosView();
private void setChannelsView()
rvRelive = (RecyclerView) findViewById(R.id.rv_relive_details);
rvRelive.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false));
adapterRelives = new ReliveAdapter();
rvRelive.setAdapter(adapterRelives);
if (getIntent() != null && getIntent().getParcelableExtra(Const.IntentData.D_RELIVE_LIST) != null)
adapterRelives.setData(((ReliveMainPojo) getIntent().getParcelableExtra(Const.IntentData.D_RELIVE_LIST)).relives);
private void setVideosView()
rvVideos = (RecyclerView) findViewById(R.id.rv_videos);
rvVideos.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
adapterVideos = new ChannelVideosAdapter();
rvVideos.setAdapter(adapterVideos);
if (getIntent() != null && getIntent().getParcelableExtra(Const.IntentData.D_VIDEOS_LIST) != null)
adapterVideos.setData(((MVideosForChannel) getIntent().getParcelableExtra(Const.IntentData.D_VIDEOS_LIST)).experience);
ChannelDetails 适配器:
public final class ChannelVideosAdapter extends RecyclerView.Adapter<ChannelVideosAdapter.ViewHolder>
private List<MVideo> data = new ArrayList<>();
public ChannelVideosAdapter()
public void setData(List<MVideo> newData)
if (newData != null && !newData.isEmpty())
data = newData;
notifyDataSetChanged();
public void clearData()
data.clear();
notifyDataSetChanged();
@Override
public final ChannelVideosAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType)
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_video_recycle_tile, parent, false));
@Override
public final void onBindViewHolder(final ChannelVideosAdapter.ViewHolder holder, final int position)
final MVideo video = data.get(position);
final String videoBackgroundImageUrl = video.asset.frame;
final String videoName = video.name;
ImageLoader.getInstance().displayImage(videoBackgroundImageUrl, holder.coverPhoto, new ImageLoadingListener()
@Override
public void onLoadingStarted(String imageUri, View view)
holder.videoLoading.setVisibility(View.VISIBLE);
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason)
holder.videoLoading.setVisibility(View.GONE);
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
holder.videoLoading.setVisibility(View.GONE);
@Override
public void onLoadingCancelled(String imageUri, View view)
holder.videoLoading.setVisibility(View.GONE);
);
holder.videoName.setText(videoName);
holder.itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
VideoPlayerActivity.StartNewVideoPlayerActivity((ChannelDetailsActivity) holder.itemView.getContext(), video, true);
);
@Override
public final int getItemCount()
return data.size();
final class ViewHolder extends RecyclerView.ViewHolder
private final ImageView coverPhoto;
private final TextView videoName;
private final ProgressBar videoLoading;
ViewHolder(final View itemView)
super(itemView);
coverPhoto = (ImageView) itemView.findViewById(R.id.img_thumbnail_background_video);
videoName = (TextView) itemView.findViewById(R.id.txt_video_name);
videoLoading = (ProgressBar) itemView.findViewById(R.id.pb_video_loading);
重温适配器:
public final class ReliveAdapter extends RecyclerView.Adapter<ReliveAdapter.ViewHolder>
private List<Relive> data = new ArrayList<>();
public ReliveAdapter()
public void setData(List<Relive> newData)
if (newData != null && !newData.isEmpty())
data = newData;
notifyDataSetChanged();
public void clearData()
data.clear();
notifyDataSetChanged();
@Override
public final ReliveAdapter.ViewHolder onCreateViewHolder(final ViewGroup parent, final int viewType)
return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_relive_recycle_tile, parent, false));
@Override
public void onBindViewHolder(final ReliveAdapter.ViewHolder holder, final int position)
final Relive relive = data.get(position);
final String reliveOwnerIconUrl = relive.owner.asset.large;
final String reliveCoverPhotoUrl = relive.asset.stream.thumbnail;
final String reliveDescription = relive.owner.name;
ImageLoader.getInstance().displayImage(reliveCoverPhotoUrl, holder.backgroundImage, new ImageLoadingListener()
@Override
public void onLoadingStarted(String imageUri, View view)
holder.imageLoading.setVisibility(View.VISIBLE);
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason)
holder.imageLoading.setVisibility(View.GONE);
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
holder.imageLoading.setVisibility(View.GONE);
ImageLoader.getInstance().displayImage(reliveOwnerIconUrl, holder.profilePicture, new ImageLoadingListener()
@Override
public void onLoadingStarted(String imageUri, View view)
holder.imageLoading.setVisibility(View.VISIBLE);
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason)
holder.imageLoading.setVisibility(View.GONE);
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage)
holder.imageLoading.setVisibility(View.GONE);
@Override
public void onLoadingCancelled(String imageUri, View view)
holder.imageLoading.setVisibility(View.GONE);
);
holder.eyeIcon.setImageResource(R.drawable.relive);
@Override
public void onLoadingCancelled(String imageUri, View view)
holder.imageLoading.setVisibility(View.GONE);
);
holder.reliveDescription.setText(reliveDescription);
holder.itemView.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
RelivePlayerActivity.StartReliveReviewActivity((ChannelDetailsActivity) holder.itemView.getContext(), relive.asset.stream.url, relive.experienceGuid, relive.guid, holder.getAdapterPosition());
);
@Override
public final int getItemCount()
return data.size();
final class ViewHolder extends RecyclerView.ViewHolder
private final CircleImageView profilePicture;
private final ImageView eyeIcon;
private final ImageView backgroundImage;
private final TextView reliveDescription;
private final ProgressBar imageLoading;
ViewHolder(View itemView)
super(itemView);
profilePicture = (CircleImageView) itemView.findViewById(R.id.profile_circle_image);
eyeIcon = (ImageView) itemView.findViewById(R.id.icon_circle_image);
backgroundImage = (ImageView) itemView.findViewById(R.id.thumbnail_image);
reliveDescription = (TextView) itemView.findViewById(R.id.description_textview);
imageLoading = (ProgressBar) itemView.findViewById(R.id.image_loading);
这是我的布局:
activity_channel_details
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar_details"
android:layout_
android:layout_
android:background="#017789"
android:textAlignment="center">
<TextView
android:id="@+id/txt_toolbar_title"
android:layout_
android:layout_
android:layout_gravity="center"
android:textColor="@android:color/white"
android:textStyle="bold" />
<ImageView
android:layout_
android:layout_
android:layout_gravity="end"
android:layout_marginEnd="10dp"
android:background="@color/white_trans"
android:src="@drawable/zeality" />
</android.support.v7.widget.Toolbar>
<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="#fff"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="#ffff"
android:orientation="vertical">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:background="#ffff"
android:orientation="vertical">
<RelativeLayout
android:layout_
android:layout_>
<ImageView
android:id="@+id/image_cover_details"
android:layout_
android:layout_
android:adjustViewBounds="true"
android:scaleType="fitXY" />
<FrameLayout
android:id="@+id/frame"
android:layout_
android:layout_
android:layout_centerInParent="true">
<co.zeality.vrplayer.views.HexagonImageView
android:id="@+id/img_hex"
android:layout_
android:layout_
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:scaleType="fitXY" />
</FrameLayout>
</RelativeLayout>
<RelativeLayout
android:layout_
android:layout_
android:layout_marginTop="5dp">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_videos"
android:layout_
android:layout_
android:nestedScrollingEnabled="false" />
</RelativeLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_relive_details"
android:layout_
android:layout_ />
</LinearLayout>
</LinearLayout>
</android.support.v4.widget.NestedScrollView>
item_video_recycle_tile
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical">
<ImageView
android:id="@+id/img_thumbnail_background_video"
android:layout_
android:layout_
android:adjustViewBounds="true" />
<FrameLayout
android:id="@+id/frame_image"
android:layout_
android:layout_
android:layout_centerInParent="true">
<ProgressBar
android:id="@+id/pb_video_loading"
android:layout_
android:layout_
android:layout_gravity="center"
android:foregroundGravity="center"
android:visibility="gone" />
<ImageView
android:layout_
android:layout_
android:layout_gravity="center_horizontal"
android:layout_marginBottom="40dp"
android:src="@drawable/glasses" />
</FrameLayout>
<FrameLayout
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:layout_alignParentStart="true">
<RelativeLayout
android:layout_
android:layout_>
<ImageView
android:id="@+id/img_play_button"
android:layout_
android:layout_
android:layout_marginBottom="5dp"
android:layout_marginStart="10dp"
android:src="@drawable/play_no_circle" />
<TextView
android:id="@+id/txt_video_name"
android:layout_
android:layout_marginBottom="5dp"
android:layout_
android:layout_below="@id/img_play_button"
android:layout_marginStart="5dp"
android:textColor="#FFF" />
</RelativeLayout>
</FrameLayout>
<View
android:layout_
android:layout_
android:layout_alignParentBottom="true"
android:background="#660c7582"></View>
【问题讨论】:
将一个recyclerview与linearlayout manager一起使用,它的item作为另一个recyclerview与gridlayout manager一起使用。 您需要在适配器中处理此问题。您将确定您希望在哪个位置拥有一个水平 RecyclerView,并且您将为那里的特定适配器位置创建不同的视图。在那个位置,您将创建自己的视图以成为 Recycler 【参考方案1】:您应该使用一个 recyclerView(垂直)作为父级,并且在位置 1 的适配器中绑定视图时,您返回一个包含 recyclerView(水平)的视图并为该 recyclerView 加载其他适配器。请参考图表以获得正确的理解。
Main RecyclerView (vertical):
---------------------------
+ Item 1
---------------------------
+ Second RecyclerView (Horizontal)
---------------------------
+ Item 2
---------------------------
父 RecyclerView 适配器代码:
@Override
public int getItemViewType(int position)
if (position == 1)
return 0;
else
return 1;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
if (viewType == 0)
View v = LayoutInflater.from(context).inflate(R.layout.your_second_recylerView_layout, parent, false);
return new ViewHolder1(v);
else
View v = LayoutInflater.from(context).inflate(R.layout.your_item_layout, parent, false);
return new ViewHolder2(v);
现在您需要为水平 recycleView 实现第二个适配器。
【讨论】:
感谢您的回答。我试着弄乱它,但它仍然太复杂了。您是否有某种参考或样本?以上是关于垂直 RecyclerView 内的水平 RecyclerView的主要内容,如果未能解决你的问题,请参考以下文章
Android 布局:具有滚动行为的 Viewpager 内的垂直 Recyclerview 内的水平 Recyclerview
如何修复垂直 RecyclerView 内的水平 ViewPager2 和 RecyclerView 的滚动问题?
NestedScrollView 内的 RecyclerView :使水平滚动更容易
在垂直 recyclerView 中带有 wrap_content 的水平 recyclerView