In my example, I have Expandable recyclerview. For the recyclerview each item have checkbox like if we click on parent item then child list will open. parent and child both have checkbox. If we click on parent checkbox child items with check box will open and parent item is checked.
My problem is when user click on parent item checkbox, it will checked and child list will open but if user select any child item of that parent, parent checkbox should be unchecked.
Following is my code.
Main Activity:-
public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
MyAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerView=(RecyclerView)findViewById(R.id.main_recycler);
adapter=new MyAdapter(this);
adapter.setMode(ExpandableRecyclerAdapter.MODE_ACCORDION);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(adapter);
}
}
My Adapter class:-
public class MyAdapter extends ExpandableRecyclerAdapter<MyAdapter.PeopleListItem> {
public static final int TYPE_PERSON = 1001;
public MyAdapter(Context context) {
super(context);
setItems(getSampleItems());
}
public class PeopleListItem extends ExpandableRecyclerAdapter.ListItem {
public String Text;
public PeopleListItem(String group) {
super(TYPE_HEADER);
Text = group;
}
public PeopleListItem(String first, String last) {
super(TYPE_PERSON);
Text = first + " " + last;
}
}
public class HeaderViewHolder extends ExpandableRecyclerAdapter.HeaderViewHolder {
TextView name;
CheckBox parent_check;
public HeaderViewHolder(View view) {
// super(view, (ImageView) view.findViewById(R.id.item_arrow));
super(view, (CheckBox) view.findViewById(R.id.parent_check));
parent_check=(CheckBox)view.findViewById(R.id.parent_check);
name = (TextView) view.findViewById(R.id.item_header_name);
}
public void bind(int position) {
super.bind(position);
name.setText(visibleItems.get(position).Text);
}
}
public class PersonViewHolder extends ExpandableRecyclerAdapter.ViewHolder {
TextView name;
CheckBox child_check;
public PersonViewHolder(View view) {
super(view);
name = (TextView) view.findViewById(R.id.item_name);
child_check=(CheckBox)view.findViewById(R.id.child_check);
}
public void bind(final int position) {
name.setText(visibleItems.get(position).Text);
child_check.setChecked(false);
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_HEADER:
return new HeaderViewHolder(inflate(R.layout.parent_item, parent));
case TYPE_PERSON:
default:
return new PersonViewHolder(inflate(R.layout.child_item, parent));
}
}
@Override
public void onBindViewHolder(ExpandableRecyclerAdapter.ViewHolder holder, int position) {
switch (getItemViewType(position)) {
case TYPE_HEADER:
((HeaderViewHolder) holder).bind(position);
break;
case TYPE_PERSON:
default:
((PersonViewHolder) holder).bind(position);
break;
}
}
private List<PeopleListItem> getSampleItems() {
List<PeopleListItem> items = new ArrayList<>();
items.add(new PeopleListItem("Java"));
items.add(new PeopleListItem("Java","JDK Beta"));
items.add(new PeopleListItem("Java","JDK 1.0"));
items.add(new PeopleListItem("Java","JDK 1.1"));
items.add(new PeopleListItem("Java","JDK 1.2"));
items.add(new PeopleListItem("Java","JDK 1.3"));
items.add(new PeopleListItem("Java","JDK 1.4"));
items.add(new PeopleListItem("Java","JDK 1.5"));
items.add(new PeopleListItem("Java","JDK 1.6"));
items.add(new PeopleListItem("Java","JDK 1.7"));
items.add(new PeopleListItem("Java","JDK 1.8"));
items.add(new PeopleListItem("Android"));
items.add(new PeopleListItem("Cupcake","1.5"));
items.add(new PeopleListItem("Donut","1.6"));
items.add(new PeopleListItem("Eclair","2.0"));
items.add(new PeopleListItem("Froyo","2.2"));
items.add(new PeopleListItem("Gingerbread","2.3"));
items.add(new PeopleListItem("Honeycomb","3.0"));
items.add(new PeopleListItem("IceCreamSandwich","4.0"));
items.add(new PeopleListItem("Jellybean","4.1"));
items.add(new PeopleListItem("KitKat","4.4"));
items.add(new PeopleListItem("Lollipop","5.0"));
items.add(new PeopleListItem("Marshmallow","6.0"));
items.add(new PeopleListItem("Nougat","7.0"));
items.add(new PeopleListItem("DotNet"));
items.add(new PeopleListItem("FrameWork","1.0"));
items.add(new PeopleListItem("FrameWork","1.1"));
items.add(new PeopleListItem("FrameWork","2.0"));
items.add(new PeopleListItem("FrameWork","3.0"));
items.add(new PeopleListItem("FrameWork","4"));
items.add(new PeopleListItem("FrameWork","4.5"));
items.add(new PeopleListItem("FrameWork","4.5.1"));
items.add(new PeopleListItem("FrameWork","4.5.2"));
items.add(new PeopleListItem("FrameWork","4.6"));
items.add(new PeopleListItem("FrameWork","4.6.1"));
items.add(new PeopleListItem("FrameWork","4.6.2"));
return items:
}
}
ExpandableRecyclerAdapter class:-
public abstract class ExpandableRecyclerAdapter<T extends ExpandableRecyclerAdapter.ListItem> extends RecyclerView.Adapter<ExpandableRecyclerAdapter.ViewHolder> {
protected Context mContext;
protected List<T> allItems = new ArrayList<>();
protected List<T> visibleItems = new ArrayList<>();
private List<Integer> indexList = new ArrayList<>();
private SparseIntArray expandMap = new SparseIntArray();
private int mode;
protected static final int TYPE_HEADER = 1000;
private static final int ARROW_ROTATION_DURATION = 150;
public static final int MODE_NORMAL = 0;
public static final int MODE_ACCORDION = 1;
public ExpandableRecyclerAdapter(Context context) {
mContext = context;
}
public static class ListItem {
public int ItemType;
public ListItem(int itemType) {
ItemType = itemType;
}
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public int getItemCount() {
return visibleItems == null ? 0 : visibleItems.size();
}
protected View inflate(int resourceID, ViewGroup viewGroup) {
return LayoutInflater.from(mContext).inflate(resourceID, viewGroup, false);
}
public class ViewHolder extends RecyclerView.ViewHolder {
public ViewHolder(View view) {
super(view);
}
}
public class HeaderViewHolder extends ViewHolder {
CheckBox arrow;
// ImageView arrow;
/* public HeaderViewHolder(View view, final ImageView arrow) {
super(view);
this.arrow = arrow;
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick();
}
});
}*/
public HeaderViewHolder(View view, final CheckBox arrow) {
super(view);
this.arrow = arrow;
arrow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handleClick();
}
});
}
protected void handleClick() {
if (toggleExpandedItems(getLayoutPosition(), false)) {
// openArrow(arrow);
arrow.setChecked(true);
} else {
// closeArrow(arrow);
arrow.setChecked(false);
}
}
public void bind(int position) {
arrow.setChecked(isExpanded(position));
// arrow.setChecked(false);
/* arrow.setRotation(isExpanded(position) ? 90 : 0);*/
}
}
public boolean toggleExpandedItems(int position, boolean notify) {
if (isExpanded(position)) {
collapseItems(position, notify);
return false;
} else {
expandItems(position, notify);
if (mode == MODE_ACCORDION) {
collapseAllExcept(position);
}
return true;
}
}
public void expandItems(int position, boolean notify) {
int count = 0;
int index = indexList.get(position);
int insert = position;
for (int i=index+1; i<allItems.size() && allItems.get(i).ItemType != TYPE_HEADER; i++) {
insert++;
count++;
visibleItems.add(insert, allItems.get(i));
indexList.add(insert, i);
}
notifyItemRangeInserted(position + 1, count);
int allItemsPosition = indexList.get(position);
expandMap.put(allItemsPosition, 1);
if (notify) {
notifyItemChanged(position);
}
}
public void collapseItems(int position, boolean notify) {
int count = 0;
int index = indexList.get(position);
for (int i=index+1; i<allItems.size() && allItems.get(i).ItemType != TYPE_HEADER; i++) {
count++;
visibleItems.remove(position + 1);
indexList.remove(position + 1);
}
notifyItemRangeRemoved(position + 1, count);
int allItemsPosition = indexList.get(position);
expandMap.delete(allItemsPosition);
if (notify) {
notifyItemChanged(position);
}
}
public class StaticViewHolder extends ViewHolder {
public StaticViewHolder(View view) {
super(view);
}
}
public class ItemViewHolder extends ViewHolder {
public ItemViewHolder(View view) {
super(view);
}
}
protected boolean isExpanded(int position) {
int allItemsPosition = indexList.get(position);
return expandMap.get(allItemsPosition, -1) >= 0;
}
@Override
public int getItemViewType(int position) {
return visibleItems.get(position).ItemType;
}
public void setItems(List<T> items) {
allItems = items;
List<T> visibleItems = new ArrayList<>();
expandMap.clear();
indexList.clear();
for (int i=0; i<items.size(); i++) {
if (items.get(i).ItemType == TYPE_HEADER) {
indexList.add(i);
visibleItems.add(items.get(i));
}
}
this.visibleItems = visibleItems;
notifyDataSetChanged();
}
protected void notifyItemInserted(int allItemsPosition, int visiblePosition) {
incrementIndexList(allItemsPosition, visiblePosition, 1);
incrementExpandMapAfter(allItemsPosition, 1);
if (visiblePosition >= 0) {
notifyItemInserted(visiblePosition);
}
}
protected void removeItemAt(int visiblePosition) {
int allItemsPosition = indexList.get(visiblePosition);
allItems.remove(allItemsPosition);
visibleItems.remove(visiblePosition);
incrementIndexList(allItemsPosition, visiblePosition, -1);
incrementExpandMapAfter(allItemsPosition, -1);
notifyItemRemoved(visiblePosition);
}
private void incrementExpandMapAfter(int position, int direction) {
SparseIntArray newExpandMap = new SparseIntArray();
for (int i=0; i<expandMap.size(); i++) {
int index = expandMap.keyAt(i);
newExpandMap.put(index < position ? index : index + direction, 1);
}
expandMap = newExpandMap;
}
private void incrementIndexList(int allItemsPosition, int visiblePosition, int direction) {
List<Integer> newIndexList = new ArrayList<>();
for (int i=0; i<indexList.size(); i++) {
if (i == visiblePosition) {
if (direction > 0) {
newIndexList.add(allItemsPosition);
}
}
int val = indexList.get(i);
newIndexList.add(val < allItemsPosition ? val : val + direction);
}
indexList = newIndexList;
}
public void collapseAll() {
collapseAllExcept(-1);
}
public void collapseAllExcept(int position) {
for (int i=visibleItems.size()-1; i>=0; i--) {
if (i != position && getItemViewType(i) == TYPE_HEADER) {
if (isExpanded(i)) {
collapseItems(i, true);
}
}
}
}
public void expandAll() {
for (int i=visibleItems.size()-1; i>=0; i--) {
if (getItemViewType(i) == TYPE_HEADER) {
if (!isExpanded(i)) {
expandItems(i, true);
}
}
}
}
/*public static void openArrow(View view) {
((CheckBox) view).isChecked();
// view.animate().setDuration(ARROW_ROTATION_DURATION).rotation(90);
}
public static void closeArrow(View view) {
// view.animate().setDuration(ARROW_ROTATION_DURATION).rotation(0);
}*/
public int getMode() {
return mode;
}
public void setMode(int mode) {
this.mode = mode;
}
}
it is my code if anyone need more clarification i can give.
In this example if user click on first parent,that parent child items will display and parent checkbox will be checked.we can select any child even multiple child items.
But my Problem is i want when child item is selected that parent checkbox get unchecked.user can able to check single check box.
I try to implement but all my attempt are unsuccessful.If any one has any idea help me out.