@Override public void onChildCheckChanged(View view, boolean checked, int flatPos) { ExpandableListPosition listPos = expandableList.getUnflattenedPosition(flatPos); childCheckController.onChildCheckChanged(checked, listPos); if (childClickListener != null) { childClickListener.onCheckChildCLick(view, checked, (CheckedExpandableGroup) expandableList.getExpandableGroup(listPos), listPos.childPos); } }
public ExpandableRecyclerViewAdapter(List<? extends ExpandableGroup> groups) { this.expandableList = new ExpandableList(groups); this.expandCollapseController = new ExpandCollapseController(expandableList, this); }
/** * Converts a child position to a flat list position. * * @param packedPosition The child positions to be converted in it's * packed position representation. * @return The flat list position for the given child */ public int getFlattenedChildIndex(long packedPosition) { ExpandableListPosition listPosition = ExpandableListPosition.obtainPosition(packedPosition); return getFlattenedChildIndex(listPosition); }
public boolean toggleGroup(ExpandableGroup group) { ExpandableListPosition listPos = expandableList.getUnflattenedPosition(expandableList.getFlattenedGroupIndex(group)); boolean expanded = expandableList.expandedGroupIndexes[listPos.groupPos]; if (expanded) { collapseGroup(listPos); } else { expandGroup(listPos); } return expanded; }
/** * Triggered by a click event on a {@link CheckableChildViewHolder} causing the {@link Checkable} * object to change checked states * * @param checked The current checked state of the view * @param listPosition The flat position (raw index) of the {@link CheckableChildViewHolder} */ public void onChildCheckChanged(boolean checked, ExpandableListPosition listPosition) { CheckedExpandableGroup group = (CheckedExpandableGroup) expandableList.groups.get(listPosition.groupPos); group.onChildClicked(listPosition.childPos, checked); if (childrenUpdateListener != null) { childrenUpdateListener.updateChildrenCheckState( expandableList.getFlattenedFirstChildIndex(listPosition), expandableList.getExpandableGroupItemCount(listPosition)); } }
/** * @param flatPos the flattened position of an item in the list * @return true if {@code group} is expanded, false if it is collapsed */ public boolean isGroupExpanded(int flatPos) { ExpandableListPosition listPosition = expandableList.getUnflattenedPosition(flatPos); return expandableList.expandedGroupIndexes[listPosition.groupPos]; }
@Test public void test_getUnflattenedPosition() { ExpandableList list = new ExpandableList(groups); int flatPos = 3; //initial state //flatPos 3 == group at index 3 ExpandableListPosition initialExpected = obtain(GROUP, 3, -1, 3); ExpandableListPosition initialActual = list.getUnflattenedPosition(flatPos); assertEquals(initialExpected, initialActual); //expand first group list.expandedGroupIndexes[0] = true; //flatPos 3 == child number 2 within group at index 0 ExpandableListPosition newExpected = obtain(CHILD, 0, 2, 3); ExpandableListPosition newActual = list.getUnflattenedPosition(flatPos); assertEquals(newExpected, newActual); } }
@Test public void test_getVisibleItemCount() { ExpandableList list = new ExpandableList(groups); //initial state int initialExpected = 6; int initialActual = list.getVisibleItemCount(); assertEquals(initialExpected, initialActual); //expand first group list.expandedGroupIndexes[0] = true; //new state int newExpected = 9; int newActual = list.getVisibleItemCount(); assertEquals(newExpected, newActual); }
public void checkChild(boolean checked, int groupIndex, int childIndex) { CheckedExpandableGroup group = (CheckedExpandableGroup) expandableList.groups.get(groupIndex); group.onChildClicked(childIndex, checked); if (childrenUpdateListener != null) { //only update children check states if group is expanded boolean isGroupExpanded = expandableList.expandedGroupIndexes[groupIndex]; if (isGroupExpanded) { childrenUpdateListener.updateChildrenCheckState( expandableList.getFlattenedFirstChildIndex(groupIndex), group.getItemCount()); } } }
/** * @return the number of group and child objects currently expanded * @see ExpandableList#getVisibleItemCount() */ @Override public int getItemCount() { return expandableList.getVisibleItemCount(); }
/** * Gets the view type of the item at the given position. * * @param position The flat position in the list to get the view type of * @return {@value ExpandableListPosition#CHILD} or {@value ExpandableListPosition#GROUP} * @throws RuntimeException if the item at the given position in the list is not found */ @Override public int getItemViewType(int position) { return expandableList.getUnflattenedPosition(position).type; }
/** * Clear any choices previously checked */ public void clearChoices() { childCheckController.clearCheckStates(); //only update the child views that are visible (i.e. their group is expanded) for (int i = 0; i < getGroups().size(); i++) { ExpandableGroup group = getGroups().get(i); if (isGroupExpanded(group)) { notifyItemRangeChanged(expandableList.getFlattenedFirstChildIndex(i), group.getItemCount()); } } }
@Override public void onChildCheckChanged(View view, boolean checked, int flatPos) { ExpandableListPosition listPos = expandableList.getUnflattenedPosition(flatPos); childCheckController.onChildCheckChanged(checked, listPos); if (childClickListener != null) { childClickListener.onCheckChildCLick(view, checked, (CheckedExpandableGroup) expandableList.getExpandableGroup(listPos), listPos.childPos); } }
/** * @param flatPos The flat list position of the group * @return false if the group is expanded, *after* the toggle, true if the group is now collapsed */ public boolean toggleGroup(int flatPos) { ExpandableListPosition listPos = expandableList.getUnflattenedPosition(flatPos); boolean expanded = expandableList.expandedGroupIndexes[listPos.groupPos]; if (expanded) { collapseGroup(listPos); } else { expandGroup(listPos); } return expanded; }
public void clearChoices() { childCheckController.clearCheckStates(); //only update the child views that are visible (i.e. their group is expanded) for (int i = 0; i < getGroups().size(); i++) { ExpandableGroup group = getGroups().get(i); if (isGroupExpanded(group)) { notifyItemRangeChanged(expandableList.getFlattenedFirstChildIndex(i), group.getItemCount()); } } }
/** * @return list of indexes of all checked child items */ public List<Integer> getCheckedPositions() { List<Integer> selected = new ArrayList<>(); for (int i = 0; i < expandableList.groups.size(); i++) { if (expandableList.groups.get(i) instanceof CheckedExpandableGroup) { CheckedExpandableGroup group = (CheckedExpandableGroup) expandableList.groups.get(i); for (int j = 0; j < group.getItemCount(); j++) { if (group.isChildChecked(j)) { long packedPosition = ExpandableListView.getPackedPositionForChild(i, j); selected.add(expandableList.getFlattenedChildIndex(packedPosition)); } } } } return selected; }
/** * Gets the view type of the item at the given position. * * @param position The flat position in the list to get the view type of * @return if the flat position corresponds to a child item, this will return the value returned * by {@code getChildViewType}. if the flat position refers to a group item this will return the * value returned by {@code getGroupViewType} */ @Override public int getItemViewType(int position) { ExpandableListPosition listPosition = expandableList.getUnflattenedPosition(position); ExpandableGroup group = expandableList.getExpandableGroup(listPosition); int viewType = listPosition.type; switch (viewType) { case ExpandableListPosition.GROUP: return getGroupViewType(position, group); case ExpandableListPosition.CHILD: return getChildViewType(position, group, listPosition.childPos); default: return viewType; } }
@Override public void onBindChildViewHolder(CCVH holder, int flatPosition, ExpandableGroup group, int childIndex) { ExpandableListPosition listPosition = expandableList.getUnflattenedPosition(flatPosition); holder.onBindViewHolder(flatPosition, childCheckController.isChildChecked(listPosition)); onBindCheckChildViewHolder(holder, flatPosition, (CheckedExpandableGroup) group, childIndex); }
/** * Implementation of Adapter.onBindViewHolder(RecyclerView.ViewHolder, int) * that determines if the list item is a group or a child and calls through * to the appropriate implementation of either {@link #onBindGroupViewHolder(GroupViewHolder, * int, * ExpandableGroup)} * or {@link #onBindChildViewHolder(ChildViewHolder, int, ExpandableGroup, int)}. * * @param holder Either the GroupViewHolder or the ChildViewHolder to bind data to * @param position The flat position (or index in the list of {@link * ExpandableList#getVisibleItemCount()} in the list at which to bind */ @Override public void onBindViewHolder(ViewHolder holder, int position) { ExpandableListPosition listPos = expandableList.getUnflattenedPosition(position); ExpandableGroup group = expandableList.getExpandableGroup(listPos); switch (listPos.type) { case ExpandableListPosition.GROUP: onBindGroupViewHolder((GVH) holder, position, group); if (isGroupExpanded(group)) { ((GVH) holder).expand(); } else { ((GVH) holder).collapse(); } break; case ExpandableListPosition.CHILD: onBindChildViewHolder((CVH) holder, position, group, listPos.childPos); break; } }
/** * Called when a group is expanded * * @param positionStart the flat position of the first child in the {@link ExpandableGroup} * @param itemCount the total number of children in the {@link ExpandableGroup} */ @Override public void onGroupExpanded(int positionStart, int itemCount) { //update header int headerPosition = positionStart - 1; notifyItemChanged(headerPosition); // only insert if there items to insert if (itemCount > 0) { notifyItemRangeInserted(positionStart, itemCount); if (expandCollapseListener != null) { int groupIndex = expandableList.getUnflattenedPosition(positionStart).groupPos; expandCollapseListener.onGroupExpanded(getGroups().get(groupIndex)); } } }