RecyclerView的使用、res下新建菜单menu-main.xml

来源:互联网 发布:淘宝开零食店赚钱吗 编辑:程序博客网 时间:2024/05/22 17:41

1.参考链接:Android RecyclerView 使用完全解析 体验艺术般的控件

2.使用RecyclerView需要导入support v7包:

在build.gradle(app)中设置:(和AndroidStudio设置的一样就行了,哈哈)

compile 'com.android.support:recyclerview-v7:25.1.0'

3.疑问:瀑布流中添加分割线操作?

4.代码如下:

MainActivity:

package com.ruru.recyclerview;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.support.v7.widget.DefaultItemAnimator;import android.support.v7.widget.GridLayoutManager;import android.support.v7.widget.LinearLayoutManager;import android.support.v7.widget.RecyclerView;import android.support.v7.widget.StaggeredGridLayoutManager;import android.view.Menu;import android.view.MenuItem;import com.ruru.recyclerview.adapter.DividerGridItemDecoration;import com.ruru.recyclerview.adapter.DividerItemDecoration;import com.ruru.recyclerview.adapter.MyAdapter;import java.util.ArrayList;import java.util.List;/** * RecycleView-回收与复用View 高度解耦 给予充分定制自由 */public class MainActivity extends AppCompatActivity {    //打印log语句    public static final String TAG = "info";    //UI控件    private RecyclerView recycleView;    //ListView集合    private List<String> list;    private MyAdapter mAdapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //初始化控件        initView();        //初始化list集合        initData();        //初始化布局        initLayout();    }    /**     * 初始化RecycleView的布局     */    private void initLayout() {        /*设置布局        RecyclerView.LayoutManager是一个抽象类 系统实现了三个实现类        LinearLayoutManager 现行管理器,支持横向、纵向。        GridLayoutManager 网格布局管理器        StaggeredGridLayoutManager 瀑布就式布局管理器*/        //ListView//        recycleView.setLayoutManager(new LinearLayoutManager(this));//        recycleView.setAdapter(new MyAdapter(this, list));        //当我们调用recycleView.addItemDecoration()方法添加decoration的时候,RecycleView在绘制的时候,        // 会去绘制decorator,即调用该类的onDraw()和onDrawOver()方法//        recycleView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));        //GridView//        recycleView.setLayoutManager(new GridLayoutManager(this,4));//        recycleView.setAdapter(new MyAdapter(this, list));//        recycleView.addItemDecoration(new DividerGridItemDecoration(this));        // 瀑布流StaggeredGridLayoutManager        // 第二个参数传一个orientation,        // 如果传入的是StaggeredGridLayoutManager.VERTICAL代表有多少列;注:固定列上下混动        // 如果传入的是StaggeredGridLayoutManager.HORIZONTAL就代表有多少行;注:固定行的话可能会左右滑动        //如果是横向的时候,item的宽度需要注意去设置,毕竟横向的宽度没有约束了,应为控件可以横向滚动了        recycleView.setLayoutManager(new StaggeredGridLayoutManager(4, StaggeredGridLayoutManager.VERTICAL));        mAdapter = new MyAdapter(this, list);        recycleView.setAdapter(mAdapter);        // 设置item动画        recycleView.setItemAnimator(new DefaultItemAnimator());    }    /**     * 初始化list集合数据     */    private void initData() {        list = new ArrayList<String>();        for (int i = 1; i < 10; i++) {            list.add("序号" + i);        }    }    /**     * 初始化控件     */    private void initView() {        recycleView = (RecyclerView) findViewById(R.id.recycleView);    }    /**     * Activity中点击MenuItem触发     * 注意,这里更新数据集不是用adapter.notifyDataSetChanged()     * 而是notifyItemInserted(position)与notifyItemRemoved(position)     */    @Override    public boolean onCreateOptionsMenu(Menu menu)    {        getMenuInflater().inflate(R.menu.main, menu);        return super.onCreateOptionsMenu(menu);    }    /**     * Activity中点击MenuItem触发     */    @Override    public boolean onOptionsItemSelected(MenuItem item) {        switch (item.getItemId()) {            case R.id.id_action_add:                mAdapter.addData(1);                break;            case R.id.id_action_delete:                mAdapter.removeData(1);                break;        }        return true;    }}
MyAdapter:

package com.ruru.recyclerview.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.ruru.recyclerview.R;import java.util.List;/** * Created by SophieLiang on 2017/2/28. *///注意要加后面的<MyAdapter.MyViewHolder>public class MyAdapter extends RecyclerView.Adapter<MyAdapter.MyViewHolder> {    private Context context;    private List<String> list;    public MyAdapter(Context context, List<String> list) {        this.context = context;        this.list = list;    }    @Override    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        MyViewHolder holder = new MyViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));        return holder;    }    @Override    public void onBindViewHolder(MyViewHolder holder, int position) {        holder.tv_name.setText(list.get(position));        //如果是瀑布流的话,为item设计个随机的高度    }    @Override    public int getItemCount() {        return list.size();    }    class MyViewHolder extends RecyclerView.ViewHolder {        TextView tv_name;//不要写成private static        public MyViewHolder(View itemView) {            super(itemView);            tv_name = (TextView) itemView.findViewById(R.id.tv_name);        }    }    /**     * 添加动画更新数据集     */    public void addData(int position) {        list.add(position, "Insert One");        notifyItemInserted(position);    }    /**     * 删除动画更新数据集     */    public void removeData(int position) {        list.remove(position);        notifyItemRemoved(position);    }}
ItemDecoration:

package com.ruru.recyclerview;import android.graphics.Canvas;import android.graphics.Rect;import android.support.v7.widget.RecyclerView;import android.view.View;/** * Created by SophieLiang on 2017/2/28. */public abstract class ItemDecoration {    //onDraw方法先于drawChildren    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        onDraw(c, parent, state);    }    //onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {        onDrawOver(c, parent, state);    }    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {        getItemOffsets(outRect, ((RecyclerView.LayoutParams) view.getLayoutParams()).getViewLayoutPosition(),                parent);    }    //getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,主要用于绘制Decorator。    @Deprecated    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {        outRect.set(0, 0, 0, 0);    }}
DividerItemDecoration:ListView添加分割线的操作

/** * Created by SophieLiang on 2017/2/28. * 添加分割线操作 */public class DividerItemDecoration extends RecyclerView.ItemDecoration {    private static final String TAG = "info";    /**     * 通过读取系统主题中的 Android.R.attr.listDivider作为Item间的分割线,并且支持横向和纵向     */    private static final int[] ATTRS = new int[]{            android.R.attr.listDivider    };    //定义了两个方法中的orientation    public static final int HORIZONTAL_LIST = LinearLayoutManager.HORIZONTAL;    public static final int VERTICAL_LIST = LinearLayoutManager.VERTICAL;    //获取到listDivider以后,该属性的值是个Drawable    private Drawable mDivider;    private int mOrientation;    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 = orientation;    }    /**     * 画分割线:一个item只有一个children     */    @Override    public void onDraw(Canvas c, RecyclerView parent) {        Log.i(TAG, "onDraw:+++ ");        if (mOrientation == VERTICAL_LIST) {            drawVertical(c, parent);        } else {            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 < childCount; 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.bottomMargin;            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 < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    /**     * 在getItemOffsets中,outRect去设置了绘制的范围。onDraw中实现了真正的绘制     */    @Override    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {        if (mOrientation == VERTICAL_LIST) {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        }    }}
DividerGridItemDecoration: GridView添加分割线的操作
public class DividerGridItemDecoration extends RecyclerView.ItemDecoration {    private static final int[] ATTRS = new int[]{android.R.attr.listDivider};    private Drawable mDivider;    public DividerGridItemDecoration(Context context) {        final TypedArray a = context.obtainStyledAttributes(ATTRS);        mDivider = a.getDrawable(0);        a.recycle();    }    @Override    public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {        drawHorizontal(c, parent);        drawVertical(c, parent);    }    private int getSpanCount(RecyclerView parent) {        // 列数        int spanCount = -1;        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            spanCount = ((StaggeredGridLayoutManager) layoutManager)                    .getSpanCount();        }        return spanCount;    }    public void drawHorizontal(Canvas c, RecyclerView parent) {        int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int left = child.getLeft() - params.leftMargin;            final int right = child.getRight() + params.rightMargin                    + mDivider.getIntrinsicWidth();            final int top = child.getBottom() + params.bottomMargin;            final int bottom = top + mDivider.getIntrinsicHeight();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    public void drawVertical(Canvas c, RecyclerView parent) {        final int childCount = parent.getChildCount();        for (int i = 0; i < childCount; i++) {            final View child = parent.getChildAt(i);            final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child                    .getLayoutParams();            final int top = child.getTop() - params.topMargin;            final int bottom = child.getBottom() + params.bottomMargin;            final int left = child.getRight() + params.rightMargin;            final int right = left + mDivider.getIntrinsicWidth();            mDivider.setBounds(left, top, right, bottom);            mDivider.draw(c);        }    }    private boolean isLastColum(RecyclerView parent, int pos, int spanCount, int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边            {                return true;            }        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                if ((pos + 1) % spanCount == 0)// 如果是最后一列,则不需要绘制右边                {                    return true;                }            } else {                childCount = childCount - childCount % spanCount;                if (pos >= childCount)// 如果是最后一列,则不需要绘制右边                    return true;            }        }        return false;    }    private boolean isLastRaw(RecyclerView parent, int pos, int spanCount,                              int childCount) {        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();        if (layoutManager instanceof GridLayoutManager) {            childCount = childCount - childCount % spanCount;            if (pos >= childCount)// 如果是最后一行,则不需要绘制底部                return true;        } else if (layoutManager instanceof StaggeredGridLayoutManager) {            int orientation = ((StaggeredGridLayoutManager) layoutManager)                    .getOrientation();            // StaggeredGridLayoutManager 且纵向滚动            if (orientation == StaggeredGridLayoutManager.VERTICAL) {                childCount = childCount - childCount % spanCount;                // 如果是最后一行,则不需要绘制底部                if (pos >= childCount)                    return true;            } else            // StaggeredGridLayoutManager 且横向滚动            {                // 如果是最后一行,则不需要绘制底部                if ((pos + 1) % spanCount == 0) {                    return true;                }            }        }        return false;    }    /**     * 主要在getItemOffsets方法中,去判断如果是最后一行,则不需要绘制底部;如果是最后一列,则不需要绘制右边,     * 整个判断也考虑到了StaggeredGridLayoutManager的横向和纵向     * 一般如果仅仅是希望有空隙,还是去设置item的margin方便     */    @Override    public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {        int spanCount = getSpanCount(parent);        int childCount = parent.getAdapter().getItemCount();        if (isLastRaw(parent, itemPosition, spanCount, childCount))// 如果是最后一行,则不需要绘制底部        {            outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);        } else if (isLastColum(parent, itemPosition, spanCount, childCount))// 如果是最后一列,则不需要绘制右边        {            outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());        } else {            outRect.set(0, 0, mDivider.getIntrinsicWidth(),                    mDivider.getIntrinsicHeight());        }    }}
divider_bg.xml:设置分割线的背景颜色

<?xml version="1.0" encoding="utf-8"?><shape xmlns:android="http://schemas.android.com/apk/res/android"    android:shape="rectangle">    <gradient        android:centerColor="#ff00ff00"        android:endColor="#ff0000ff"        android:startColor="#ffff0000"        android:type="linear" />    <size android:height="4dp" /></shape>
res右键第二个新建menu目录,再新建xml文件:main.xml

<?xml version="1.0" encoding="utf-8"?><menu xmlns:android="http://schemas.android.com/apk/res/android">    <item        android:id="@+id/id_action_add"        android:title="添加动画"/>    <item        android:id="@+id/id_action_delete"        android:title="删除动画"/></menu>
activity_main.xml:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:id="@+id/activity_main"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="com.ruru.recyclerview.MainActivity">    <!--RecycleView中divider这样的属性不会起作用-->    <android.support.v7.widget.RecyclerView        android:id="@+id/recycleView"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:divider="#ffff0000"        android:dividerHeight="10dp"></android.support.v7.widget.RecyclerView></RelativeLayout>

item.xml:ListView有一个item,GridView有好多个ChildView

<?xml version="1.0" encoding="utf-8"?><FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="50dp"    android:background="#44ff0000">    <TextView        android:id="@+id/tv_name"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:gravity="center" /></FrameLayout>












0 0
原创粉丝点击