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的小项目实例,主要是代码,所 ...
随机推荐
- python的模块和包
==模块== python语言的组织结构层次: 包->模块->代码文件->类->函数->代码块 什么是模块呢 可以把模块理解为一个代码文件的封装,这是比类更高一级的封装层 ...
- LeetCode & Q88-Merge Sorted Array-Easy
Array Two Pointers Description: Given two sorted integer arrays nums1 and nums2, merge nums2 into nu ...
- 使用JavaScript实现一个俄罗斯方块
清明假期期间,闲的无聊,就做了一个小游戏玩玩,目前游戏逻辑上暂未发现bug,只不过样子稍微丑了一些-.-项目地址:https://github.com/Jiasm/tetris在线Demo:http: ...
- Django REST framework+Vue 打造生鲜超市(三)
四.xadmin后台管理 4.1.xadmin添加富文本插件 (1)xadmin/plugins文件夹下新建文件ueditor.py 代码如下: # xadmin/plugins/ueditor.py ...
- GIT入门笔记(5)- 创建版本库
版本库又名仓库,英文名repository,可以简单理解成一个目录, 这个目录里面的所有文件都可以被Git管理起来,每个文件的修改.删除,Git都能跟踪,以便任何时刻都可以追踪历史,或者在将来某个时刻 ...
- Linux探索之路1---CentOS入坑笔记整理
前言 上次跟运维去行方安装行内环境,发现linux命令还是不是很熟练.特别是用户权限分配以及vi下的快捷操作.于是决定在本地安装一个CentOS虚拟机,后面有时间就每天学习一点Linux常用命令. 作 ...
- SSM登陆注册
package com.coingod.controller; import java.io.IOException;import java.io.PrintWriter;import java.ut ...
- Trensient的使用介绍
1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,java的这种序列化模式为开发者提供了很多便利,我们可以不必关系具体序列化的过 ...
- pymysql.err.ProgrammingError: 1064 (Python字符串转义问题)
代码: sql = """INSERT INTO video_info(video_id, title) VALUES("%s","%s&q ...
- python json.dumps 中的ensure_ascii 参数引起的中文编码问题
在使用json.dumps时要注意一个问题 >>> import json >>> print json.dumps('中国') "\u4e2d\u5 ...