android recyclerview linearlayout addviewmanager必须要设置吗

2464人阅读
android技术文档(143)
ScrollView嵌套RecyclerView时,android:layout_height=”wrap_content”并不起作用,RecyclerView会填充剩余的整个屏幕空间,也就相当于android:layout_height=”match_parent”,通过重写GridLayoutManager或LinearLayoutManager 的onMeasure方法进行可重置RecyclerView的高度。
这里只给出GridLayoutManager的例子,LinearLayoutManager类似
a.设置LayoutManager
rvPhotos.setLayoutManager(new PhotoLayoutManage(this, 3));
b.RecyclerView的Adapter
Adapter中定义变量item中的height
private int itemH
public int getItemHeight(){ return itemH}
在Adapter的ViewHolder构造方法中设置item项显示后的高度
itemView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
public boolean onPreDraw() {
itemHeight=convertView.getMeasuredHeight();
return true;
c.自定义GridLayoutManager重写onMeasure方法
public class PhotoLayoutManage extends GridLayoutManager{
public PhotoLayoutManage(Context context,int spanCount) {
super(context,spanCount);
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, final int widthSpec,final int heightSpec) {
if(adapter!=null&&adapter.getItemHeight()&0) {
int measuredWidth = View.MeasureSpec.getSize(widthSpec);
int line = adapter.getItemCount() / getSpanCount();
if (adapter.getItemCount() % getSpanCount() & 0) line++;
int measuredHeight = adapter.getItemHeight()* line+rvPhotos.getPaddingBottom()+rvPhotos.getPaddingTop();
setMeasuredDimension(measuredWidth, measuredHeight);
super.onMeasure(recycler,state,widthSpec,heightSpec);
}catch (Exception e){
super.onMeasure(recycler,state,widthSpec,heightSpec);
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:96177次
积分:1688
积分:1688
排名:第16320名
原创:31篇
转载:277篇
评论:13条
(1)(1)(2)(25)(3)(5)(9)(7)(3)(7)(7)(6)(9)(10)(9)(1)(2)(1)(7)(7)(3)(9)(7)(7)(8)(6)(3)(8)(6)(6)(5)(26)(18)(5)(70)(1)Android学习(241)
Android UI(8)
该系列文章 &如果想全方面学习,建议参考这个大牛的文章,写的真可以。
地址:http://blog.csdn.net/lmj/article/details/
ItemDecoration &下划线效果
在使用RecyclerView 的时候有三种东西是可以自己定义的 & 响应事件 & &分割线 &动画效果
&mRecyclerView&=&findView(R.id.id_recyclerview);
//设置布局管理器 &layout可以设置方向
mRecyclerView.setLayoutManager(layout);
//设置adapter
mRecyclerView.setAdapter(adapter)
//设置Item增加、移除动画
mRecyclerView.setItemAnimator(new&DefaultItemAnimator());
//添加分割线
mRecyclerView.addItemDecoration(new&DividerItemDecoration(&getActivity(),&DividerItemDecoration.HORIZONTAL_LIST));&
布局管理器有三种:
LinearLayoutManager 现行管理器,支持横向、纵向。GridLayoutManager 网格布局管理器StaggeredGridLayoutManager 瀑布就式布局管理器
这节主要学习如何添加下划线:为LinearLayoutManager模式添加下划线 &&mRecyclerView.addItemDecoration()&
我们可以通过该方法添加分割线:&
mRecyclerView.addItemDecoration()&
该方法的参数为RecyclerView.ItemDecoration,该类为抽象类,官方目前并没有提供默认的实现类(我觉得最好能提供几个)。&
该类的源码:
public static abstract class ItemDecoration {
public void onDraw(Canvas c, RecyclerView parent, State state) {
onDraw(c, parent);
public void onDrawOver(Canvas c, RecyclerView parent, State state) {
onDrawOver(c, parent);
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) {
getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),
@Deprecated
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
outRect.set(0, 0, 0, 0);
当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,即调用该类的onDraw和onDrawOver方法,
onDraw方法先于drawChildrenonDrawOver在drawChildren之后,一般我们选择复写其中一个即可。getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。
接下来我们看一个RecyclerView.ItemDecoration的实现类,该类很好的实现了RecyclerView添加分割线(当使用LayoutManager为LinearLayoutManager时)。&
该类参考自:
* Copyright (C) 2014 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the &License&);
* limitations under the License.
import android.content.C
import android.content.res.TypedA
import android.graphics.C
import android.graphics.R
import android.graphics.drawable.D
import android.support.v7.widget.LinearLayoutM
import android.support.v7.widget.RecyclerV
import android.support.v7.widget.RecyclerView.S
import android.util.L
import android.view.V
* This class is from the v7 samples of the Android SDK. It's not by me!
* See the license above for details.
public class DividerItemDecoration extends RecyclerView.ItemDecoration {
private static final int[] ATTRS = new int[]{
android.R.attr.listDivider
public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;
public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;
private Drawable mD
private int mO
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL_LIST && orientation != VERTICAL_LIST) {
throw new IllegalArgumentException(&invalid orientation&);
mOrientation =
public void onDraw(Canvas c, RecyclerView parent) {
Log.v(&recyclerview - itemdecoration&, &onDraw()&);
if (mOrientation == VERTICAL_LIST) {
drawVertical(c, parent);
drawHorizontal(c, parent);
public void drawVertical(Canvas c, RecyclerView parent) {
final int left = parent.getPaddingLeft();
final int right = parent.getWidth() - parent.getPaddingRight();
final int childCount = parent.getChildCount();
for (int i = 0; i & childC i++) {
final View child = parent.getChildAt(i);
android.support.v7.widget.RecyclerView v = new android.support.v7.widget.RecyclerView(parent.getContext());
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int top = child.getBottom() + params.bottomM
final int bottom = top + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
public void drawHorizontal(Canvas c, RecyclerView parent) {
final int top = parent.getPaddingTop();
final int bottom = parent.getHeight() - parent.getPaddingBottom();
final int childCount = parent.getChildCount();
for (int i = 0; i & childC i++) {
final View child = parent.getChildAt(i);
final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child
.getLayoutParams();
final int left = child.getRight() + params.rightM
final int right = left + mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(c);
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {
if (mOrientation == VERTICAL_LIST) {
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
该实现类可以看到通过读取系统主题中的&android.R.attr.listDivider作为Item间的分割线,并且支持横向和纵向。如果你不清楚它是怎么做到的读取系统的属性用于自身,请参考一篇博文:
获取到listDivider以后,该属性的值是个Drawable,在getItemOffsets中,outRect去设置了绘制的范围。onDraw中实现了真正的绘制。
在原来的代码中添加一句:
mRecyclerView.addItemDecoration(new&DividerItemDecoration(&getActivity(),&DividerItemDecoration.HORIZONTAL_LIST));&
该分割线是系统默认的,你可以在styles.xml中找到该属性的使用情况。那么,使用系统的listDivider有什么好处呢?就是方便我们去随意的改变,该属性我们可以直接声明在:
&!-- Application theme. --&
&style name=&AppTheme& parent=&AppBaseTheme&&
&item name=&android:listDivider&&@drawable/divider_bg&/item&
然后自己写个drawable即可,下面我们换一种分隔符:
&?xml version=&1.0& encoding=&utf-8&?&
&shape xmlns:android=&/apk/res/android&
android:shape=&rectangle& &
android:centerColor=&#ff00ff00&
android:endColor=&#ff0000ff&
android:startColor=&#ffff0000&
android:type=&linear& /&
&size android:height=&4dp&/&
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:74788次
积分:3994
积分:3994
排名:第5181名
原创:248篇
转载:183篇
译文:61篇
评论:21条
(9)(39)(46)(100)(24)(5)(1)(6)(68)(40)(43)(7)(5)(6)(4)(2)(4)(5)(39)(31)(5)(1)(6)
学习HTML5游戏编程Android Open Source - RecyclerViewLib
Grid Layout ManagerFrom ProjectBack to project page .LicenseThe source code is released under:
Apache License
Java Source Codepackage com.twotoasters.
import android.content.C
import android.util.L
import android.view.V
import com.twotoasters.android.support.v7.widget.RecyclerV
public class GridLayoutManager extends BaseLayoutManager {
private static final int DEFAULT_COLUMNS = 2;
private int
private static final String TAG = GridLayoutManager.class.getSimpleName();
public GridLayoutManager(Context context){
this(context, DEFAULT_COLUMNS, VERTICAL);
public GridLayoutManager(Context context, int columns, int orientation) {
super(context, orientation, false);
this.columns =
public int getColumns() {
public void setColumns(int columns) {
this.columns =
protected int fill(RecyclerView.Recycler recycler, BaseLayoutManager.RenderState renderState,
RecyclerView.State state, boolean stopOnFocusable) {
if (mOrientation == VERTICAL) {
itemWidth = (getWidth() - getPaddingLeft() - getPaddingRight()) /
itemWidth = (getHeight() - getPaddingTop() - getPaddingBottom()) /
// max offset we should set is mFastScroll + available
final int start = renderState.mA
if (renderState.mScrollingOffset != RenderState.SCOLLING_OFFSET_NaN) {
// TODO ugly bug fix. should not happen
if (renderState.mAvailable & 0) {
renderState.mScrollingOffset += renderState.mA
recycleByRenderState(recycler, renderState);
int remainingSpace = renderState.mAvailable + renderState.mE
int columnCount = 0;
while (remainingSpace & 0 && renderState.hasMore(state)) {
View view = renderState.next(recycler);
if (view == null) {
if (DEBUG && renderState.mScrapList == null) {
throw new RuntimeException("received null view when unexpected");
// if we are laying out views in scrap, this may return null which means there is
// no more items to layout.
RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) view.getLayoutParams();
if (!params.isItemRemoved() && mRenderState.mScrapList == null) {
if (mShouldReverseLayout == (renderState.mLayoutDirection
== RenderState.LAYOUT_START)) {
addView(view);
addView(view, 0);
if (mOrientation == VERTICAL) {
params.width = itemWidth - params.leftMargin - params.rightM
params.height = itemWidth - params.topMargin - params.bottomM
measureChildWithMargins(view, 0, 0);
int consumed = mOrientationHelper.getDecoratedMeasurement(view);
int left, top, right,
if (mOrientation == VERTICAL) {
if (isLayoutRTL() == (renderState.mLayoutDirection
== RenderState.LAYOUT_END)) {
right = getWidth() - getPaddingRight() - itemWidth * columnC
left = right - mOrientationHelper.getDecoratedMeasurementInOther(view);
left = columnCount * itemWidth + getPaddingLeft();
right = left + mOrientationHelper.getDecoratedMeasurementInOther(view);
if (renderState.mLayoutDirection == RenderState.LAYOUT_START) {
bottom = renderState.mO
top = renderState.mOffset -
top = renderState.mO
bottom = renderState.mOffset +
if (renderState.mLayoutDirection == RenderState.LAYOUT_START) {
bottom = getHeight() - getPaddingBottom() - itemWidth * columnC
top = bottom - mOrientationHelper.getDecoratedMeasurementInOther(view);
right = renderState.mO
left = renderState.mOffset -
top = columnCount * itemWidth + getPaddingTop();
bottom = top + mOrientationHelper.getDecoratedMeasurementInOther(view);
left = renderState.mO
right = renderState.mOffset +
// We calculate everything with View's bounding box (which includes decor and margins)
// To calculate correct layout position, we subtract margins.
layoutDecorated(view, left + params.leftMargin, top + params.topMargin
, right - params.rightMargin, bottom - params.bottomMargin);
if (DEBUG) {
Log.d(TAG, "laid out child at position " + getPosition(view) + ", with l:"
+ (left + params.leftMargin) + ", t:" + (top + params.topMargin) + ", r:"
+ (right - params.rightMargin) + ", b:" + (bottom - params.bottomMargin));
if (!params.isItemRemoved()) {
columnCount++;
if (columnCount == columns) {
columnCount = 0;
renderState.mOffset += consumed * renderState.mLayoutD
renderState.mAvailable -=
// we keep a separate remaining space because mAvailable is important for recycling
remainingSpace -=
if (renderState.mScrollingOffset != RenderState.SCOLLING_OFFSET_NaN) {
renderState.mScrollingOffset +=
if (renderState.mAvailable & 0) {
renderState.mScrollingOffset += renderState.mA
recycleByRenderState(recycler, renderState);
if (stopOnFocusable && view.isFocusable()) {
if (state != null && state.getTargetScrollPosition() == getPosition(view)) {
if (DEBUG) {
validateChildOrder();
return start - renderState.mA
Java Source Code List
&|&Email:info &|&& Demo Source and Support. All rights reserved.android recyclerview linearlayoutmanager必须要设置吗_百度知道
android recyclerview linearlayoutmanager必须要设置吗
getTop()==0 && lm用LayoutManager判断RecyclerView rc=(RecyclerView) if(lm.findFirstVisibleItemPosition()==0) return true.findViewByPosition(lm.findFirstVisibleItemPosition()); LinearLayoutManager lm= (LinearLayoutManager) rc.getLayoutManager()
其他类似问题
为您推荐:
android的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁

我要回帖

更多关于 recyclerview manager 的文章

 

随机推荐