本人学习安卓从看完《第一行代码》就开始用小书匠写markdown做学习笔记(后悔没早点知道这个学习方法,不然学第一行代码会更扎实一点,以后当然会补上的哈哈哈)我的想法是先做一次笔记在小书匠,然后在CSDN发布的时候再重新阅读修改一下,以保证自己能真的记住会用,实在不行就要达到自己要用到时可以一眼看懂的效果.这篇是我几个月前总结的,排版格式emm大家将就着看吧…
这是用于将RecycleView分组的
实际运用的时候直接继承GroupedRecyclerViewAdapter、创建好父/子的数据Bean然后根据系统提示引入重写方法,然后不了解的地方看着目录跳转去解决就好
参考博客
在Project的build.gradle在添加以下代码
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
在Module的build.gradle在添加以下代码
compile 'com.github.donkingliang:GroupedRecyclerViewAdapter:1.3.0'
继承了GroupedRecyclerViewAdapter 后需要实现以下默认方法(直接用提示键一键引入就好)以下是介绍各个抽象方法的作用
//返回组的数量
public abstract int getGroupCount();
//返回当前组的子项数量
public abstract int getChildrenCount(int groupPosition);
//当前组是否有头部
public abstract boolean hasHeader(int groupPosition);
//当前组是否有尾部
public abstract boolean hasFooter(int groupPosition);
//返回头部的布局id。(如果hasHeader返回false,这个方法不会执行)
public abstract int getHeaderLayout(int viewType);
//返回尾部的布局id。(如果hasFooter返回false,这个方法不会执行)
public abstract int getFooterLayout(int viewType);
//返回子项的布局id。
public abstract int getChildLayout(int viewType);
//绑定头部布局数据。(如果hasHeader返回false,这个方法不会执行)
public abstract void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition);
//绑定尾部布局数据。(如果hasFooter返回false,这个方法不会执行)
public abstract void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition);
//绑定子项布局数据。
public abstract void onBindChildViewHolder(BaseViewHolder holder,
int groupPosition, int childPosition);
//设置组头点击事件
public void setOnHeaderClickListener(OnHeaderClickListener listener) {
mOnHeaderClickListener = listener;
}
//设置组尾点击事件
public void setOnFooterClickListener(OnFooterClickListener listener) {
mOnFooterClickListener = listener;
}
// 设置子项点击事件
public void setOnChildClickListener(OnChildClickListener listener) {
mOnChildClickListener = listener;
}
//返回头部的布局id。(如果hasHeader返回false,这个方法不会执行)
@Override
public int getHeaderLayout(int viewType) {
return R.layout.head_item;
}
//返回尾部的布局id。(如果hasFooter返回false,这个方法不会执行)
public abstract int getFooterLayout(int viewType);
//返回子项的布局id。
public abstract int getChildLayout(int viewType);
头部中注意这个ChildItem就好,就相当于父亲带了个孩子
public class ExpandableGroupItem {
private String header;
private String footer;
private boolean isExpand;
private ArrayList<ChildItem> childItems;
public ExpandableGroupItem(String header, String footer, boolean isExpand,
ArrayList<ChildItem> children) {
this.header = header;
this.footer = footer;
this.isExpand = isExpand;
this.childItems = children;
}
}
子项Bean,就是和之前的普通Adapter一样设置每一个item的内容
public class ChildItem {
private String doWhat;
private String point;
private String tab;
private String belong;
}
头部
@Override
public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
ExpandableGroupItem groupItem = mGroups.get(groupPosition);
//因为这个BaseViewHolder是底层实现的,所以直接传view 的id就好
holder.setText(R.id.header_text, groupItem.getHeader());
ImageView ivState = holder.get(R.id.iv_state);
}
子项也差不多注意和头部的关系(分清楚两个pos就可以)
@Override
public void onBindChildViewHolder(BaseViewHolder holder, int groupPosition, int childPosition) {
//一定要注意子项父项的关系
ChildItem childItem = mGroups.get(groupPosition).getChildItems().get(childPosition);
holder.setText(R.id.dowhat, childItem.getDoWhat());
holder.setText(R.id.point, childItem.getPoint());
}
//更新操作
public final void notifyDataSetChanged();
public final void notifyItemChanged(int position);
public final void notifyItemChanged(int position, Object payload);
public final void notifyItemRangeChanged(int positionStart, int itemCount);
public final void notifyItemRangeChanged(int positionStart, int itemCount, Object payload);
//插入操作
public final void notifyItemInserted(int position);
public final void notifyItemRangeInserted(int positionStart, int itemCount);
//删除操作
public final void notifyItemRemoved(int position)
public final void notifyItemRangeRemoved(int positionStart, int itemCount);
还有更详细的操作请看参考博客
但如果是使用GroupedRecyclerViewAdapter,就一定不能去重写以下这几个方法(因为这些方法GroupedRecycleViewAdapter底层已经实现了,重写可能会破坏原有的功能)
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType);
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position);
public int getItemCount();
public int getItemViewType(int position);
关键是折叠效果的实现和布局的选择,这里是用网格布局
View view = inflater.inflate(R.layout.fragment_gatelist, container, false);
/**
* 初始化recycleView
*/
mRecycleView = view.findViewById(R.id.gateList_recyclerView);
gatewayAdapter = new GatewayAdapter(getActivity(), deviceManagerItems);
GroupedGridLayoutManager groupedGridLayoutManager = new GroupedGridLayoutManager(getContext(), 2, gatewayAdapter);
mRecycleView.setLayoutManager(groupedGridLayoutManager);
gatewayAdapter.setOnHeaderClickListener(new GroupedRecyclerViewAdapter.OnHeaderClickListener() {
@Override
public void onHeaderClick(GroupedRecyclerViewAdapter adapter, BaseViewHolder holder,
int groupPosition) {
GatewayAdapter gatewayAdapter1 = (GatewayAdapter) adapter;
//如果是展开状态下点击的,就把他折叠
if (gatewayAdapter1.isExpand(groupPosition)) {
gatewayAdapter1.collapseGroup(groupPosition);
} else {
gatewayAdapter1.expandGroup(groupPosition);
}
}
});
mRecycleView.setAdapter(gatewayAdapter);
其实也和RecycleView差不多的,加上合适的前缀就可以运用自如了
@Override
public void onBindChildViewHolder(final BaseViewHolder holder, final int groupPosition, final int childPosition) {
holder.itemView.findViewById(R.id.gateway_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
holder.itemView.findViewById(R.id.gateway_layout).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
}
初始化数据后还想在特定的分组插入子项应该怎么做?
我自己想了一个正常思路的方法
/**
* 如果是已经存在的话就把原来父项item中的childItems赋值过去最后再给回expandableGroupItem保证插入成功
*/
ChildItem newItem = new ChildItem(a, b, c, d);
int i;
for (i = 0; i < expandableGroupItems.size(); i++) {
if (d.equals(expandableGroupItems.get(i).getHeader())) {
childItems = expandableGroupItems.get(i).getChildItems();
childItems.add(newItem);
break;
}
}
/**
* 如果是新的话就直接添加这个item给childItems,然后再给expandableGroupItem保证生成新的父项和子项
*/
if (i == expandableGroupItems.size()) {
childItems.add(newItem);
}
ExpandableGroupItem expandableGroupItem = new ExpandableGroupItem("头部", "尾部", true, childItems);
/**
* 添加完后就刷新一次list的数据
*/
expandableGroupItems.add(expandableGroupItem);
adapter.notifyDataChanged();
private static final String TAG = "GatewayAdapter";
private List<DeviceManagerItem> deviceManagerItems;
private Activity mContext;
public GatewayAdapter(Activity context, List<DeviceManagerItem> deviceManagerItems) {
super(context);
mContext = context;
this.deviceManagerItems = deviceManagerItems;
}
@Override
public int getGroupCount() {
return deviceManagerItems == null ? 0 : deviceManagerItems.size();
}
@Override
public int getChildrenCount(int groupPosition) {
//如果当前组收起,就直接返回0,否则才返回子项数。这是实现列表展开和收起的关键。
if (!isExpand(groupPosition)) {
return 0;
}
List<GatewayBean> children = deviceManagerItems.get(groupPosition).getGatewayBeans();
return children == null ? 0 : children.size();
}
@Override
public boolean hasHeader(int groupPosition) {
return true;
}
@Override
public boolean hasFooter(int groupPosition) {
return false;
}
@Override
public int getHeaderLayout(int viewType) {
return R.layout.header_item;
}
@Override
public int getFooterLayout(int viewType) {
return 0;
}
@Override
public int getChildLayout(int viewType) {
return R.layout.item_show_gateway;
}
@Override
public void onBindHeaderViewHolder(BaseViewHolder holder, int groupPosition) {
DeviceManagerItem deviceManagerItem = deviceManagerItems.get(groupPosition);
holder.setText(R.id.header_address, deviceManagerItem.getHeader());
}
@Override
public void onBindFooterViewHolder(BaseViewHolder holder, int groupPosition) {
}
@Override
public void onBindChildViewHolder(final BaseViewHolder holder, final int groupPosition, final int childPosition) {
final GatewayBean gatewayBean = deviceManagerItems.get(groupPosition).getGatewayBeans().get(childPosition);
holder.itemView.findViewById(R.id.gateway_layout).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
}
});
holder.itemView.findViewById(R.id.gateway_layout).setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return true;
}
});
}
/**
* 判断当前组是否展开
*
* @param groupPosition
* @return
*/
public boolean isExpand(int groupPosition) {
DeviceManagerItem entity = deviceManagerItems.get(groupPosition);
return entity.isExpand();
}
/**
* 展开一个组
*
* @param groupPosition
*/
public void expandGroup(int groupPosition) {
expandGroup(groupPosition, false);
}
/**
* 展开一个组
*
* @param groupPosition
* @param animate
*/
public void expandGroup(int groupPosition, boolean animate) {
DeviceManagerItem entity = deviceManagerItems.get(groupPosition);
entity.setExpand(true);
if (animate) {
// 通知一组里的所有子项插入
notifyChildrenInserted(groupPosition);
} else {
notifyDataChanged();
}
}
/**
* 收起一个组
*
* @param groupPosition
*/
public void collapseGroup(int groupPosition) {
collapseGroup(groupPosition, false);
}
/**
* 收起一个组
*
* @param groupPosition
* @param animate
*/
public void collapseGroup(int groupPosition, boolean animate) {
DeviceManagerItem entity = deviceManagerItems.get(groupPosition);
entity.setExpand(false);
if (animate) {
notifyChildrenRemoved(groupPosition);
} else {
notifyDataChanged();
}
}
}
感谢阅读!如有不合理之处还望指出,谢谢!
侵删