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的小项目实例,主要是代码,所 ... 
随机推荐
- 创建帧动画1 - xml方式
			废话不多说,先看东西 创建帧动画1 - xml方式 帧动画的创建方式主要以下2种: * 用xml创建动画: * 用代码创建动画: 本文内容主要关注 xml文件 创建帧动画的方式 xml文件 ... 
- api-gateway实践(16)【租户模块:修改api定义】通过mq通知【开发者模块:更新开发者集市】
			一.订阅关系 二.接收消息 dev模块接收更新本地集市 
- nodejs(1-1)
			http://www.runoob.com/nodejs/nodejs-tutorial.html 
- 新概念英语(1-71)He's awful!
			He's awful!How did Pauline answer the telephone at the nine o'clock?A:What's Ron Marston like, Pauli ... 
- Hive&SqlServerql:inner join on条件中如果两边都是空值的情况下,关联结果中会把数据给过滤掉。
			今天遇到的一个大坑,话不多少,看sql和下边的查询结果: --问题:恰好把buildingid is null的记录给过滤掉 ),buildingid ),)); ); ); ); ); ); ); ... 
- PageRank之基于C C#的基本实现
			重点不是说PageRank是什么,而是怎么用代码实现 什么是PageRank? PageRank,网页排名,又称网页级别.Google左侧排名或佩奇排名,是一种由[1] 根据网页之间相互的超链接计算 ... 
- 06、NetCore2.0依赖注入(DI)之整合Autofac
			06.NetCore2.0依赖注入(DI)之整合Autofac 除了使用NetCore2.0系统的依赖注入(DI)框架外,我们还可以使用其他成熟的DI框架,如Autofac.Unity等.只要他们支持 ... 
- netcore webapi帮助文档设置
			如何建 .netcore webapi 项目这个就不说了,这个都没有没必要看下去. 我这里是.netcore 2.0,虽然没测过1.0的,但想来差不多. 1.Nuget Packages安装,使用程序 ... 
- JS中的递归
			递归基础 递归的概念 在程序中函数直接或间接调用自己 直接调用自己 简介调用自己 跳出结构,有了跳出才有结果 递归的思想 递归的调用,最终还是要转换为自己这个函数 如果有个函数foo,如果他是递归 ... 
- JavaScript中内存使用规则--堆和栈
			堆和栈都是运行时内存中分配的一个数据区,因此也被称为堆区和栈区,但二者存储的数据类型和处理速度不同.堆(heap)用于复杂数据类型(引用类型)分配空间,例如数组对象.object对象:它是运行时动态分 ... 
