본문 바로가기
안드로이드/개발자 일상

안드로이드 ExpandableListAdapter( 하위 목록까지 보여주기 )

by 차누감 2020. 4. 23.

목록을 보여줄 때는 보통 RecyclerView를 이용하여 RecyclerAdapter를 사용할 것입니다.

그러나 한 항목에 하위 항목까지 보여주려고 하면 많이 불편하실 겁니다.

그래서 편하게 하위 항목까지 보열 줄 수 있는 ExpandableListAdapter 예제입니다.

<실행 화면>


RecyclerView를 사용하고 Adapter만 ExpandableListAdapter로 사용하는 것입니다.

리스트만 보여줄 것이기 때문에 화면에는 RecyclerView만 놓습니다.

activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
       android:id="@+id/recyclerview"
       android:layout_width="match_parent"
       android:layout_height="match_parent"/>
 
 
 

상위 목록 모양과 하위 목록 모양을 만들어 줍니다.

list_header.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:background="#FFDADA">
 
    <TextView
        android:id="@+id/header_title"
        android:textColor="#191B1E"
        android:textSize="18sp"
        android:gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
 
    <ImageView
        android:id="@+id/btn_expand_toggle"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_marginTop="20dp"
        android:layout_marginRight="20dp"
        android:src="@drawable/ic_arrow_downward_black_24dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
 

list_child.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
    android:layout_width="match_parent"
    android:layout_height="70dp"
    android:background="#FDE9E9">
 
    <TextView
        android:id="@+id/child_title"
        android:textColor="#837D7D"
        android:textSize="18sp"
        android:gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="20dp"
        android:layout_marginLeft="20dp"
        android:layout_marginTop="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"/>
 
    <Button
        android:id="@+id/btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginRight="20dp"
        android:text="버튼"
        android:background="#FFEFEF"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

이제 ExpandableListAdapter를 만듭니다.

ExpandableListAdapter.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
package com.example.ex_expandablelistadapter;
 
import android.content.Context;
 
 
 
public class ExpandableListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
    public static final int HEADER = 0;
    public static final int CHILD = 1;
 
    private List<Item> data;
 
    public ExpandableListAdapter(List<Item> data) {
        this.data = data;
    }
 
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int type) {
        View view = null;
        Context context = parent.getContext();
        switch (type) {
            case HEADER:
                LayoutInflater inflaterHeader = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflaterHeader.inflate(R.layout.list_header, parent, false);
                ListHeaderViewHolder header = new ListHeaderViewHolder(view);
                return header;
            case CHILD:
                LayoutInflater inflaterChild = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                view = inflaterChild.inflate(R.layout.list_child, parent, false);
                ListChildViewHolder child = new ListChildViewHolder(view);
                return child;
 
        }
        return null;
    }
 
    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
        final Item item = data.get(position);
        switch (item.type) {
            case HEADER:
                final ListHeaderViewHolder itemController = (ListHeaderViewHolder) holder;
                itemController.refferalItem = item;
                itemController.header_title.setText(item.text);
                if (item.invisibleChildren == null) {
                    itemController.btn_expand_toggle.setImageResource(R.drawable.ic_arrow_upward_black_24dp);
                } else {
                    itemController.btn_expand_toggle.setImageResource(R.drawable.ic_arrow_downward_black_24dp);
                }
                itemController.btn_expand_toggle.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        if (item.invisibleChildren == null) {
                            item.invisibleChildren = new ArrayList<Item>();
                            int count = 0;
                            int pos = data.indexOf(itemController.refferalItem);
                            while (data.size() > pos + 1 && data.get(pos + 1).type == CHILD) {
                                item.invisibleChildren.add(data.remove(pos + 1));
                                count++;
                            }
                            notifyItemRangeRemoved(pos + 1, count);
                            itemController.btn_expand_toggle.setImageResource(R.drawable.ic_arrow_downward_black_24dp);
                        } else {
                            int pos = data.indexOf(itemController.refferalItem);
                            int index = pos + 1;
                            for (Item i : item.invisibleChildren) {
                                data.add(index, i);
                                index++;
                            }
                            notifyItemRangeInserted(pos + 1, index - pos - 1);
                            itemController.btn_expand_toggle.setImageResource(R.drawable.ic_arrow_upward_black_24dp);
                            item.invisibleChildren = null;
                        }
                    }
                });
                break;
            case CHILD:
                final ListChildViewHolder itemController1 = (ListChildViewHolder) holder;
                itemController1.refferalItem = item;
                itemController1.child_title.setText(item.text);
 
                break;
        }
    }
 
    @Override
    public int getItemViewType(int position) {
        return data.get(position).type;
    }
 
 
    @Override
    public int getItemCount() {
        return data.size();
    }
 
    private static class ListHeaderViewHolder extends RecyclerView.ViewHolder {
        public TextView header_title;
        public ImageView btn_expand_toggle;
        public Item refferalItem;
 
        public ListHeaderViewHolder(View itemView) {
            super(itemView);
            header_title = (TextView) itemView.findViewById(R.id.header_title);
            btn_expand_toggle = (ImageView) itemView.findViewById(R.id.btn_expand_toggle);
        }
    }
    private static class ListChildViewHolder extends RecyclerView.ViewHolder {
        public TextView child_title;
        public Button btn;
        public Item refferalItem;
 
        public ListChildViewHolder(View itemView) {
            super(itemView);
            child_title = (TextView) itemView.findViewById(R.id.child_title);
            btn =  itemView.findViewById(R.id.btn);
        }
    }
 
    public static class Item {
        public int type;
        public String text;
        public List<Item> invisibleChildren;
 
        public Item() {
        }
 
        public Item(int type, String text) {
            this.type = type;
            this.text = text;
        }
    }
}
 
 

이제 MainActivity.java에 적용하면 됩니다.

MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.ex_expandablelistadapter;
 
 
 
 
public class MainActivity extends AppCompatActivity {
 
    private RecyclerView recyclerview;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
 
        recyclerview = findViewById(R.id.recyclerview);
        recyclerview.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));
        List<ExpandableListAdapter.Item> data = new ArrayList<>();  // 데이터를 담을 List
 
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, "운동"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "축구"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "농구"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "배구"));
 
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.HEADER, "과목"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "국어"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "영어"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "수학"));
        data.add(new ExpandableListAdapter.Item(ExpandableListAdapter.CHILD, "과학"));
 
        recyclerview.setAdapter(new ExpandableListAdapter(data));
    }// onCreate()..
}// MainActivity class..
 
 

<실행 화면>

댓글