【Android视图效果】分组列表实现吸顶效果

本文介绍了如何在Android中实现一个分组列表,列表包含按月份分组的图片,顶部有一个悬浮栏,可随滑动刷新。文章详细讲解了使用RecyclerView+GridLayoutManager创建列表,实现多布局,处理头部点击事件,以及点击顶部栏弹出筛选框的思路和关键代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

效果图

20190212_142252.gif

分析

先来分析一下,可以看到这是一个按月份分组的2行图片列表,列表顶部一个悬浮栏,会随着列表滑动而刷新,点击顶部栏,弹出了一个筛选框。

思路

1.列表部分

可以用RecyclerView+GridLayoutManager,月份的标题栏可以使用多布局

首先是主体item的布局

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView 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="wrap_content"
    android:background="@color/cffffff"
    app:cardCornerRadius="4dp">


    <android.support.constraint.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@+id/iv_pictrue"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1.78:1" />

        <TextView
            android:id="@+id/tv_pictrue_title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:textColor="@color/c151619"
            android:textSize="16sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/iv_pictrue"
            tools:text="长沙会议图集(210)" />

        <TextView
            android:id="@+id/tv_pictrue_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:layout_marginBottom="10dp"
            tools:text="2018-11-10"
            android:textColor="@color/c969696"
            android:textSize="16sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/tv_pictrue_title" />


    </android.support.constraint.ConstraintLayout>

</android.support.v7.widget.CardView>

然后是月份标题的布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:orientation="horizontal"
    android:paddingTop="15dp"
    android:paddingBottom="15dp">

    <TextView
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="10dp"
        android:layout_weight="1"
        android:background="@color/cbbbfc2" />

    <TextView
        android:id="@+id/tv_picture_month"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2018年10月"
        android:textColor="@color/c969696"
        android:textSize="16sp" />


    <TextView
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="15dp"
        android:layout_weight="1"
        android:background="@color/cbbbfc2" />


</LinearLayout>

PictureAdapter 这里使用了 BaseRecyclerViewAdapterHelper,需要继承BaseMultiItemQuickAdapter,关于adapter多布局的使用,篇幅所限,这里不再细述。

public class PictureAdapter extends BaseMultiItemQuickAdapter<PictureModel, BaseViewHolder> {
   
   
    public PictureAdapter(@Nullable List<PictureModel> data) {
   
   
        super(data);
        addItemType(PictureModel.PICTURE_CONTENT, R.layout.item_pictures);
        addItemType(PictureModel.PICTURE_TITLE, R.layout.item_picture_month);
    }


    @Override
    protected void convert(BaseViewHolder helper, PictureModel item) {
   
   

        if (helper.getItemViewType() == PictureModel.PICTURE_CONTENT) {
   
   
            //标题/数量
            helper.setText(R.id.tv_pictrue_title, item.getTitle() + "(" + item.getPicture_count() + ")");
            //时间
            helper.setText(R.id.tv_pictrue_time, item.getDate());
            //封面图
            GlideUtils.loadImg(mContext, item.getCover_image(), (ImageView) helper.getView(R.id.iv_pictrue));

        } else if (helper.getItemViewType() == PictureModel.PICTURE_TITLE) {
   
   
            helper.setText(R.id.tv_picture_month, item.getDate());

        }

    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
   
   
        super.onAttachedToRecyclerView(recyclerView);
        FullSpanUtil.onAttachedToRecyclerView(recyclerView, this, PictureModel.PICTURE_TITLE);


    }

    @Override
    public void onViewDetachedFromWindow(@NonNull BaseViewHolder holder) {
   
   
        super.onViewDetachedFromWindow(holder);
        FullSpanUtil.onViewAttachedToWindow(holder, this, PictureModel.PICTURE_TITLE);
    }

}

其中,由于月份的标题需要占满一行,需要重写onAttachedToRecyclerView和onViewDetachedFromWindow方法。

public class FullSpanUtil {
   
   

    public static void onAttachedToRecyclerView(RecyclerView recyclerView, final RecyclerView.Adapter adapter, final int pinnedHeaderType) {
   
   
        // 如果是网格布局,这里处理标签的布局占满一行
        final RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
   
   
            final GridLayoutManager gridLayoutManager = (GridLayoutManager) layoutManager;
            final GridLayoutManager.SpanSizeLookup oldSizeLookup = gridLayoutManager.getSpanSizeLookup();
            gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
   
   
                @Override
                public int getSpanSize(int position) {
   
   
                    if (adapter.getItemViewType(position) == pinnedHeaderType) {
   
   
                        return gridLayoutManager.getSpanCount();
                    }
                    if (oldSizeLookup 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值