/**
* 自定义recyclerview继承relativeLayout
*/
public class ExpandableRecyclerView extends RelativeLayout{
// 悬浮在顶部的view
private RelativeLayout pinnedView;
ImageView pinnedIcon; // 顶部悬浮view的icon,可用来表示展开状态
TextView pinnedText; // 顶部悬浮view的内容
TextView pinnedNum; // 顶部悬浮view的数据,展示当前分组成员个数
ExpandableRecyclerViewAdapter adapter; // 项目中的二级列表adapter
private RecyclerView recyclerView;
// 两个状态图标
private Drawable mListIndicatorExpanded;
private Drawable mListIndicatorNormal;
public ExpandableRecyclerView(Context context){
super(context);
initView(context);
}
public ExpandableRecyclerView(Context context, AttributeSet attrs){
super(context, attrs);
initView(context);
}
public ExpandableRecyclerView(Context context, AttributeSet attrs, int defStyleAttr){
super(context, attrs, defStyleAttr);
initView(context);
}
private void initView(Context context){
LayoutInflater.from(context).inflate(R.layout.expandable_recyclerview_layout, this, true);
pinnedView = findViewById(R.id.expanded_recyclerview_pinned_view);
pinnedIcon = findViewById(R.id.expanded_recyclerview_indicator);
pinnedText = findViewById(R.id.expanded_recyclerview_name);
pinnedNum = findViewById(R.id.expanded_recyclerview_number);
recyclerView = findViewById(R.id.expanded_recyclerview);
MyLinearLayoutManager lm = new MyLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
recyclerView.setLayoutManager(lm);
mListIndicatorExpanded = context.getResources().getDrawable(R.drawable.list_indicator_expanded);
mListIndicatorNormal = context.getResources().getDrawable(R.drawable.list_indicator_normal);
initListener();
}
private void initListener(){
// 通过recyclerview的滑动判断顶部悬浮view展示内容
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy){
// 滑动的时候悬浮框置顶
LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager();
// 获取第一个可见item位置
int firstVisibleItemPosition = lm.findFirstVisibleItemPosition();
pinnedView.setVisibility(View.VISIBLE);
// 对应位置在二级列表里的坐标 该坐标包含父坐标和子坐标
ExpandableListPosition expandableListPosition =
adapter.expandableList.getUnflattenedPosition(firstVisibleItemPosition);
if (expandableListPosition.groupPos < adapter.getGroups().size()) {
// 根据二级列表坐标取出group的数据,该数据包含child的数据
ExpandableGroup expandableGroup =
(ExpandableGroup) adapter.getGroups().get(expandableListPosition.groupPos);
// 根据展开状态设置顶部悬浮view的icon状态
pinnedIcon.setImageDrawable(
adapter.isGroupExpanded(expandableGroup) ? mListIndicatorExpanded : mListIndicatorNormal);
// 设置顶部悬浮view的内容
pinnedText.setText(expandableGroup.getTitle());
// // 设置顶部悬浮view的child的数量
pinnedNum.setText(
expandableGroup.getItems() != null ? "(" + expandableGroup.getItems().size() + ")" : "");
pinnedView.setTag(expandableGroup);
}
}
});
pinnedView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v){
// 点击悬浮框展开或伸缩列表
ExpandableGroup expandableGroup = (ExpandableGroup) pinnedView.getTag();
if (expandableGroup != null) {
adapter.toggleGroup(expandableGroup);
recyclerView.scrollToPosition(0);
}
if (pinnedIcon.getDrawable() == mListIndicatorNormal) {
pinnedIcon.setImageDrawable(mListIndicatorExpanded);
} else if (pinnedIcon.getDrawable() == mListIndicatorExpanded) {
pinnedIcon.setImageDrawable(mListIndicatorNormal);
}
}
});
}
public RecyclerView getRecyclerView(){
return recyclerView;
}
private RecyclerView.AdapterDataObserver observer = new RecyclerView.AdapterDataObserver() {
@Override
public void onChanged(){
super.onChanged();
// 更新顶部悬浮view
updatePinnedView();
}
};
public void setAdapter(final ExpandableRecyclerViewAdapter adapter){
this.adapter = adapter;
// 数据更新的时候,如果不滑动,这个时候顶部悬浮view的内容不准,所以在数据变更的时候要更新顶部悬浮view
// adapter注册数据变更监听
this.adapter.registerAdapterDataObserver(observer);
recyclerView.setAdapter(adapter);
}
/**
* 更新pinnedview的内容
*/
private void updatePinnedView(){
// 查找第一个父布局
LinearLayoutManager lm = (LinearLayoutManager) recyclerView.getLayoutManager();
int firstVisibleItemPosition = lm.findFirstVisibleItemPosition();
// 对应位置在列表里的坐标
ExpandableListPosition expandableListPosition =
adapter.expandableList.getUnflattenedPosition(firstVisibleItemPosition);
if (expandableListPosition.groupPos < adapter.getGroups().size()) {
ExpandableGroup expandableGroup =
(ExpandableGroup) adapter.getGroups().get(expandableListPosition.groupPos);
pinnedIcon.setImageDrawable(
adapter.isGroupExpanded(expandableGroup) ? mListIndicatorExpanded : mListIndicatorNormal);
pinnedText.setText(expandableGroup.getTitle());
pinnedNum.setText(expandableGroup.getItems() != null ? "(" + expandableGroup.getItems().size() + ")" : "");
pinnedView.setTag(expandableGroup);
}
}
// java.lang.IndexOutOfBoundsException: Inconsistency detected.Invalid item position
// 这个crash据说是recyclerview的bug,google建议重写下面的方法改成false,我试试
class MyLinearLayoutManager extends LinearLayoutManager{
@SuppressWarnings("SameParameterValue")
MyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
@Override
public boolean supportsPredictiveItemAnimations(){
return false;
}
}
}