RecyclerView下拉刷新上拉加载(三)—对Adapter的封装
RecyclerView下拉刷新上拉加载(一) http://blog.csdn.net/baiyuliang2013/article/details/51506036
RecyclerView下拉刷新上拉加载(二) http://blog.csdn.net/baiyuliang2013/article/details/51506354
RecyclerView嵌套RecyclerView http://blog.csdn.net/baiyuliang2013/article/details/51518868
前两篇讲了RecyclerView下拉刷新上拉加载普通实现,以及动画实现,但在使用时对适配器数据的填充比较原始,且RecyclerView并没有像ListView那样自带的item点击事件和长按事件,所以如果不做点什么的话,每次填充数据还不要麻烦死?!因此,这篇文章将讲解如何封装一个BaseAdapter使得每次使用时,对数据的填充,以及对item的点击,长按事件,甚至于item中的子View的点击事件变得简单起来!
还是先上两个图,看下效果:
第一张图就是一普通String的列表,只包含了item的点击和长按事件,第二张图,则是一个model列表,包含了item的点击,长按,以及子View的赞和评论(模仿qq空间说说)的点击事件!
在封装Adapter时要有一个基础思想,就是我们想要实现一个怎样的效果,或者说我们在调用时,想要简单到什么程度?然后再结合Listview的adapter内部流程,得出了最基本的几个点:
- 数据源:无论你的model是什么,我都可以随意传进Adapter对吧;
- item点击和长按事件:统一设置一个对外接口,不必每次都要在adapter重写一遍吧;
- item中子View的点击事件:就像第二张图,常见的需求吧;
注意: 以上所有的回调都是在Activity中进行的,而不是在Adapter中!
本文主要就是实现了以上三点,看似没什么,但其实在使用时会省掉不少力气!当然,你也可以根据自己的需求,在BaseAdapter中继续写一些简化操作步骤的方法,本文只是对于最常见的操作做的一个封装!
BaseAdapter:
package com.byl.recyclerview.view;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import java.util.List;
/**
* BaseAdapter
* Created by baiyuliang on 2016-5-27.
*/
public class BaseAdapter<T extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<T> {
public Context context;//上下文
public List<Object> listDatas;//数据源
public LayoutInflater mInflater;
public OnViewClickListener onViewClickListener;//item子view点击事件
public OnItemClickListener onItemClickListener;//item点击事件
public OnItemLongClickListener onItemLongClickListener;//item长按事件
public BaseAdapter(Context context, List<Object> listDatas) {
init(context,listDatas);
}
/**
* 如果item的子View有点击事件,可使用该构造方法
* @param context
* @param listDatas
* @param onViewClickListener
*/
public BaseAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
init(context,listDatas);
this.onViewClickListener = onViewClickListener;
}
/**
* 初始化
* @param context
* @param listDatas
*/
void init(Context context, List<Object> listDatas){
this.context = context;
this.listDatas = listDatas;
this.mInflater = LayoutInflater.from(context);
}
@Override
public T onCreateViewHolder(ViewGroup parent, int viewType) {
return null;
}
@Override
public void onBindViewHolder(T holder, final int position) {
holder.itemView.setOnClickListener(new View.OnClickListener() {//item点击事件
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClick(position);
}
}
});
holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {//item长按事件
@Override
public boolean onLongClick(View v) {
if (onItemLongClickListener != null) {
onItemLongClickListener.onItemLongClick(position);
}
return true;
}
});
}
@Override
public int getItemCount() {
return listDatas.size();
}
/**
* item中子view的点击事件(回调)
*/
public interface OnViewClickListener {
/**
* @param position item position
* @param viewtype 点击的view的类型,调用时根据不同的view传入不同的值加以区分
*/
void onViewClick(int position,int viewtype);
}
/**
* item点击事件
*/
public interface OnItemClickListener {
void onItemClick(int position);
}
/**
* item长按事件
*/
public interface OnItemLongClickListener {
void onItemLongClick(int position);
}
/**
* 设置item点击事件
* @param onItemClickListener
*/
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
/**
* 设置item长按事件
* @param onItemLongClickListener
*/
public void setOnItemLongClickListener(OnItemLongClickListener onItemLongClickListener) {
this.onItemLongClickListener = onItemLongClickListener;
}
}
其中有两个构造方法,注释写的非常清楚,根据自己的需求,在new Adapter时选取不同的构造方法:
public BaseAdapter(Context context, List<Object> listDatas) {
init(context,listDatas);
}
/**
* 如果item的子View有点击事件,可使用该构造方法
* @param context
* @param listDatas
* @param onViewClickListener
*/
public BaseAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
init(context,listDatas);
this.onViewClickListener = onViewClickListener;
}
好了,接下来我们看下整个demo的结构:
首先看Activity1中TextAdapter实现:
/**
* Created by baiyuliang on 2016-5-27.
*/
public class TextAdapter extends BaseAdapter<TextAdapter.MyViewHolder> {
public TextAdapter(Context context, List<Object> listDatas) {
super(context, listDatas);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(mInflater.inflate(R.layout.item_text, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
super.onBindViewHolder(holder, position);
String text = (String) listDatas.get(position);//转换
holder.tv.setText(text);//填充数据
}
@Override
public int getItemCount() {
return listDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;
public MyViewHolder(View view) {
super(view);
tv = (TextView) view.findViewById(R.id.tv);
}
}
}
Activity1中的调用:
private void initRecyclerView() {
recyclerView = (PullRecyclerView) findViewById(R.id.recyclerView);
recyclerView.setOnRefreshListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
textAdapter = new TextAdapter(this, mDatas);
textAdapter.setOnItemClickListener(this);
textAdapter.setOnItemLongClickListener(this);
recyclerView.setAdapter(textAdapter);
}
@Override
public void onItemClick(int position) {
Toast.makeText(Activity1.this, "点击-position>>" + position, Toast.LENGTH_SHORT).show();
}
@Override
public void onItemLongClick(int position) {
Toast.makeText(Activity1.this, "长按-position>>" + position, Toast.LENGTH_SHORT).show();
}
接着看Activity2中的InfoAdapter实现:
/**
* Created by baiyuliang on 2016-5-27.
*/
public class InfoAdapter extends BaseAdapter<InfoAdapter.MyViewHolder> {
public InfoAdapter(Context context, List<Object> listDatas, OnViewClickListener onViewClickListener) {
super(context, listDatas, onViewClickListener);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return new MyViewHolder(mInflater.inflate(R.layout.item_info, parent, false));
}
@Override
public void onBindViewHolder(MyViewHolder holder, final int position) {
super.onBindViewHolder(holder, position);
InfoBean infoBean = (InfoBean) listDatas.get(position);//转换
holder.tv.setText(infoBean.getText());//填充数据
holder.iv_z.setOnClickListener(new ViewClikListener(onViewClickListener, position, 1));//赞 viewtype=1代表赞点击事件
holder.iv_pl.setOnClickListener(new ViewClikListener(onViewClickListener, position, 2));//评论 viewtype=2代表评论点击事件
}
@Override
public int getItemCount() {
return listDatas.size();
}
class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv;//内容
ImageView iv_z, iv_pl;//赞,评论
public MyViewHolder(View view) {
super(view);
tv = (TextView) view.findViewById(R.id.tv);
iv_z = (ImageView) view.findViewById(R.id.iv_z);
iv_pl = (ImageView) view.findViewById(R.id.iv_pl);
}
}
/**
* view的点击事件
*/
class ViewClikListener implements View.OnClickListener {
OnViewClickListener onViewClickListener;
int position;
int viewtype;
public ViewClikListener(OnViewClickListener onViewClickListener, int position, int viewtype) {
this.onViewClickListener = onViewClickListener;
this.position = position;
this.viewtype = viewtype;
}
@Override
public void onClick(View v) {
onViewClickListener.onViewClick(position, viewtype);
}
}
}
Activity2中的调用:
private void initRecyclerView() {
recyclerView = (PullRecyclerView) findViewById(R.id.recyclerView);
recyclerView.setOnRefreshListener(this);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
infoAdapter = new InfoAdapter(this, mDatas, this);
infoAdapter.setOnItemClickListener(this);
infoAdapter.setOnItemLongClickListener(this);
recyclerView.setAdapter(infoAdapter);
}
/**
* 子View点击事件
*
* @param position item position
* @param viewtype 点击的view的类型,调用时根据不同的view传入不同的值加以区分
*/
@Override
public void onViewClick(int position, int viewtype) {
switch (viewtype) {
case 1://赞
Toast.makeText(Activity2.this, "赞-position>>" + position, Toast.LENGTH_SHORT).show();
break;
case 2://评论
Toast.makeText(Activity2.this, "评论-position>>" + position, Toast.LENGTH_SHORT).show();
break;
}
}
/**
* item点击事件
*
* @param position
*/
@Override
public void onItemClick(int position) {
Toast.makeText(Activity2.this, "点击-position>>" + position, Toast.LENGTH_SHORT).show();
}
/**
* item长按事件
*
* @param position
*/
@Override
public void onItemLongClick(int position) {
Toast.makeText(Activity2.this, "长按-position>>" + position, Toast.LENGTH_SHORT).show();
}
基本跟Listview没什么区别了,对于不同类型的Adapter只需复制粘贴即可,当然,本例中并没有封装添加或者删除动画以及分割线等等用户体验方面的代码,只是做了最基础的封装!你可能会说,图中明明有分割线,这是怎么弄的?哈哈,对于RecyclerView设置分割线有两种做法:一种是在item布局xml中直接在顶部或者底部放条线,或者最外层设置一下paddingTop或paddingBottom即可;第二种比较优雅的做法就是重写ItemDecoration类,并调用addItemDecoration()方法;根据自己的喜好或者需求吧,哪种方便按哪种来!
最后,再结合上两篇实现的下拉刷新上拉加载(自己可以再封装一些动画之类的操作或其它功能),将会满足普通项目开发中的大部分需求了!
本例中对第一篇中的代码做了部分优化,并增加了几个设置方法:
// recyclerView.setCanScrollAtRereshing(true);//设置正在刷新时是否可以滑动,默认不可滑动
// recyclerView.setCanPullDown(false);//设置是否可下拉
// recyclerView.setCanPullUp(false);//设置是否可上拉
可根据自己的需求进行相应设置!
ASdemo下载地址:http://download.csdn.net/detail/baiyuliang2013/9533101
RecyclerView下拉刷新上拉加载(三)—对Adapter的封装的更多相关文章
- Android 下拉刷新上啦加载SmartRefreshLayout + RecyclerView
在弄android刷新的时候,可算是耗费了一番功夫,最后发觉有现成的控件,并且非常好用,这里记录一下. 原文是 https://blog.csdn.net/huangxin112/article/de ...
- SwipeRefreshLayout实现下拉刷新上滑加载
1. 效果图 2.RefreshLayout.java package myapplication.com.myapplication; import android.content.Context; ...
- 移动端下拉刷新上拉加载-mescroll.js插件
最近无意间看到有这么一个上拉刷新下拉加载的插件 -- mescroll.js,个人感觉挺好用的,官网地址是:http://www.mescroll.com 然后我就看了一下文档,简单的写了一个小dem ...
- 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载
title: 带你实现开发者头条APP(五)--RecyclerView下拉刷新上拉加载 tags: -RecyclerView,下拉刷新,上拉加载更多 grammar_cjkRuby: true - ...
- RecyclerView下拉刷新上拉加载(二)
listview下拉刷新上拉加载扩展(一) http://blog.csdn.net/baiyuliang2013/article/details/50252561 listview下拉刷新上拉加载扩 ...
- RecyclerView下拉刷新上拉加载(一)
listview下拉刷新上拉加载扩展(一) http://blog.csdn.net/baiyuliang2013/article/details/50252561 listview下拉刷新上拉加载扩 ...
- MaterialRefreshLayout+ListView 下拉刷新 上拉加载
效果图是这样的,有入侵式的,非入侵式的,带波浪效果的......就那几个属性,都给出来了,自己去试就行. 下拉刷新 上拉加载 关于下拉刷新-上拉加载的效果,有许许多多的实现方式,百度了一下竟然有几十种 ...
- 自定义ListView下拉刷新上拉加载更多
自定义ListView下拉刷新上拉加载更多 自定义RecyclerView下拉刷新上拉加载更多 Listview现在用的很少了,基本都是使用Recycleview,但是不得不说Listview具有划时 ...
- ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多
ListView实现Item上下拖动交换位置 并且实现下拉刷新 上拉加载更多 package com.example.ListViewDragItem; import android.app.Ac ...
随机推荐
- [cf453e]Little Pony and Lord Tirek
来自FallDream的博客,未经允许,请勿转载,谢谢. 更博客= = 有n个数,每个数字都有一个初始大小ai和最大值mi,然后每秒会增加ri,你需要回答m个发生时间依此增大的询问,每次询问区间和并且 ...
- hdu 4747 线段树
Mex Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others)Total Submis ...
- hdu 1166 线段树(sum+单点修改)
敌兵布阵 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submi ...
- QSDK下驱动AR8035
0 概述 QSDK平台中,我所接触到的版本,能支持MIPS架构的,是基于Openwrt AA版本:虽然CC版本上就已经能很好地支持AR8035了,可是AA版本它本身是不支持的,于是不断有人要求提供补丁 ...
- PLSQL(1)
PLSQLl编程 plsql是Oracle在标准的sql语言上的扩展 特点:可以在数据库中定义变量,常量,还可以使用条件语句和判断语句以及异常等 P ...
- ubuntu14.04+sublime3+latex配置
目的:用题目所说的三个东西写论文. 配置方法:参考 http://blog.csdn.net/bleedingfight/article/details/72810606, 但该博客所提的texliv ...
- Kirill And The Game CodeForces - 842A
CodeForces - 842A 需要将除法改换成乘法进行计算 #include<bits/stdc++.h> using namespace std; int main() { lon ...
- Java第5次实验提纲(Java图形界面编程)
1. Swing与NetBeans 使用NetBeans编写简单界面.见GUI实验参考文件中的0.第06次实验(图形程序设计.事件处理与Swing).doc 题目1: Swing用户界面组件与事件处理 ...
- 【Java 语言】Java 多线程 一 ( 线程启动 | 线程中断 )
一. 线程启动 线程启动 : -- 1. 继承 Thread 运行线程 : 重写 Thread 类的 run 方法, 然后执行该线程; -- 2. 实现 Runnable 接口, 并运行线程; -- ...
- SpringBatch的核心组件JobLauncher和JobRepository
Spring Batch的框架包括启动批处理作业的组件和存储Job执行产生的元数据.因此只需掌握配置这个基础框架在批处理应用程序中即启动Jobs并存储Job元数据. 组件:Job Launcher和J ...