Creating an expandable RecyclerView

后端 未结 4 1383
旧巷少年郎
旧巷少年郎 2021-01-31 11:11

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

4条回答
  •  温柔的废话
    2021-01-31 11:14

    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);
        }
    }
    }
    

提交回复
热议问题