RecyclerView的使用、res下新建菜单menu-main.xml
2017-03-01 18:07
501 查看
1.参考链接:Android RecyclerView 使用完全解析 体验艺术般的控件
2.使用RecyclerView需要导入support v7包:
在build.gradle(app)中设置:(和AndroidStudio设置的一样就行了,哈哈)
3.疑问:瀑布流中添加分割线操作?
4.代码如下:
MainActivity:
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>
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 setOrien da66 tation(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>
相关文章推荐
- [一个星期自学安卓]使用xml加载菜单Menu
- 使用ActionManager, ActionMainMenuBar, ActionToolBar制作菜单
- Andriod ADT v22.6.2版本中在Mainactivity.java中使用fragment_main.xml中TextView控件对象的问题
- C#winform使用XML绑定toolStripMenuItem生成菜单
- 使用RecyclerView获取xml数据(csdn的数据)并解析展示(二)
- 【起航计划 023】2015 起航计划 Android APIDemo的魔鬼步伐 22 App->Menu->Inflate from XML 使用xml资源展示菜单
- RecyclerView进阶使用-实现仿支付宝菜单编辑页面拖拽功能
- 最强RecyclerView,Item侧滑菜单,长按拖拽Item,滑动删除Item。可以和任何下拉刷新框架结合使用
- How to create custom navigation menu in SharePoint with XML data source 使用XML数据源在SharePoint创建自定义导航菜单
- Android学习之menu菜单使用与用户自定义View
- AndroidStudio下使用 RecyclerView xml文件不显示预览条目并报错类似:NoClassDefFoundError 问题解决
- 手势检测实现相册的左右滑动(并加上移动与旋转的特效) 首先,activity_main.xml里,使用ViewFlipper组件(可使用动画控制多个组件之间的切换效果) <?xml version="
- \res\menu\main.xml:3: error: Error: No resource found that matches the given name (at 'title' with
- 使用少量代码实现自己的RecyclerView侧滑菜单
- 【起航计划 023】2015 起航计划 Android APIDemo的魔鬼步伐 22 App-&gt;Menu-&gt;Inflate from XML 使用xml资源展示菜单
- res\menu\main.xml:6: error: No resource identifier found for attribute 'showAsAction' in package 'com.xxx.xxxx'
- How to create custom navigation menu in SharePoint with XML data source 使用XML数据源在SharePoint创建自定义导航菜单
- 使用xml作为数据源,配合asp:Menu类自由扩展菜单项
- Android开发——使用高级的RecyclerView实现侧滑菜单删除功能(SwipeRecyclerView)
- ActionMainMenuBar使用XPColorMap定义颜色