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
- RecyclerView的使用、res下新建菜单menu-main.xml
- Menu 菜单的使用
- Menu菜单的使用
- 菜单的使用Menu
- menu菜单的使用
- Menu菜单的使用
- android开发之res下的menu (xml+代码的形式)
- 新建 一个android工程,res/layout 下的xml布局文件无法预览
- 在Android Studio中的res文件夹下新建含alpha的XML文件
- Android菜单的使用Menu
- android Menu菜单的使用
- Menu 选项菜单的使用
- Android Menu菜单的使用
- 19.菜单Menu的使用
- “新建安卓工程时,src与res目录下没有自动生成的.java和.xml文件“的解决
- \res\menu\main.xml:3: error: Error: No resource found that matches the given name (at 'title' with
- apktool反编译res下的XML
- 关于asp的工具条 使用xml作为数据源,配合asp:Menu类自由扩展菜单项
- Linux--多进程拷贝一个文件
- 转载待修改-压缩感知--1
- HTML学习笔记(五)--表单
- 轻松实现iOS9多任务管理器效果(iCarousel高级教程)
- 今天的任务 复习数据库 然后写一下面向对象的代码(图书馆租书系统)
- RecyclerView的使用、res下新建菜单menu-main.xml
- Slim使用详解
- 团体程序设计天梯赛L2-008 最长对称子串
- 第二章 线性表
- Spark RPC之Netty启动
- Pigeon发布流程
- JavaScript读取XML文件
- 【面试题】剑指offer 7
- shell脚本之-if流程控制语句和for循环语句的使用