ListView의 checkbox와 다중 선택 기능 처리하기/글꼴과 색상 변경

2019. 8. 7. 17:07

<ListView 기본 이외 커스텀 구성시 기본 루트>

1. 리스트뷰 아이템에 대한 레이아웃을 구성
2. 레이아웃에 출력될 데이터에 대한 새로운 클래스를 정의
3. 사용자 데이터를 레이아웃에 정의된 형태의 view로 변환하기 위한
어뎁터 클래스도 상속받아서 필요한 함수를 채워줘야 한다

-> 확장되는 기능을 가지는 리스트 뷰를 커스텀리스트 뷰라고 말함
 

다시말해 정리하자면..

<워크 플로우 정리>
1. ListView가 표시될 위치 결정(Layout 리소스 XML 작성)
2. 사용자 데이터 정의(String 타입의 배열 선언)
3. Adapter 생성 후 ListView에 지정
4. ListView 클릭 이벤트 처리

 

이 순서대로 한 코드는 다음과 같다

1. ListView가 표시될 위치 결정(Layout 리소스 XML 작성) 

1
2
3
4
5
6
7
8
9
10
11
12
13
 <LinearLayout
            android:layout_width="370dp"
            android:layout_height="280dp"
            android:background="@drawable/spinner_box">
 
           <ListView
               android:id="@+id/choose_subjects_List"
               android:layout_width="match_parent"
               android:layout_height="wrap_content"
               android:choiceMode="multipleChoice">
           </ListView>
 
        </LinearLayout>
 
 

화면에 표시될 xml 파일에서 Linar 레이아웃 안에 ListView를 설정한다 결과 화면은 위의 사진을 참고하자.

뒤에서 ListView의 글꼴 바꾸는 방법에 대해서도 설명하겠다.

 

2. 사용자 데이터 정의(String 타입의 배열 선언) 

1
2
 final String[] subject_select = {"웹 프로그래밍","컴퓨터 프로그래밍3","알고리즘","창의 소프트웨어 설계","모바일 소프트웨어 설계",
                                    "인공지능""선형대수학""객체지향 설계""컴퓨터 구조"}; //2번 String 타입의 배열 선언
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

간단하게 데이터들을 배열로 선언해놓았다. 총 데이터의 개수는 9개이다.

 

3. Adapter 생성 후 ListView에 지정 

1
2
3
4
 /************ListView*******/
 final ArrayAdapter adapter = new ArrayAdapter(this, R.layout.simple_list_item, subject_select);
 final ListView listview = (ListView)findViewById(R.id.choose_subjects_List);
 listview.setAdapter(adapter);
 

adapter: 말 그대로 데이터와 리스트뷰를 연결하여 그 폼에 맞게 나타내주는 역할을 하는 것이다.

어뎁터를 생성한 후에(여기서 디자인을 적용한다. R.layout.simple_list_item가 리스트뷰의 커스텀 디자인이 된다.)

이 어뎁터를 리스트 뷰에 적용해주면 된다.


-> String 배열을 저장해야 하므로 ArrayAdapter를 사용
ArrayAdapter(Context context, int resource, T[] objects)
- context: 어플리케이션 전역 환경 정보에 대한 인터페이스

(여기서는 this)
- resource: View로 매핑될 리소스id (TextView 위젯으로 구성된 ListView 아이템 리소스id)

(여기서는 R.layout.simple_list_item)
- objects: 배열로 선언된 사용자 데이터

(여기서는 subject_select)
simple_list_item_multiple_choice(체크박스까지 나옴)
simple_expandable_list_item_2(기본 테마, 아무것도 안 나옴)

기본 테마를 응용해서 폰트나 글씨 색을 바꿀 수 있다. 하지만 ListView는 조금 다르다.
원래 있는 파일을 복사해서 layout 파일에 다른 layout파일을 만드는 것이다.
기존에 만들어져 있는 테마 파일 코드를 복사해와서 글씨 설정을 조금만 바꿔주면 된다. 코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<CheckedTextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="?android:attr/listPreferredItemHeightSmall"
    android:textAppearance="?android:attr/textAppearanceListItemSmall"
    android:gravity="center_vertical"
    android:checkMark="?android:attr/listChoiceIndicatorMultiple"
    android:paddingStart="?android:attr/listPreferredItemPaddingStart"
    android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
    android:textColor="@color/originText"
    android:textSize="15dp"
    android:fontFamily="@font/scdream3"/>
 



<복수 선택을 위해서>

선택 기능을 만들기 위해서는 리스트 뷰의 choiceMode 속성을 사용한다.
어떤 값을 지정하느냐에 따라 다중 선택 또는 단일 선택 모드가 결정 됨
단일: singleChoice 다중:multipleChoice (ex. android:choiceMode="multipleChoice")

 

우선 코드는 아래와 같다.

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
  next_btn.setOnClickListener(new View.OnClickListener() { //다음으로 화면 이동
            @Override
            public void onClick(View view) {
                SparseBooleanArray checkedItems = listview.getCheckedItemPositions(); //체크박스로 체크한 셀의 정보를 담고 있는 희소 논리 배열 얻어오기
                int count = adapter.getCount(); //전체 몇개인지 세기
 
                if(checkedItems.size()!=0){
                    for(int i=count-1; i>=0; i--){
                        if(checkedItems.get(i))//희소 논리 배열의 해당 인덱스가 선택되어 있다면
                            subject.add(subject_select[i]) ; //arrayList에 추가하기
                            ++index;
                            Log.d("데이터확인"String.valueOf(checkedItems.get(i)));
                        }
                        Intent intent = new Intent(
                                getApplicationContext(),
                                SelectTimeSetActivity.class);
                        intent.putExtra("subject",subject.toArray()); //체크박스로 선택한 객체만 넘어오게 해야 함
                        intent.putExtra("Write", Write); //정보 전송 -> 학점(int)
                        intent.putExtra("Grade", Grade); //정보 전송 -> 몇학년인지(int)
                        startActivity(intent);
                        overridePendingTransition(00);
                    }
                } else {
                    Toast.makeText(ChooseSubjectsActivity.this"꼭 필수로 들을 과목을 선택해주세요.", Toast.LENGTH_SHORT).show();
                }
                listview.clearChoices() ;
                adapter.notifyDataSetChanged();
                //화면 전환 및 정보 전송
 
            }
        });
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
http://colorscripter.com/info#e" target="_blank" style="text-decoration:none;color:white">cs

처리는 Next버튼을 눌렀을 때 선택한 것들이 한번에 처리되도록 구현했다.

SpareseBooleanArray값을 리턴하는 getCheckedItemPositions()함수, 이 함수는 선택된 아이템을 가져오기 위해 getCheckedItemPositions()함수를 사용한다. 한마디로 선택된 것들을 알 수 있게 만드는 함수이다.

 

if문을 사용하여 만약에 아무것도 체크되지 않았다면 체크를 유도하는 안내문이 뜨고, 그렇지 않으면 동작을 실행하게 동작을 구현했다.

 

if(checkItems.get(i)는 이 항목이 for문을 돌면서 작동하는 조건문으로, i 인덱스의 아이템이 체크되었는지 안되었는지 확인해주는 조건문이다. 만약에 이에 해당되면 그 리스트 안에 있는 값을 다른 최종 값을 담는 리스트에 추가하는 형식으로 체크되어있는 것들을 체크하였다.


adapter.notifyDataSetChanged(); :이 함수는 아뎁터에 모델이 바뀌었다고 알리는 것(삭제나 리스트 수정 시)

현재는 꼭 해주지 않아도 되는 코드지만 연습 겸 적어보았다.

 

BELATED ARTICLES

more