ExpandableListView를 사용하지 않고 ListView의 항목중 하나의 항목만 확장되도록 할 수 없나요?

조회수 1316회

ExpandableListView를 사용하지 않은 상태에서

ListView에

"AA" ,"BB", "CC", "DD" 라는 항목이 있고 이 4개의 항목중에 "DD" 에만 자식노드로 "xxx", "yyy" 를 가지게 할 수는 없나요? 그리고 DD를 눌렀을 때 펼쳐지는 형식으로.

정확히 말씀드리면 기능 자체는 ExpandableListView와 동일합니다. 그런데 이걸 Ex를 사용하지 않고 일반 ListView에 하나의 항목에만 적용하고 싶습니다.

어떻게 해야할까요?

  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 간단한 예제 코드를 작성해 보았습니다. RecyclerView 를 사용하시는게 좋지만 ListView 를 사용하고 있으셔서 ListView 로 작성하였습니다.

    activity_test.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".TestActivity">
    
        <ListView
            android:id="@+id/listView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
    </RelativeLayout>
    

    TestActivity.java

    public class TestActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_test);
            final String[] nameArray = {
                    "Brill/Color", "Display", "Echo", "Alert Settings",
                    "Tuning", "Others", "Target", "OS/Barge Mark", "TT",
                    "AIS", "System", "Key Operation", "Touch Operation"};
    
            final List<ListItem> dataSet = new ArrayList<>();
            for (String name : nameArray) {
                dataSet.add(new ListItem(name));
            }
    
            final TestAdapter adapter = new TestAdapter(dataSet);
            final ListView listView = findViewById(R.id.listView);
            listView.setAdapter(adapter);
            listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    dataSet.get(position).isExpand = !dataSet.get(position).isExpand;
                    adapter.notifyDataSetChanged();
                }
            });
        }
    
        static class TestAdapter extends BaseAdapter {
    
            final List<ListItem> dataSet;
    
            TestAdapter(List<ListItem> dataSet) {
                this.dataSet = dataSet;
            }
    
            @Override
            public int getCount() {
                return dataSet.size();
            }
    
            @Override
            public ListItem getItem(int position) {
                return dataSet.get(position);
            }
    
            @Override
            public long getItemId(int position) {
                return 0;
            }
    
            @Override
            public View getView(int position, View convertView, ViewGroup parent) {
                ViewHolder holder;
                if (convertView == null) {
                    convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.expandable_row, null);
                    holder = new ViewHolder();
                    holder.title = convertView.findViewById(R.id.title);
                    holder.expandableSection = convertView.findViewById(R.id.expand_section);
                    convertView.setTag(holder);
                } else {
                    holder = (ViewHolder) convertView.getTag();
                }
                holder.title.setText(getItem(position).name);
                holder.expandableSection.setVisibility(getItem(position).isExpand ? View.VISIBLE : View.GONE);
                return convertView;
            }
    
            class ViewHolder {
                TextView title;
                FrameLayout expandableSection;
            }
        }
    
        static class ListItem {
            public String name;
            public boolean isExpand = false;
    
            ListItem(String name) {
                this.name = name;
            }
        }
    }
    

    ArrayAdapter 를 사용하고 계셨지만 말씀하신 기능을 위해서는 BaseAdapter 를 상속받아서 CustomAdapter 를 구현해야 합니다.

    ListView 에 사용 될 String 배열을 expand 를 위해 ListItem 이라는 data 객체에 넣었습니다. 그리고 setOnItemClickListener() 에서는 선택 된 position 의 data 객체에 있는 isExpand 값을 변경해줍니다. 그후, Adapter 의 notifyDataSetChanged() 를 호출하여 List 를 갱신하면 getView() 에 구현 된 것처럼 isExpand 값에 따라 확장 영역을 Visible / Gone 시킴으로써 동작하게 됩니다.

    각 List row 에 대한 layout 은 아래와 같이 작성하였습니다.

    expandable_row.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:cardUseCompatPadding="true">
    
        <android.support.constraint.ConstraintLayout
            android:id="@+id/row_frame"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="100dp"
                android:gravity="center_vertical"
                android:paddingLeft="10dp"
                android:paddingTop="10dp"
                android:textColor="@android:color/black"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintTop_toTopOf="parent" />
    
            <FrameLayout
                android:id="@+id/expand_section"
                android:layout_width="0dp"
                android:layout_height="200dp"
                android:background="@color/colorPrimary"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintLeft_toLeftOf="parent"
                app:layout_constraintRight_toRightOf="parent"
                app:layout_constraintTop_toBottomOf="@id/title" />
    
        </android.support.constraint.ConstraintLayout>
    </android.support.v7.widget.CardView>
    

    복잡한것 같지만, 흐름을 이해하시면 생각보다 간단한 구조를 갖고 있습니다 :) 도움이 되셨으면 좋겠네요.

    • (•́ ✖ •̀)
      알 수 없는 사용자
    • 뭔가 굉장히 복잡해보이네요. 한번 도전해보고 다시 문의드리겠습니다! 알 수 없는 사용자 2018.7.10 08:51
    • 일단 이 문제에 대해서는 좀 나중으로 미루기로 해서 지금 당장 테스트를 해볼 수는 없지만 다음번에 꼭 해보겠습니다! 알 수 없는 사용자 2018.7.10 14:57

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)