00-Unit_Common综述-RecyclerView封装
1 package top.toly.www.unit_common.bean; 2 3 /** 4 * 作者:张风捷特烈 5 * 时间:2018/4/10:14:55 6 * 邮箱:1981462002@qq.com 7 * 说明:每个界面的bean对象 图片+名称 8 */ 9 public class ItemBean { 10 11 private String name; 12 private int ResId; 13 14 public ItemBean(String name, int resId) { 15 this.name = name; 16 ResId = resId; 17 } 18 19 public String getName() { 20 return name; 21 } 22 23 public void setName(String name) { 24 this.name = name; 25 } 26 27 public int getResId() { 28 return ResId; 29 } 30 31 public void setResId(int resId) { 32 ResId = resId; 33 } 34 }
1 注:笔者为避免寻找id的麻烦,使用了ButterKnife 2 依赖:implementation 'com.jakewharton:butterknife:7.0.1' 3 混淆:#butterknife 4 -keep class butterknife.** { *; } 5 -dontwarn butterknife.internal.** 6 -keep class **$$ViewBinder { *; } 7 -keepclasseswithmembernames class * { 8 @butterknife.* <fields>; 9 } 10 -keepclasseswithmembernames class * { 11 @butterknife.* <methods>; 12 }
1 package top.toly.www.unit_common.home; 2 3 import android.content.Intent; 4 import android.os.Bundle; 5 import android.support.v7.app.AppCompatActivity; 6 import android.support.v7.widget.RecyclerView; 7 import android.view.View; 8 9 import java.util.ArrayList; 10 import java.util.List; 11 12 import butterknife.Bind; 13 import butterknife.ButterKnife; 14 import top.toly.www.unit_common.R; 15 import top.toly.www.unit_common.activity.MainActivity; 16 import top.toly.www.unit_common.bean.ItemBean; 17 import utils.ev.recyclerview.MyRVAdapter; 18 import utils.ev.recyclerview.MyRVHolder; 19 import utils.ui.UIUtils; 20 21 public class Activity_Home_RV extends AppCompatActivity { 22 23 @Bind(R.id.recyclerview) 24 RecyclerView mRecyclerview; 25 private List<ItemBean> mItems;//itemBean的集合 26 27 @Override 28 protected void onCreate(Bundle savedInstanceState) { 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.activity_home_rv); 31 ButterKnife.bind(this); 32 33 setItemsData();//为item设置数据 34 initRV();//初始化RecyclerView 35 36 } 37 38 private void initRV() { 39 // 注:笔者已对RecyclerView进行封装,以下几行就搞定RecyclerView的简单使用,封装代码见下 40 UIUtils.setStyle4RV(mRecyclerview, 3, UIUtils.GRIDVIEW, this);//设置类型 41 MyRVAdapter<ItemBean> rvAdapter = new MyRVAdapter<ItemBean>(mItems, R.layout.rv_item_home) { 42 @Override 43 public void setDatas(MyRVHolder holder, ItemBean data, int position) { 44 holder.setText(R.id.tv_title, data.getName()) 45 .setImageViewRes(R.id.iv_icon, data.getResId()); 46 } 47 }; 48 49 mRecyclerview.setAdapter(rvAdapter); 50 rvAdapter.setOnRvItemClickListener(new MyRVAdapter.OnRvItemClickListener() { 51 @Override 52 public void OnRvItemClick(View v, int pos) { 53 switch (pos) { 54 case 0: 55 startActivity(new Intent(Activity_Home_RV.this, MainActivity.class)); 56 break; 57 } 58 } 59 }); 60 } 61 62 /** 63 * 为item设置数据 64 * 65 * @return 66 */ 67 68 public List<ItemBean> setItemsData() { 69 mItems = new ArrayList<>(); 70 mItems.add(new ItemBean("test", R.drawable.ic_launcher_background)); 71 mItems.add(new ItemBean("test1", R.drawable.ic_launcher_background)); 72 return mItems; 73 } 74 75 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 xmlns:tools="http://schemas.android.com/tools" 5 android:layout_width="match_parent" 6 android:layout_height="match_parent"> 7 8 <android.support.v7.widget.RecyclerView 9 android:id="@+id/recyclerview" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content"/> 12 13 </RelativeLayout>
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="match_parent" 4 android:layout_height="wrap_content" 5 android:padding="5dp"> 6 7 <ImageView 8 android:id="@+id/iv_icon" 9 android:layout_width="50dp" 10 android:layout_height="50dp" 11 android:src="@drawable/ic_launcher_background" /> 12 13 <TextView 14 android:id="@+id/tv_title" 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:layout_marginLeft="3dp" 18 android:layout_toRightOf="@+id/iv_icon" 19 android:layout_centerInParent="true" 20 android:text="Content" 21 android:textAllCaps="false" 22 android:textColor="#000000" /> 23 </RelativeLayout>
package utils.ev.recyclerview; import android.graphics.Bitmap; import android.support.v7.widget.RecyclerView; import android.util.SparseArray; import android.view.View; import android.widget.ImageView; import android.widget.TextView; import com.bumptech.glide.Glide; import com.bumptech.glide.load.engine.DiskCacheStrategy; import utils.ui.UIUtils; /** * 作者:张风捷特烈 * 时间:2018/4/10:14:22 * 邮箱:1981462002@qq.com * 说明:View的持有人 */ public class MyRVHolder extends RecyclerView.ViewHolder { //键值对中键是int类型使用SparseArray比map更好 private SparseArray<View> mViews;//持有的所有View集合 private View mItemView;//Item的 public MyRVHolder(View itemView) { super(itemView); mItemView = itemView; mViews = new SparseArray<>(); } /** * 获取pos * * @return */ public int getPos() { return this.getLayoutPosition(); } /** * 通过viewId获取控件 * * @param viewId * @param <T> * @return */ public <T extends View> T getView(int viewId) { View view = mViews.get(viewId); if (view == null) { view = mItemView.findViewById(viewId); mViews.put(viewId, view);//以id为键,view为值 } return (T) view; } public View getItemView() { return mItemView; } /** * 设置item背景颜色 */ public MyRVHolder setColor(int color) { mItemView.setBackgroundColor(color); return this; } /** * 设置TextView文本方法 * * @param viewId * @param text * @return */ public MyRVHolder setText(int viewId, String text) { TextView view = getView(viewId); view.setText(text); return this; } /** * 通过资源id设置ImageView图片 * @param viewId * @param resId * @return */ public MyRVHolder setImageViewRes(int viewId, int resId) { ImageView view = getView(viewId); view.setImageResource(resId); return this; } /** * 通过Bitmap设置ImageView图片 * @param viewId * @param bitmap * @return */ public MyRVHolder setImageViewBitmap(int viewId, Bitmap bitmap) { ImageView view = getView(viewId); view.setImageBitmap(bitmap); return this; } /** * 通过url设置图片 * @param viewId * @param url * @return */ public MyRVHolder setImageViewUrl(int viewId, String url) { ImageView view = getView(viewId); //此处使用Glide进行Url类型图片的加载,如果未添加Glide依赖会报错 //依赖: implementation 'com.github.bumptech.glide:glide:3.7.0' Glide.with(UIUtils.getContext()) .load(url) .skipMemoryCache(false) .diskCacheStrategy(DiskCacheStrategy.SOURCE) .into(view); return this; } /////////////////////可继续拓展完善,添加更多方法////////////////////// }
package utils.ev.recyclerview; import android.support.v7.widget.RecyclerView; import android.view.View; import android.view.ViewGroup; import java.util.List; import utils.ui.UIUtils; /** * 作者:张风捷特烈 * 时间:2018/4/10:14:28 * 邮箱:1981462002@qq.com * 说明:RecyclerView的Adapter封装类 */ public abstract class MyRVAdapter<T> extends RecyclerView.Adapter<MyRVHolder> { protected List<T> mDatas; protected int mItemId; private View mItemView; public MyRVAdapter(List<T> datas, int itemId) { mDatas = datas; mItemId = itemId; } @Override public MyRVHolder onCreateViewHolder(ViewGroup parent, int viewType) { mItemView = UIUtils.inflate(mItemId); final MyRVHolder myRVHolder = new MyRVHolder(mItemView); //点击事件方式 mItemView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) {//使用回调实现点击监听 if (mOnRvItemClickListener != null) { mOnRvItemClickListener.OnRvItemClick(v, myRVHolder.getPos()); } } }); return myRVHolder; } @Override public void onBindViewHolder(MyRVHolder holder, int position) { setDatas(holder, mDatas.get(position), position); } @Override public int getItemCount() { return mDatas.size(); } /** * 抽象方法,通过holder可对各控件进行操作 * * @param holder View的持有人 * @param data 数据 * @param position 点击位置 */ public abstract void setDatas(MyRVHolder holder, T data, int position); /////////////////////////////////////////////////////////// /** * 添加item * * @param i * @param aNew */ public void addData(int i, T aNew) { mDatas.add(i, aNew); notifyItemInserted(i);//刷新数据 } /** * 删除item * * @param i */ public void deleteData(int i) { mDatas.remove(i); notifyItemRemoved(i);//刷新数据 } public View getItemView() { return mItemView; } /////////////////为RecyclerView设置点击监听接口///////////////////////// /** * 为RecyclerView设置点击监听接口 */ public interface OnRvItemClickListener { void OnRvItemClick(View v, int pos);//item被点击的时候回调方法 } /** * 声明监听器接口对象 */ private OnRvItemClickListener mOnRvItemClickListener; /** * 设置RecyclerView某个的监听方法 * * @param onRvItemClickListener */ public void setOnRvItemClickListener(OnRvItemClickListener onRvItemClickListener) { mOnRvItemClickListener = onRvItemClickListener; } }
这样可以使用了,不过为了添加分割线,还有免去写一些初始化的设置方法,把其封装在我的UiUtils中,静态方法如下:
////////////////////////设置RecyclerView///////////////////////////////////////// public static final int GRIDVIEW = 0; public static final int LISTVIEW = 1; public static final int PULL = 2; /** * * @param rv RecyclerView * @param count count 数量 LISTVIEW可随意 * @param style 模式 GRIDVIEW LISTVIEW PULL * @param ctx 上下文 */ public static GridLayoutManager setStyle4RV(RecyclerView rv, int count, int style,Context ctx) { switch (style) { case GRIDVIEW://GridView类型 rv.addItemDecoration(new MyDividerItemDecoration(ctx));//设置分割线 GridLayoutManager gridLayoutManager = new GridLayoutManager(getContext(), count, GridLayoutManager.VERTICAL, false); rv.setLayoutManager(gridLayoutManager); return gridLayoutManager; case LISTVIEW://ListView类型 rv.addItemDecoration(new SampleDivider(ctx)); rv.setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false)); return null; case PULL://瀑布流类型 rv.addItemDecoration(new MyDividerItemDecoration(ctx)); rv.setLayoutManager(new StaggeredGridLayoutManager(count, StaggeredGridLayoutManager.VERTICAL)); return null; } return null; }
package utils.ev.recyclerview; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.support.v7.widget.GridLayoutManager; import android.support.v7.widget.OrientationHelper; import android.support.v7.widget.RecyclerView; import android.view.View; public class MyDividerItemDecoration extends RecyclerView.ItemDecoration { private static final int[] ATTRS = new int[]{ android.R.attr.listDivider }; /** * 用于绘制间隔样式 */ private Drawable mDivider; public MyDividerItemDecoration(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) { // 绘制间隔,每一个item,绘制右边和下方间隔样式 int childCount = parent.getChildCount(); int spanCount = ((GridLayoutManager)parent.getLayoutManager()).getSpanCount(); int orientation = ((GridLayoutManager)parent.getLayoutManager()).getOrientation(); boolean isDrawHorizontalDivider = true; boolean isDrawVerticalDivider = true; int extra = childCount % spanCount; extra = extra == 0 ? spanCount : extra; for(int i = 0; i < childCount; i++) { isDrawVerticalDivider = true; isDrawHorizontalDivider = true; // 如果是竖直方向,最右边一列不绘制竖直方向的间隔 if(orientation == OrientationHelper.VERTICAL && (i + 1) % spanCount == 0) { isDrawVerticalDivider = false; } // 如果是竖直方向,最后一行不绘制水平方向间隔 if(orientation == OrientationHelper.VERTICAL && i >= childCount - extra) { isDrawHorizontalDivider = false; } // 如果是水平方向,最下面一行不绘制水平方向的间隔 if(orientation == OrientationHelper.HORIZONTAL && (i + 1) % spanCount == 0) { isDrawHorizontalDivider = false; } // 如果是水平方向,最后一列不绘制竖直方向间隔 if(orientation == OrientationHelper.HORIZONTAL && i >= childCount - extra) { isDrawVerticalDivider = false; } if(isDrawHorizontalDivider) { drawHorizontalDivider(c, parent, i); } if(isDrawVerticalDivider) { drawVerticalDivider(c, parent, i); } } } @Override public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) { int spanCount = ((GridLayoutManager) parent.getLayoutManager()).getSpanCount(); int orientation = ((GridLayoutManager)parent.getLayoutManager()).getOrientation(); int position = parent.getChildLayoutPosition(view); if(orientation == OrientationHelper.VERTICAL && (position + 1) % spanCount == 0) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); return; } if(orientation == OrientationHelper.HORIZONTAL && (position + 1) % spanCount == 0) { outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0); return; } outRect.set(0, 0, mDivider.getIntrinsicWidth(), mDivider.getIntrinsicHeight()); } /** * 绘制竖直间隔线 * * @param canvas * @param parent * 父布局,RecyclerView * @param position * irem在父布局中所在的位置 */ private void drawVerticalDivider(Canvas canvas, RecyclerView parent, int position) { final View child = parent.getChildAt(position); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getTop() - params.topMargin; final int bottom = child.getBottom() + params.bottomMargin + mDivider.getIntrinsicHeight(); final int left = child.getRight() + params.rightMargin; final int right = left + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } /** * 绘制水平间隔线 * * @param canvas * @param parent * 父布局,RecyclerView * @param position * item在父布局中所在的位置 */ private void drawHorizontalDivider(Canvas canvas, RecyclerView parent, int position) { final View child = parent.getChildAt(position); final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child .getLayoutParams(); final int top = child.getBottom() + params.bottomMargin; final int bottom = top + mDivider.getIntrinsicHeight(); final int left = child.getLeft() - params.leftMargin; final int right = child.getRight() + params.rightMargin + mDivider.getIntrinsicWidth(); mDivider.setBounds(left, top, right, bottom); mDivider.draw(canvas); } }
00-Unit_Common综述-RecyclerView封装的更多相关文章
- 打造android偷懒神器———RecyclerView的万能适配器
转载请注明出处谢谢:http://www.cnblogs.com/liushilin/p/5720926.html 很不好意思让大家久等了,本来昨天就应该写这个的,无奈公司昨天任务比较紧,所以没能按时 ...
- Android 5.X新特性之RecyclerView基本解析及无限复用
说到RecyclerView,相信大家都不陌生,它是我们经典级ListView的升级版,升级后的RecyclerView展现了极大的灵活性.同时内部直接封装了ViewHolder,不用我们自己定义Vi ...
- 一篇博客理解Recyclerview的使用
从Android 5.0开始,谷歌公司推出了RecylerView控件,当看到RecylerView这个新控件的时候,大部分人会首先发出一个疑问,recylerview是什么?为什么会有recyler ...
- Android开发——RecyclerView特性以及基本使用方法(一)
)关于点击事件,没有像ListView那样现成的API,但是自己封装起来也不难,而且我们使用ListView时,如果item中有可点击组件,那么点击事件的冲突也是一个问题,而在RecyclerView ...
- RecyclerView底部刷新实现具体解释
关于RecyclerView底部刷新实现的文章已经非常多了,但大都仅仅介绍了其基本原理和框架,对当中的非常多细节没有交代,无法直接使用. 本文会着重介绍RecyclerView底部刷新实现的一些细节处 ...
- 从 ListView 到 RecyclerView 的用法浅析
文章目录 要走好明天的路,必须记住昨天走过的路,思索今天正在走着的路. ListView,一种在垂直滚动列表中显示条目的视图:RecyclerView,一种在局限的窗口呈现大数据集合的灵活视图.Rec ...
- RecyclerView 的简单使用
自从 Android 5.0 之后,google 推出了一个 RecyclerView 控件,他是 support-v7 包中的新组件,是一个强大的滑动组件,与经典的 ListView 相比,同样拥有 ...
- colorPrimaryDark无法改变状态栏颜色
设置完colorPrimaryDark后,这个颜色是改变状态栏的颜色的, colorPrimary是改变标题栏背景色的 发现状态栏一直是灰色. 然后在布局文件中 AndroidMainifest.xm ...
- 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高
第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...
随机推荐
- Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(下篇——多页面VueSSR+热更新Server)
Vue 2.x + Webpack 3.x + Nodejs 多页面项目框架(下篇--多页面VueSSR+热更新Server) @(HTML/JS) 这是Vue多页面框架系列文章的第二篇,上一篇(纯前 ...
- Java服务器端生成报告文档:使用SQL Server Report Service(SSRS)
SQL Server Report Service(SSRS)提供了Asp.Net和WinForm两类客户端组件封装,因此使用C#实现SSRS报表的导出功能,仅需要使用相应的组件即可. Java操作S ...
- jenkins简单安装及配置(Windows环境)
jenkins是一款跨平台的持续集成和持续交付.基于Java开发的开源软件,提供任务构建,持续集成监控的功能,可以使开发测试人员更方便的构建软件项目,提高工作效率. Windows平台下,一般安装方法 ...
- 用Vue.js开发微信小程序:开源框架mpvue解析
前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...
- Python内置函数(30)——super
英文文档: super([type[, object-or-type]]) Return a proxy object that delegates method calls to a parent ...
- 新概念英语(1-31)Where's Sally?
新概念英语(1-31)Where's Sally? Is the cat climbing the tree ? A:Where is Sally, Jack ? B:She is in the ga ...
- Linux实战案例(5)关闭Centos的防火墙
1.检查防火墙的状态 [root@LxfN1 ~]# service iptables status表格:filterChain INPUT (policy ACCEPT)num target pro ...
- 1.7 理解dropout
Dropout为什么有正则化的作用? 下面来直观理解一下. 上面讲到,dropout每次迭代都会让一部分神经元失活,这样使得神经网络会比原始的神经网络规模变小,因此采用一个较小神经网络好像和使用正则化 ...
- java 面向对象编程。。。。
经过一周的学习(java),总结了许多,对java的理解,java的类型,运用,安装,基础语法,变量,常量,表达式,语句 java从C语言中继承了大量语言特性.java面向对象编程的基本特征,包括继承 ...
- nginx location的命中过程
1 先判断精准命中,立即返回结果并结束解析过程 2 判断普通命中,如果有多个命中,"记录"下"最长"的命中结果(注意:记录但不结束,最长的为准) 3 继续判断正 ...