您的位置:首页 > 其它

RecyclerView组件自定义分组

2016-11-17 09:26 375 查看
轻松实现类试与 header footer item等分组的Adapter组件。好用方便。

原理: 将每一个Item 从position 转化为section(段) row(列)数据格式,方便定位具体属于那一组的哪一个Item的数据。数据格式如下:

public static class IndexPath{
public int row;
public int section;

@Override
public String toString() {
return "IndexPath [row=" + row + ", section=" + section + "]";
}
}


关键点一:

count的计算法,count 从以前的position现在复杂化了,应该包含每一段的header、item、 footer的总和,算法较复杂,这里讲定义为final不让重复写。

@Override
final public int getItemCount() {
int section = getSection();
int count = 0;
for (int i = 0; i < section; i++) {
int header = isGroupHeaderForSection(i)?1:0;
int footer = isGroupFooterForSection(i)?1:0;
count = count + getRow(i) + header + footer;
}
return count;
}


关键2:

header 和 footer的动态处理,动态的删减

/**
* 该组是否包含HeadView
* @param section
* @return
*/
public boolean isGroupHeaderForSection(int section){
return false;
}
/**
* 该组是否包含FooterVew
* @param section
* @return
*/
public boolean isGroupFooterForSection(int section){
return false;
}


关键3:

将position转化为indexpath的算法

/**
* 根据 postion 计算 indexPath
* @param position
* @return
*/
final public IndexPath findIndexPathForPosition(int position){
position -= getListHeadCount();
int section = getSection();
int count = 0;
int sec = 0;
for (int i = 0; i < section; i++) {
int header = isGroupHeaderForSection(i)?1:0;
int footer = isGroupFooterForSection(i)?1:0;

count = count + getRow(i) + header + footer;
if (count > position) {
sec = i;
count = count - getRow(i) - header - footer;
break;
}
}

IndexPath indexPath = new IndexPath();
indexPath.section = sec;
indexPath.row = position-count;

Log.d("demo", "" +indexPath +" po: "+ position +" getRow:"+getRow(indexPath.section));

return indexPath;
}


完成上面的情况,就可以进行封装了:

全码:

package com.hujiang.designsupportlibrarydemo.adapter;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

/**
* Created by tp on 2016/11/16.
*/
public abstract class BaseRecyclerAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

public Context mContext;

public int getSection(){//获取切片
return 1;
}

/**
* 根据切片section 获取对应的 row item
* @param section
* @return
*/
public abstract int getRow(int section);

@Override
final public int getItemCount() {
int section = getSection();
int count = 0;
for (int i = 0; i < section; i++) {
int header = isGroupHeaderForSection(i)?1:0;
int footer = isGroupFooterForSection(i)?1:0;
count = count + getRow(i) + header + footer;
}
return count;
}

@Override
final public int getItemViewType(int position) {
IndexPath indexPath = findIndexPathForPosition(position);
if (isGroupHeaderForSection(indexPath.section) && indexPath.row == 0 ) {//有头
return getItemHeaderViewType(indexPath);
}

if (isGroupFooterForSection(indexPath.section)) {//有尾
int row = getRow(indexPath.section);
int header = isGroupHeaderForSection(indexPath.section)?1:0;
if (row == indexPath.row - header) {//到尾部了
return getItemFooterViewType(indexPath);
}
}
return getItemViewType(indexPath);
}

/**
*
* @param indexPath 改位置的 view type
* @return
*/
public int getItemViewType(IndexPath indexPath){
return 0;
}

/**
*
* @param indexPath section Footer 位置的 view type
* @return
*/
public int getItemFooterViewType(IndexPath indexPath){
return 1;
}
/**
*
* @param indexPath section Header position view type
* @return
*/
public int getItemHeaderViewType(IndexPath indexPath){
return 2;
}

/**
* 根据 postion 计算 indexPath
* @param position
* @return
*/
final public IndexPath findIndexPathForPosition(int position){
position -= getListHeadCount();
int section = getSection();
int count = 0;
int sec = 0;
for (int i = 0; i < section; i++) {
int header = isGroupHeaderForSection(i)?1:0;
int footer = isGroupFooterForSection(i)?1:0;

count = count + getRow(i) + header + footer;
if (count > position) {
sec = i;
count = count - getRow(i) - header - footer;
break;
}
}

IndexPath indexPath = new IndexPath();
indexPath.section = sec;
indexPath.row = position-count;

Log.d("demo", "" +indexPath +" po: "+ position +" getRow:"+getRow(indexPath.section));

return indexPath;
}

/**
* listview header 的数量决定 position 的位置
* @return
*/
public int getListHeadCount(){
return 0;
}

@Override
final public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
IndexPath indexPath = findIndexPathForPosition(position);

int header = isGroupHeaderForSection(indexPath.section)?1:0;

if (isGroupHeaderForSection(indexPath.section) && indexPath.row == 0) {//有头
onBindHeaderViewHolder(holder,position,indexPath);
return;
}

if (isGroupFooterForSection(indexPath.section)) {//有尾
int row = getRow(indexPath.section);
if (row == indexPath.row - header) {//到尾部了
onBindFooterViewHolder(holder,position,indexPath);
return;
}
}

if (isGroupHeaderForSection(indexPath.section)) {//包含header row位置 -1 和 list index 保持一致
indexPath.row -= 1;
}

onBindItemViewHolder(holder,position,indexPath);
}

public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder, int position,IndexPath indexPath){}
public void onBindFooterViewHolder(RecyclerView.ViewHolder holder, int position,IndexPath indexPath){}
public abstract void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position,IndexPath indexPath);
/** * 该组是否包含HeadView * @param section * @return */ public boolean isGroupHeaderForSection(int section){ return false; } /** * 该组是否包含FooterVew * @param section * @return */ public boolean isGroupFooterForSection(int section){ return false; }

public View getHeaderView(int position,int section,View convertView,ViewGroup parent){
if (isGroupHeaderForSection(section)) {
TextView header = null;
if (convertView!=null) {
header =(TextView) convertView;
}else {
header = new TextView(mContext);
}
header.setText("第:"+section+" header");
return header;
}
return null;
}
public View getFooterView(int position,int section,View convertView,ViewGroup parent){
if (isGroupFooterForSection(section)) {
TextView footer =null;
if (convertView != null) {
footer = (TextView) convertView;
}else {
footer = new TextView(mContext);
}
footer.setText("第:"+section +" footer");
return footer;
}
return null;
}

public static class IndexPath{
public int row;
public int section;

@Override
public String toString() {
return "IndexPath [row=" + row + ", section=" + section + "]";
}
}

}


使用方法:

继承基类adapter 例如:

package com.hujiang.designsupportlibrarydemo.adapter;

import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.hujiang.designsupportlibrarydemo.R;

import java.util.List;

/**
* Created by tp on 2016/11/16.
*/

public class RecylerGroupAdapter extends BaseRecyclerAdapter {

private List<String> list;

public RecylerGroupAdapter(List<String> list) {
this.list = list;
}

@Override
public int getRow(int section) {
return  section;
//return 1;
}

@Override
public int getSection() {
return  list.size();
}

@Override
public boolean isGroupFooterForSection(int section) {
return true;
}

@Override
public boolean isGroupHeaderForSection(int section) {
return  true;
}

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.item, parent, false);
return new DefineViewHolder(view);
}

@Override
public void onBindItemViewHolder(RecyclerView.ViewHolder holder, int position, IndexPath indexPath) {
IndexPath path =  findIndexPathForPosition(position);
if (holder instanceof DefineViewHolder) {
((DefineViewHolder)holder).setData(list.get(indexPath.row));
}
}

@Override
public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder, int position, IndexPath indexPath) {
if (holder instanceof DefineViewHolder) {
((DefineViewHolder)holder).setData("第:"+indexPath+" 段 - header");
}
}

@Override
public void onBindFooterViewHolder(RecyclerView.ViewHolder holder, int position, IndexPath indexPath) {
if (holder instanceof DefineViewHolder) {
((DefineViewHolder)holder).setData("第:"+indexPath+" 段 - Footer");
}
}

static class DefineViewHolder extends RecyclerView.ViewHolder {

TextView tvTitle;

public DefineViewHolder(View itemView) {
super(itemView);
tvTitle = (TextView) itemView.findViewById(R.id.tv_title);
}

public void setData(String data) {
tvTitle.setText(data);
}

}
}


关键方法:

@Override
public int getRow(int section) {
return  section;
//return 1;
}

@Override
public int getSection() {
return  list.size();
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  recyclervi