RecyclerView(ScrollView嵌套,添加HeardView、FootView)
来源:互联网 发布:任务管理工具 知乎 编辑:程序博客网 时间:2024/05/18 10:51
ScrollView里面嵌套RecylerView
我们的recyclerView有多个layoutmanager,通过重写layoutmanager的方法就可以让recyclerView和ScrollView嵌套了在应用的时候 recyclerView.setNestedScrollingEnabled(false);//让RecyclerView不可以滑动
LinearLayoutManager和ScrollView嵌套
public class FullyLinearLayoutManager extends LinearLayoutManager { private static final String TAG = FullyLinearLayoutManager.class.getSimpleName(); public FullyLinearLayoutManager(Context context) { super(context); } public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { super(context, orientation, reverseLayout); } private int[] mMeasuredDimension = new int[2]; @Override public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode + " \nheightMode " + heightSpec + " \nwidthSize " + widthSize + " \nheightSize " + heightSize + " \ngetItemCount() " + getItemCount()); int width = 0; int height = 0; for (int i = 0; i < getItemCount(); i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { width = width + mMeasuredDimension[0]; if (i == 0) { height = mMeasuredDimension[1]; } } else { height = height + mMeasuredDimension[1]; if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height); } private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { try { View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } finally { } }}
GridLayoutManager和ScrollView进行嵌套
public class FullyGridLayoutManager extends GridLayoutManager {public FullyGridLayoutManager(Context context, int spanCount) { super(context, spanCount);}public FullyGridLayoutManager(Context context, int spanCount, int orientation, boolean reverseLayout) { super(context, spanCount, orientation, reverseLayout);}private int[] mMeasuredDimension = new int[2];@Overridepublic void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { final int widthMode = View.MeasureSpec.getMode(widthSpec); final int heightMode = View.MeasureSpec.getMode(heightSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); int width = 0; int height = 0; int count = getItemCount(); int span = getSpanCount(); for (int i = 0; i < count; i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), mMeasuredDimension); if (getOrientation() == HORIZONTAL) { if (i % span == 0) { width = width + mMeasuredDimension[0]; } if (i == 0) { height = mMeasuredDimension[1]; } } else { if (i % span == 0) { height = height + mMeasuredDimension[1]; } if (i == 0) { width = mMeasuredDimension[0]; } } } switch (widthMode) { case View.MeasureSpec.EXACTLY: width = widthSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } switch (heightMode) { case View.MeasureSpec.EXACTLY: height = heightSize; case View.MeasureSpec.AT_MOST: case View.MeasureSpec.UNSPECIFIED: } setMeasuredDimension(width, height);}private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { if (position < getItemCount()) { try { View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), p.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), p.height); view.measure(childWidthSpec, childHeightSpec); measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } } }}
StaggeredGridLayoutManager和ScrollView进行嵌套
public class ExStaggeredGridLayoutManager extends StaggeredGridLayoutManager {public ExStaggeredGridLayoutManager(int spanCount, int orientation) { super(spanCount, orientation);}// 尺寸的数组,[0]是宽,[1]是高private int[] measuredDimension = new int[2];// 用来比较同行/列那个item罪宽/高private int[] dimension;@Overridepublic void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) { // 宽的mode+size final int widthMode = View.MeasureSpec.getMode(widthSpec); final int widthSize = View.MeasureSpec.getSize(widthSpec); // 高的mode + size final int heightMode = View.MeasureSpec.getMode(heightSpec); final int heightSize = View.MeasureSpec.getSize(heightSpec); // 自身宽高的初始值 int width = 0; int height = 0; // item的数目 int count = getItemCount(); // item的列数 int span = getSpanCount(); // 根据行数或列数来创建数组 dimension = new int[span]; for (int i = 0; i < count; i++) { measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED), measuredDimension); // 如果是竖直的列表,计算item的高,否则计算宽度 //Log.d("LISTENER", "position " + i + " height = " + measuredDimension[1]); if (getOrientation() == VERTICAL) { dimension[findMinIndex(dimension)] += measuredDimension[1]; } else { dimension[findMinIndex(dimension)] += measuredDimension[0]; } } if (getOrientation() == VERTICAL) { height = findMax(dimension); } else { width = findMax(dimension); } switch (widthMode) { // 当控件宽是match_parent时,宽度就是父控件的宽度 case View.MeasureSpec.EXACTLY: width = widthSize; break; case View.MeasureSpec.AT_MOST: break; case View.MeasureSpec.UNSPECIFIED: break; } switch (heightMode) { // 当控件高是match_parent时,高度就是父控件的高度 case View.MeasureSpec.EXACTLY: height = heightSize; break; case View.MeasureSpec.AT_MOST: break; case View.MeasureSpec.UNSPECIFIED: break; } // 设置测量尺寸 setMeasuredDimension(width, height);}private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec, int heightSpec, int[] measuredDimension) { // 挨个遍历所有item if (position < getItemCount()) { try { View view = recycler.getViewForPosition(position);//fix 动态添加时报IndexOutOfBoundsException if (view != null) { RecyclerView.LayoutParams lp = (RecyclerView.LayoutParams) view.getLayoutParams(); int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec, getPaddingLeft() + getPaddingRight(), lp.width); int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec, getPaddingTop() + getPaddingBottom(), lp.height); // 子view进行测量,然后可以通过getMeasuredWidth()获得测量的宽,高类似 view.measure(childWidthSpec, childHeightSpec); // 将item的宽高放入数组中 measuredDimension[0] = view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin; measuredDimension[1] = view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin; recycler.recycleView(view); } } catch (Exception e) { e.printStackTrace(); } }}private int findMax(int[] array) { int max = array[0]; for (int value : array) { if (value > max) { max = value; } } return max;}/** * 得到最数组中最小元素的下标 * * @param array * @return */ private int findMinIndex(int[] array) { int index = 0; int min = array[0]; for (int i = 0; i < array.length; i++) { if (array[i] < min) { min = array[i]; index = i; } } return index; }}
RecyclerView添加heardView和footView
RecyclerView实现添加HeaderView和FooterView的核心就是在Adapter里面的onCreateViewHolder根据viewType来判断是列表项还是HeaderView来分别加载不同的布局文件,当然viewType的判断规则也是由我们定义的
adapter
package com.example.administrator.mystudydemo.adapter;import android.content.Context;import android.support.v7.widget.RecyclerView;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;import com.example.administrator.mystudydemo.R;/** * Created by Administrator on 2017/5/4. */public class HeaderBottomAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { //item类型 public static final int ITEM_TYPE_HEADER = 0; public static final int ITEM_TYPE_CONTENT = 1; public static final int ITEM_TYPE_BOTTOM = 2; //模拟数据 public String[] texts = {"java", "python", "C++", "Php", ".NET", "js", "Ruby", "Swift", "OC"}; private LayoutInflater mLayoutInflater; private Context mContext; private int mHeaderCount = 1; //头部View个数 private int mBottomCount = 1; //底部View个数 public HeaderBottomAdapter(Context context) { mContext = context; mLayoutInflater = LayoutInflater.from(context); } //内容长度 public int getContentItemCount() { return texts.length; } //判断当前item是否是HeadView public boolean isHeaderView(int position) { return mHeaderCount != 0 && position < mHeaderCount; } //判断当前item是否是FooterView public boolean isBottomView(int position) { return mBottomCount != 0 && position >= (mHeaderCount + getContentItemCount()); } //判断当前item类型 @Override public int getItemViewType(int position) { int dataItemCount = getContentItemCount(); if (mHeaderCount != 0 && position < mHeaderCount) { //头部View return ITEM_TYPE_HEADER; } else if (mBottomCount != 0 && position >= (mHeaderCount + dataItemCount)) { //底部View return ITEM_TYPE_BOTTOM; } else { //内容View return ITEM_TYPE_CONTENT; } } //内容 ViewHolder public static class ContentViewHolder extends RecyclerView.ViewHolder { private TextView textView; public ContentViewHolder(View itemView) { super(itemView); textView = (TextView) itemView.findViewById(R.id.tv_item_text); } } //头部 ViewHolder public static class HeaderViewHolder extends RecyclerView.ViewHolder { public HeaderViewHolder(View itemView) { super(itemView); } } //底部 ViewHolder public static class BottomViewHolder extends RecyclerView.ViewHolder { public BottomViewHolder(View itemView) { super(itemView); } } @Override public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == ITEM_TYPE_HEADER) { return new HeaderViewHolder(mLayoutInflater.inflate(R.layout.rv_header, parent, false)); } else if (viewType == mHeaderCount) { return new ContentViewHolder(mLayoutInflater.inflate(R.layout.rv_item, parent, false)); } else if (viewType == ITEM_TYPE_BOTTOM) { return new BottomViewHolder(mLayoutInflater.inflate(R.layout.rv_footer, parent, false)); } return null; } @Override public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) { if (holder instanceof HeaderViewHolder) { } else if (holder instanceof ContentViewHolder) { ((ContentViewHolder) holder).textView.setText(texts[position - mHeaderCount]); } else if (holder instanceof BottomViewHolder) { } } @Override public int getItemCount() { return mHeaderCount + getContentItemCount() + mBottomCount; } }
应用
recyclerView= (RecyclerView) findViewById(R.id.rv_hf); adapter = new HeaderBottomAdapter(HFActivity.this); //布局是GridLayoutManager的时候 需要判断布局 /*gridLayoutManager = new GridLayoutManager(HFActivity.this,3); gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { return (adapter.isHeaderView(position) || adapter.isBottomView(position)) ? gridLayoutManager.getSpanCount() : 1; } }); recyclerView.setLayoutManager(gridLayoutManager);*/ //布局是LinerLayoutManager直接应用就好 recyclerView.setLayoutManager(new LinearLayoutManager(HFActivity.this)); recyclerView.setAdapter(adapter);
效果图
0 0
- RecyclerView(ScrollView嵌套,添加HeardView、FootView)
- RecyclerView添加headerview和footview
- 为RecyclerView添加FootView和HeadView
- ScrollView嵌套RecyclerView
- ScrollView嵌套recyclerView问题
- android ScrollView嵌套RecyclerView
- Scrollview 嵌套 RecyclerView
- scrollview嵌套recyclerview 问题
- scrollview嵌套recyclerview
- ScrollView嵌套RecyclerView 问题
- RecyclerView和ScrollView嵌套
- android ScrollView嵌套RecyclerView
- RecyclerView嵌套问题ScrollView
- ScrollView嵌套RecyclerView
- ScrollView嵌套recyclerView问题
- Scrollview嵌套RecyclerView
- RecyclerView 与 ScrollView嵌套
- ScrollView嵌套recyclerView问题
- 【闭包概念】关于闭包概念各路神仙的不同解读——你可以自己理解。
- Grid(规律)
- Android开发:最全面、最易懂的Android屏幕适配解决方案
- linux编程基础:使用socketpair实现双向通讯
- Eclipse Maven建web项目 与SSM三大框架整合教程(Spring+SpringMVC+MyBatis)
- RecyclerView(ScrollView嵌套,添加HeardView、FootView)
- GitHub托管Android项目的多人开发
- Oracle解析复杂json的方法
- 剑指offer 33. 把数组排成最小的数
- javaSE_8系列博客——Java语言的特性(三)--类和对象(6)--为你的类提供构造函数
- 【SSM】Eclipse使用Maven创建Web项目+整合SSM框架
- UE4 加速Setup.bat
- mybatis传多个参数
- linux命令之vimdiff