设置粘滞标题和项目布局Recyclerview

时间:2018-04-02 11:02:22

标签: android android-recyclerview recycler-adapter stickyrecycleview

我想使用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_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>

在我的活动中,这是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"/>

以前,我在活动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

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

2 个答案:

答案 0 :(得分:0)

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

在您的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>

为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)对应onCreateViewHolder中的RecyclerView,而bindView对应onBindViewHolder中的RecyclerView

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

StickyHeaderViewAdapter实例化RecyclerView并为每种商品类型注册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);

答案 1 :(得分:0)

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