I\'m trying to implement a recyclerview that behaves like my sketch below:
The idea is that there is a parent list, when an list item in the parent list is tapp
1.ExpandableRecyclerAdapter.class
public abstract class ExpandableRecyclerAdapter extends RecyclerView.Adapter {
protected Context mContext;
protected List allItems = new ArrayList<>();
protected List visibleItems = new ArrayList<>();
private List 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 {
ImageView arrow;
public HeaderViewHolder(View view) {
super(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
toggleExpandedItems(getLayoutPosition(),false);
/*if(isExpanded(getLayoutPosition())){
collapseItems(getLayoutPosition(),false);
}else {
expandItems(getLayoutPosition(),true);
}*/
}
});
}
public HeaderViewHolder(View view, final ImageView 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);
} else {
closeArrow(arrow);
}
}
public void bind(int position) {
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= 0;
}
@Override
public int getItemViewType(int position) {
return visibleItems.get(position).ItemType;
}
public void setItems(List items) {
allItems = items;
List visibleItems = new ArrayList<>();
expandMap.clear();
indexList.clear();
for (int i=0; i newIndexList = new ArrayList<>();
for (int i=0; i 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) {
view.animate().setDuration(ARROW_ROTATION_DURATION).rotation(180);
}
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;
}
}
2.activity_main
3.item_header
4.item_content.xml
5.Adapter
public class PeopleAdapter extends ExpandableRecyclerAdapter {
public static final int TYPE_PERSON = 1001;
public PeopleAdapter(Context context) {
super(context);
setItems(getSampleItems());
}
public static 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;
public HeaderViewHolder(View view) {
super(view, (ImageView) view.findViewById(R.id.img_arrow));
name = (TextView) view.findViewById(R.id.txt_header_name);
}
public void bind(int position) {
super.bind(position);
name.setText(visibleItems.get(position).Text);
}
}
public class PersonViewHolder extends ExpandableRecyclerAdapter.ViewHolder {
EditText name;
public PersonViewHolder(View view) {
super(view);
name = (EditText) view.findViewById(R.id.edt_description);
}
public void bind(int position) {
name.setText(name.getText());
}
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
switch (viewType) {
case TYPE_HEADER:
return new HeaderViewHolder(inflate(R.layout.item_header, parent));
case TYPE_PERSON:
default:
return new PersonViewHolder(inflate(R.layout.item_content, 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 getSampleItems() {
List items = new ArrayList<>();
items.add(new PeopleListItem("Friends"));
items.add(new PeopleListItem("", ""));
items.add(new PeopleListItem("Friends"));
items.add(new PeopleListItem("", ""));
return items;
}
}
6.MainActivity.java
public class MainActivity extends AppCompatActivity {
RecyclerView recycler;
PeopleAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recycler = (RecyclerView) findViewById(R.id.main_recycler);
adapter = new PeopleAdapter(this);
adapter.setMode(ExpandableRecyclerAdapter.MODE_ACCORDION);
recycler.setLayoutManager(new LinearLayoutManager(this));
recycler.setAdapter(adapter);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_expand_all:
adapter.expandAll();
return true;
case R.id.action_collapse_all:
adapter.collapseAll();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}