设置粘性页眉和项目布局 Recyclerview

Posted

技术标签:

【中文标题】设置粘性页眉和项目布局 Recyclerview【英文标题】:Set Sticky Header and Items Layouts Recyclerview 【发布时间】:2018-09-11 14:19:06 【问题描述】:

我想使用 recyclerview android 构建一个复杂的布局。在布局中,我希望在左上角固定一个相机按钮,并在其周围放置一个带有画廊图像的回收站视图。我检查了flexbox layout manager for recyclerview,但它似乎与我的用例不匹配。

我希望标题不重复,并且不与其他项目一起垂直滚动。这是标题的布局:

<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_
android:layout_
android:layout_below="@id/trendingToolbar"
android:background="@color/black">

<ImageView
    android:id="@+id/cameraShareIV"
    android:layout_
    android:layout_
    android:layout_centerHorizontal="true"
    android:layout_marginTop="10dp"
    app:srcCompat="@drawable/camera_white" />

<RelativeLayout
    android:layout_
    android:layout_
    android:layout_below="@id/cameraShareIV"
    android:layout_centerHorizontal="true">

    <TextView
        android:id="@+id/infoTxt"
        android:layout_
        android:layout_
        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_
        android:layout_
        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>

在我的活动中,这是 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_
android:layout_
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_
    android:layout_
    android:layout_below="@id/trendingToolbar"/>

以前,我在活动 XML 中包含标头,但无法在其周围包装 recyclerview。所以,我决定使用如下适配器:

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);


我很困惑如何制作标题以及如何处理getItemViewType method

这是处理这个问题的正确方法吗? 任何人都可以帮忙吗?谢谢。

【问题讨论】:

【参考方案1】:

对于这个布局,我建议更好的选择是使用这个标题视图 https://github.com/edubarr/header-decor

【讨论】:

在这个库中,是否有可能以这种方式拥有视图,例如 - 左上角的标题和周围的项目? 好的,我会尝试并接受这个答案,如果它有效。谢谢 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 ***.com/help/how-to-answer【参考方案2】:

为了简单起见,我建议您查看 this 库

在您的 XML 中将 RecylerView 放入 StickyHeaderView,为您的 RecylerView 选择水平或垂直方向

 <tellh.com.stickyheaderview_rv.StickyHeaderView
        android:id="@+id/stickyHeaderView"
        android:layout_
        android:layout_>

        <android.support.v7.widget.RecyclerView
            android:id="@+id/recyclerView"
            android:layout_
            android:layout_
            android:background="@android:color/white"
            android:scrollbars="vertical" />
    </tellh.com.stickyheaderview_rv.StickyHeaderView>

为 RecyclerView 中的每个项目类型创建数据 bean 类。他们应该扩展DataBean。覆盖方法 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;
    

创建ViewBinder 以将不同类型的视图与特定的数据bean 绑定。如您所见,provideViewHolder(View itemView) 对应于RecyclerView 中的onCreateViewHolderbindView 对应于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);
        
    

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);

【讨论】:

虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review @Rob 回答已修复,谢谢! 兄弟,我只想将第一个位置设置为标题布局。这行得通吗? @Andromeda 确定可以,您只需在适配器中指定,请下载示例并根据您的数据更改适配器。

以上是关于设置粘性页眉和项目布局 Recyclerview的主要内容,如果未能解决你的问题,请参考以下文章

具有固定页眉的真正粘性页脚?

需要粘性页眉/页脚,但 CMS 不会让我在正文标签中编码

RecyclerView 页眉和页脚

RecyclerView 页眉和页脚

在 Mat 表格中无法指定表格的高度并使页眉和页脚具有粘性

如何在此布局中使内容 100% 高度和等高列?