[英]Set Sticky Header and Items Layouts Recyclerview
I want to build a complex layout using recyclerview android. 我想使用recyclerview android构建复杂的布局。 In the layout, I want to have a camera button to the top left fixed and a recyclerview wrapped around it with gallery images.
在布局中,我想固定一个相机按钮到左上角,并用图库图像将recyclerview包裹在其周围。 I have checked
flexbox layout manager for recyclerview
but it doesn't seem to match my use-case. 我已经为
flexbox layout manager for recyclerview
检查了flexbox layout manager for recyclerview
但是它似乎与我的用例不匹配。
I want the header to be non-repeating and not to scroll with other items vertically. 我希望标题不重复并且不要垂直滚动其他项目。 Here's the layout for the header:
这是标题的布局:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/shareLayout"
android:layout_width="185dp"
android:layout_height="135dp"
android:layout_below="@id/trendingToolbar"
android:background="@color/black">
<ImageView
android:id="@+id/cameraShareIV"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_centerHorizontal="true"
android:layout_marginTop="10dp"
app:srcCompat="@drawable/camera_white" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/cameraShareIV"
android:layout_centerHorizontal="true">
<TextView
android:id="@+id/infoTxt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginLeft="20dp"
android:gravity="center_horizontal"
android:text="@string/share_pic_video"
android:textColor="@android:color/white"
android:textSize="13sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/infoTxt"
android:layout_marginLeft="16dp"
android:text="@string/share_timeout_txt"
android:textColor="@color/colorPrimaryDark"
android:textSize="11sp"
android:textStyle="bold" />
</RelativeLayout>
and in my activity, here's the XML: 在我的活动中,这是XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="base.android.com.thumbsapp.UI.Fragments.TrendingFragment">
<include layout="@layout/trending_toolbar"
android:id="@+id/trendingToolbar"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/trendingRV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/trendingToolbar"/>
Previously, I had the header inside the activity XML but had no way to wrap a recyclerview around it. 以前,我在活动XML中包含标头,但无法在其周围包装recyclerview。 So, I have decide to use an adapter like below:
因此,我决定使用如下所示的适配器:
public class TrendingAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private static final String TAG = TrendingAdapter.class.getSimpleName();
private Context context;
private List<Trending> itemList;
private static final int HEADER = 0;
private static final int ITEMS = 1;
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v;
switch (viewType){
case HEADER:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_header, parent, false);
return new TrendingHeaderViewHolder(v);
case ITEMS:
v = LayoutInflater.from(parent.getContext()).inflate(R.layout.trending_items_layout, parent, false);
return new TrendingItemsViewHolder(v);
}
return null;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
Trending tr = itemList.get(position);
if (holder instanceof TrendingHeaderViewHolder){
((TrendingHeaderViewHolder) holder).cameraShareIV.setOnClickListener( view -> {
// TODO: 4/2/2018 select image from gallery
});
} else if (holder instanceof TrendingItemsViewHolder){
// TODO: 4/2/2018 populate gallery items here with picasso
}
}
@Override
public int getItemCount() {
return itemList.size();
}
@Override
public int getItemViewType(int position) {
return super.getItemViewType(position);
}
}
I'm confused how to make the header stick and also what to do for getItemViewType method
. 我很困惑如何使标题保持
getItemViewType method
以及如何对getItemViewType method
。
Is this the right way to approach this? 这是解决这个问题的正确方法吗? Can anyone help out?
有人可以帮忙吗? Thanks.
谢谢。
To make things simple i suggest you to look into this library 为了简单起见,我建议您研究一下这个库
In your XML Place RecylerView into StickyHeaderView
,choose horizontal or vertical orientation for your RecylerView
在你的XML将RecylerView到
StickyHeaderView
,选择适合您的水平或垂直方向RecylerView
<tellh.com.stickyheaderview_rv.StickyHeaderView
android:id="@+id/stickyHeaderView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white"
android:scrollbars="vertical" />
</tellh.com.stickyheaderview_rv.StickyHeaderView>
Create data bean class for each item type in RecyclerView. 在RecyclerView中为每种项目类型创建数据bean类。 They should extend
DataBean
. 他们应该扩展
DataBean
。 Override the method public boolean shouldSticky()
to decide whether the item view should be suspended on the top. 重写方法
public boolean shouldSticky()
来决定是否应将项目视图挂在顶部。
public class User extends DataBean {
private String login;
private int id;
private String avatar_url;
private boolean shouldSticky;
@Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.item_user;
}
public void setShouldSticky(boolean shouldSticky) {
this.shouldSticky = shouldSticky;
}
// Decide whether the item view should be suspended on the top.
@Override
public boolean shouldSticky() {
return shouldSticky;
}
}
public class ItemHeader extends DataBean {
private String prefix;
@Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.header;
}
@Override
public boolean shouldSticky() {
return true;
}
}
Create ViewBinder
to bind different type views with specific data beans. 创建
ViewBinder
以将不同类型的视图与特定数据bean绑定。 As you see, provideViewHolder(View itemView)
corresponds for onCreateViewHolder
in RecyclerView
, and bindView
corresponds for onBindViewHolder
in RecyclerView
. 如您所见,
provideViewHolder(View itemView)
对应于RecyclerView
onCreateViewHolder
,而bindView
对应于RecyclerView
onBindViewHolder
。
public class ItemHeaderViewBinder extends ViewBinder<ItemHeader, ItemHeaderViewBinder.ViewHolder> {
@Override
public ViewHolder provideViewHolder(View itemView) {
return new ViewHolder(itemView);
}
@Override
public void bindView(StickyHeaderViewAdapter adapter, ViewHolder holder, int position, ItemHeader entity) {
holder.tvPrefix.setText(entity.getPrefix());
}
@Override
public int getItemLayoutId(StickyHeaderViewAdapter adapter) {
return R.layout.header;
}
static class ViewHolder extends ViewBinder.ViewHolder {
TextView tvPrefix;
public ViewHolder(View rootView) {
super(rootView);
this.tvPrefix = (TextView) rootView.findViewById(R.id.tv_prefix);
}
}
}
Instantiate StickyHeaderViewAdapter
for RecyclerView
and register ViewBinders
for each item types. 为
RecyclerView
实例化StickyHeaderViewAdapter
并为每种项目类型注册ViewBinders
。
rv = (RecyclerView) findViewById(R.id.recyclerView);
rv.setLayoutManager(new LinearLayoutManager(this));
List<DataBean> userList = new ArrayList<>();
adapter = new StickyHeaderViewAdapter(userList)
.RegisterItemType(new UserItemViewBinder())
.RegisterItemType(new ItemHeaderViewBinder());
rv.setAdapter(adapter);
对于此布局,我建议更好的选择是使用此标头视图https://github.com/edubarr/header-decor
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.