RecyclerView 自适应高度

 

http://blog.csdn.net/it_peng/article/details/51747174

 

配置版本:
compile 'com.android.support:recyclerview-v7:23.2.1'

遇过这个问题估计都知道
recyclerview 内容的高度不是 recyclerview 控制的 而是 LayoutManager 来设置的。

如果想要根据内容变化需要设置一个方法。

LayoutManager.setAutoMeasureEnabled(true);
  • 1
  • 1

如果大家有疑惑 其实可以看看 方法注释 有一句话这样写:

Defines whether the layout should be measured by the RecyclerView or the LayoutManager
* wants to handle the layout measurements itself.
我理解是 —让内容交给谁来控制

在看到 传递为 true的时候,交给谁
LayoutManager should call {@code setAutoMeasureEnabled(true)} to enable it. All of
* the framework LayoutManagers use {@code auto-measure}.

这个时候都有 LayoutManagers 来管理。

如果大家要设置动画的话,请看到这边。

https://developer.android.com/training/transitions/overview.html?utm_campaign=android_launch_supportlibrary23.2_022216&utm_source=anddev&utm_medium=blog

参考:

http://stackoverflow.com/questions/26649406/nested-recycler-view-height-doesnt-wrap-its-content/28510031#28510031

http://android-developers.blogspot.com/2016/02/android-support-library-232.html

 

 

https://github.com/sunflower-zyb/Blog/issues/3

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初识

@AllenVork

for (int i = 0; i < childCount; i++) {
            View child = recycler.getViewForPosition(i);

这里我的childCount = 7
但getViewForPosition(0)出现:

java.lang.IndexOutOfBoundsException: Invalid item position 0(0). Item count:0
at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:4604)
@herohd

java.lang.IndexOutOfBoundsException: Invalid item position 0(0). Item count:0
getViewForPosition 数组越界,
@herdotage

java.lang.IndexOutOfBoundsException: Invalid item position 0(0). Item count:0
getViewForPosition 数组越界,
@471448446

@AllenVork

mLayoutManager.setAutoMeasureEnabled(false)
recyclerView.setHasFixedSize(false)
@fishone

fishone commented on 18 Jan
你这个页面的布局,能给我一份吗!