从中间展开的RecyclerView
程序员文章站
2022-05-14 21:07:22
...
由于项目需要,想要实现可以从中间展开的列表,网上照的大部分不符合心意,所以找了一个比较容易改的自己进行一些修改,是使用RecyclerView实现的,这个是项目地址。
先上效果图:
接下来是主要的修改部分,首先是BaseViewHolder:
在原来的基础上加上了VIEW_TYPE_FOOTER的类型以及getFooterViewResId()的抽象方法。
public BaseViewHolder(Context ctx, View itemView, int viewType) {
super(itemView);
mContext = ctx;
switch (viewType) {
case VIEW_TYPE_PARENT:
groupView = (ViewGroup)itemView.findViewById(getGroupViewResId());
arrow = (ImageView) itemView.findViewById(R.id.holder_arrow);
break;
case VIEW_TYPE_CHILD:
childView = (ViewGroup) itemView.findViewById(getChildViewResId());
break;
case VIEW_TYPE_FOOTER:
footerView = (ViewGroup)itemView.findViewById(getFooterViewResId());
break;
}
}
/**
* return ChildView root layout id
*/
public abstract int getChildViewResId();
/**
* return GroupView root layout id
* */
public abstract int getGroupViewResId();
/**
* return FooterView root layout id
* */
public abstract int getFooterViewResId();
在GroupItem中加上是否为底部的判断以及实现Cloneable接口:
public class GroupItem<T,S> extends BaseItem implements Cloneable{
/**head data*/
private T groupData;
/** childDatas*/
private List<S> childDatas;
/** 是否展开, 默认展开*/
private boolean isExpand = true;
private boolean isFooter = false;
/** 返回是否是父节点*/
@Override
public boolean isParent() {
return true;
}
public boolean isExpand(){
return isExpand;
}
public void onExpand() {
isExpand = !isExpand;
}
public boolean isFooter() {
return isFooter;
}
public void setFooter(boolean footer) {
isFooter = footer;
}
public GroupItem(T groupData, List<S> childDatas, boolean isExpand) {
this.groupData = groupData;
this.childDatas = childDatas;
this.isExpand = isExpand;
}
public boolean hasChilds(){
if(getChildDatas() == null || getChildDatas().isEmpty() ){
return false;
}
return true;
}
public List<S> getChildDatas() {
return childDatas;
}
public void setChildDatas(List<S> childDatas) {
this.childDatas = childDatas;
}
public void removeChild(int childPosition){
}
public T getGroupData() {
return groupData;
}
@Override
public Object clone(){
try {
return super.clone();
}catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return null;
}
}
接着在BaseRecyclerViewAdapter进行修改,首先在getItemViewType方法以及onCreateViewHolder方法中添加类型:
@Override
public int getItemViewType(int position) {
if (showingDatas.get(position) instanceof GroupItem) {
if (((GroupItem) showingDatas.get(position)).isFooter()) {
return BaseViewHolder.VIEW_TYPE_FOOTER;
} else {
return BaseViewHolder.VIEW_TYPE_PARENT;
}
} else {
return BaseViewHolder.VIEW_TYPE_CHILD;
}
}
@Override
public VH onCreateViewHolder(ViewGroup parent, int viewType) {
View view = null;
switch (viewType) {
case BaseViewHolder.VIEW_TYPE_PARENT:
view = getGroupView(parent);
break;
case BaseViewHolder.VIEW_TYPE_CHILD:
view = getChildView(parent);
break;
case BaseViewHolder.VIEW_TYPE_FOOTER:
view = getFooterView(parent);
break;
}
return createRealViewHolder(mActivity, view, viewType);
}
在setShowingDatas方法中添加头部数据,这里我直接使用父布局的数据
/**
* setup showing datas
*/
private void setShowingDatas() {
if (null != showingDatas) {
showingDatas.clear();
}
if (this.childDatas == null) {
this.childDatas = new ArrayList<>();
}
childDatas.clear();
GroupItem groupItem;
GroupItem footerItem;
for (int i = 0; i < allDatas.size(); i++) {
if (allDatas.get(i).getGroupItem() instanceof GroupItem) {
groupItem = allDatas.get(i).getGroupItem();
} else {
break;
}
childDatas.add(i, groupItem.getChildDatas());
showingDatas.add(groupItem);
if (groupItem.hasChilds() && groupItem.isExpand()) {
showingDatas.addAll(groupItem.getChildDatas());
}
if (showFooter()) {
footerItem = (GroupItem) groupItem.clone();
footerItem.setFooter(true);
showingDatas.add(footerItem);
}
}
}
/**
* 如果要有底部布局的话,该方法要返回true;
*
* @return value
*/
public boolean showFooter(){
return false;
}
接着onBindViewHolder方法在中进行实例化
@Override
public void onBindViewHolder(final VH holder, final int position) {
final Object item = showingDatas.get(position);
final int gp = getGroupPosition(position);
final int cp = getChildPosition(gp, position);
if (item != null && item instanceof GroupItem) {
if (((GroupItem) item).isFooter()) {
onBindFooterHolder(holder, gp, position, (T) ((GroupItem) item).getGroupData());
} else {
onBindGroupHolder(holder, gp, position, (T) ((GroupItem) item).getGroupData());
holder.groupView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != itemClickListener) {
itemClickListener.onGroupItemClick(position, gp, holder.groupView, ((GroupItem) item).isExpand());
}
if (((GroupItem) item).isExpand()) {
collapseGroup(position);
} else {
expandGroup(position);
}
}
});
holder.groupView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (null != itemLongClickListener) {
itemLongClickListener.onGroupItemLongClick(position, gp, holder.groupView);
}
return true;
}
});
}
} else {
onBindChildHolder(holder, gp, cp, position, (S) item);
holder.childView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (null != itemClickListener) {
itemClickListener.onChildItemClick(position, gp, cp, holder.childView);
}
}
});
holder.childView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
if (null != itemLongClickListener) {
int gp = getGroupPosition(position);
itemLongClickListener.onChildItemLongClick(position, gp, cp, holder.childView);
}
return true;
}
});
}
}
最后是使用:
public class MiddleAdapter extends BaseRecyclerViewAdapter<ExpandData.ParentData,ExpandData.ChildData,MiddleAdapter.MiddleViewHolder> implements OnRecyclerViewListener.OnItemClickListener{
private LayoutInflater mInflater;
public MiddleAdapter(Activity activity, BaseRecyclerData data) {
super(activity, data);
mInflater = LayoutInflater.from(activity);
setOnItemClickListener(this);
}
@Override
public View getGroupView(ViewGroup parent) {
return mInflater.inflate(R.layout.viewholder_parent, parent, false);
}
@Override
public View getChildView(ViewGroup parent) {
return mInflater.inflate(R.layout.viewholder_child, parent, false);
}
@Override
public View getFooterView(ViewGroup parent) {
return mInflater.inflate(R.layout.viewholder_footer, parent, false);
}
@Override
public MiddleViewHolder createRealViewHolder(Context ctx, View view, int viewType) {
return new MiddleViewHolder(ctx,view,viewType);
}
@Override
public void onBindGroupHolder(MiddleViewHolder holder, int groupPos, int position, ExpandData.ParentData groupData) {
holder.setText(R.id.holder_title,groupData.title);
}
@Override
public void onBindFooterHolder(MiddleViewHolder holder, int groupPos, int position, ExpandData.ParentData groupData) {
holder.setImage(R.id.holder_image,R.mipmap.icon_shoes);
}
@Override
public void onBindChildHolder(MiddleViewHolder holder, int groupPos, int childPos, int position, ExpandData.ChildData childData) {
holder.setText(R.id.holder_content,childData.content);
}
@Override
public void onGroupItemClick(int position, int groupPosition, View view, boolean isExpand) {
}
@Override
public void onChildItemClick(int position, int groupPosition, int childPosition, View view) {
}
@Override
public boolean showFooter() {
return true;
}
class MiddleViewHolder extends BaseViewHolder {
MiddleViewHolder(Context ctx, View itemView, int viewType) {
super(ctx, itemView, viewType);
}
@Override
public int getChildViewResId() {
return R.id.holder_child;
}
@Override
public int getGroupViewResId() {
return R.id.holder_parent;
}
@Override
public int getFooterViewResId() {
return R.id.holder_footer;
}
void setImage(int resId, int imgId){
ImageView imageView = (ImageView) itemView.findViewById(resId);
imageView.setImageResource(imgId);
}
void setText(int resId, String str){
TextView textView = (TextView) itemView.findViewById(resId);
textView.setText(str);
}
}
}
附上下载地址
补充个GitHub地址
上一篇: JavaScript实现简单的图片切换
下一篇: php判断与去除数组中重复数据的方法
推荐阅读
-
从django的中间件直接返回请求的方法
-
从二叉查找树到B+树中间的各种树
-
如何从ERP将Material的Batch信息下载到CRM并存储在settype COMM_PR_BATCH里 CRMERPSAP中间件Middleware
-
利用CRM中间件Middleware从ERP下载Customer Material的常见错误 CRMERPSAPmiddleware中间件
-
专访小邪:从十年技术之路看阿里技术体系的变革 阿里巴巴中间件云计算
-
使用SAP CRM中间件从ERP下载Customer的错误消息 SAPSAP云平台SAP Cloud PlatformSAP成都研究院Cloud
-
Laravel5.5源码详解 -- 一次查询的详细执行:从Auth-Login-web中间件到数据库查询结果的全过程
-
使用SAP CRM中间件从ERP下载BOM的一些常见问题 SAPCloud Application ProgrammingCRMSAP云平台SAP Cloud Platform
-
Jawbone从可穿戴领域转型医疗健康,鼻祖欲展开最后的自救?
-
随意输入一串数,将其中的偶数项逆序输出,奇数项的顺序不变。从两头向中间找偶数,找到了就交换。下面附上C++代码。