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
原创粉丝点击