Skip to content

# RecyclerView使用GridLayoutManager,高度设置为wrap_content时无效 #3

Description

@sunflower-zyb

RecyclerView使用GridLayoutManager,高度设置为wrap_content时无效

标签(空格分隔): RecyclerView GridLayoutManager wrap_content


今天在使用RecyclerView,将布局设置为GridLayoutManager时,发现高度设置为wrap_content无效:
描述
Google一下后,结果如下。

RecyclerView并不负责Item的显示工作,而Adapter负责的是数据仓库和Item的视图,所以最终把目标锁定到RecyclerView.LayoutManager上。于是尝试继承LinearLayoutManager,发现果然有onMeasure方法。

类名 说明
RecyclerView.Adapter 托管数据集合,为每个Item创建视图
RecyclerView.ViewHolder 承载Item视图的子视图
RecyclerView.LayoutManager 负责Item视图的布局
RecyclerView.ItemDecoration 为每个Item视图添加子视图,在Demo中被用来绘制Divider
RecyclerView.ItemAnimator 负责添加、删除数据时的动画效果

于是自定义MyGridLayoutManager,继承自GridLayoutManager,重写onMeasure方法:

@Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
        int height = 0;
        int childCount = getItemCount();
        for (int i = 0; i < childCount; i++) {
            View child = recycler.getViewForPosition(i);
            measureChild(child, widthSpec, heightSpec);
            if (i % getSpanCount() == 0) {
                int measuredHeight = child.getMeasuredHeight() + getDecoratedBottom(child);
                height += measuredHeight;
            }
        }
        setMeasuredDimension(View.MeasureSpec.getSize(widthSpec), height);
    }

此时,RecyclerView便可显示实际高度:

完整代码如下:

package com.sunflower.music.recyclerview;

import android.content.Context;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.util.Log;
import android.view.View;

/**
 * Created by sunflower on 2015/8/30.
 */
public class MyGridLayoutManager extends GridLayoutManager {
    public MyGridLayoutManager(Context context, int spanCount) {
        //默认方向是VERTICAL
        super(context, spanCount);
    }

    public MyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) {
        super(context, spanCount, orientation, reverseLayout);
    }

    @Override
    public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
        int height = 0;
        Log.i("msg", "onMeasure---MeasureSpec-" + View.MeasureSpec.getSize(heightSpec));
        int childCount = getItemCount();
        for (int i = 0; i < childCount; i++) {
            View child = recycler.getViewForPosition(i);
            measureChild(child, widthSpec, heightSpec);
            if (i % getSpanCount() == 0) {
                int measuredHeight = child.getMeasuredHeight() + getDecoratedBottom(child);
                height += measuredHeight;
            }
        }
        Log.i("msg", "onMeasure---height-" + height);
        setMeasuredDimension(View.MeasureSpec.getSize(widthSpec), height);

    }

}

第二个构造函数参数reverseLayout的含义是什么呢?官方文档是这么说明的:

When set to true, layouts from end to start.

实践是检验真理的唯一标准,当设置为true后,效果如下:

可以看到“心情”下面的排列顺序由0~15的递增顺序变为递减了,所以当reverseLayout设置为true时,会将Adapter对应的内容倒着显示

本文中的表格来自Android-RecylerView初识

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions