[Android Studio] SQLite (2) & Spinner

노유성·2023년 4월 30일
0
post-thumbnail

🌞Spinner란


해당 그림처럼 목록을 선택할 수 있는 view를 의미한다. html에서 <select>태그와 기능이 비슷하다.

해당 포스팅에서는 DB에서 데이터를 가져온 후 해당 데이터로 Spinner를 만드는 예제를 살펴보겠다.

⭐레이아웃

		<LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">
                <TextView
                    android:layout_width="152dp"
                    android:layout_height="wrap_content"
                    android:text="운동 목록" />
                <Spinner
                    android:id="@+id/spinner"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>


            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1">
                <LinearLayout
                    android:id="@+id/exerciseListContainer"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:orientation="vertical">

                </LinearLayout>
            </ScrollView>
        </LinearLayout>
        

Spinner를 구성하고 Spinner에서 특정 카테고리를 선택하면 카테고리 하위에 존재하는 이이템들을 불러와 TextView로 만들어 레이아웃에 추가하기 위한 레이아웃 구성이다.

⭐기능구현

🪐카테고리 목록 가져오기

public List<String> readCategoryFromDb(){
        // Define a projection that specifies which columns from the database
        // you will actually use after this query.
        String[] projection = {
                "DISTINCT " + ExerciseType.ExerciseTypeEntry.COLUMN_CATEGORY
        };

        String sortOrder =
                ExerciseType.ExerciseTypeEntry.COLUMN_CATEGORY + " DESC";

        Cursor cursor = db_read.query(
                ExerciseType.ExerciseTypeEntry.TABLE_NAME,   // The table to query
                projection,             // The array of columns to return (pass null to get all)
                null,              // The columns for the WHERE clause
                null,          // The values for the WHERE clause
                null,                   // don't group the rows
                null,                   // don't filter by row groups
                sortOrder               // The sort order
        );

        List<String> category = new ArrayList<>();
        category.add("NO SELECT");
        while(cursor.moveToNext()) {
            String item = cursor.getString(0); // 0번째 인덱스의 데이터 가져오기
            category.add(item);
        }

        cursor.close(); // 커서 닫기

        return category;
    };

DB에 카테고리 리스트를 받아오는 메소드이다. 유의할 점은 cursor를 이용하고 나면 close()해주어야 한다.

🪐DB에서 카테고리에 해당하는 데이터 가져오기

public List<String> readExerciseListFromDb(@NonNull String selectedCategory){
        // Query 결과로 받아올 column 정의하기
        String[] projection = {
                ExerciseType.ExerciseTypeEntry.COLUMN_EXERCISE
        };

        // where절
        String selection = ExerciseType.ExerciseTypeEntry.COLUMN_CATEGORY + " = ?";
        String[] selectionArgs = { selectedCategory };

        // 정렬
        String sortOrder =
                ExerciseType.ExerciseTypeEntry.COLUMN_EXERCISE + " DESC";

        // Queyr 결과를 담은 cursor 가져오기
        Cursor cursor = db_read.query(
                ExerciseType.ExerciseTypeEntry.TABLE_NAME,   // The table to query
                projection,             // The array of columns to return (pass null to get all)
                selection,              // The columns for the WHERE clause
                selectionArgs,          // The values for the WHERE clause
                null,                   // don't group the rows
                null,                   // don't filter by row groups
                sortOrder               // The sort order
        );

        List<String> exerciseList = new ArrayList<>();
        while(cursor.moveToNext()) {
            String item = cursor.getString(0); // 0번째 인덱스의 데이터 가져오기
            exerciseList.add(item);
        }

        cursor.close(); // 커서 닫기

        return exerciseList;
    };

DB에 데이터를 요청하는 것이 대부분인 메소드이다. 후에 Spinner에서 특정 카테고리가 선택되면 해당 카테고리에 대한 정보를 받아 DB에 query를 날리는 기능을 한다.

🪐스피너 등록하기

 public void getSpinner() {
        List<String> dataList = readCategoryFromDb();
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(getContext(),
                android.R.layout.simple_spinner_item, dataList);

        spinner.setAdapter(adapter);
        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                // 선택된 항목 처리
                String selectedValue = parent.getItemAtPosition(position).toString();
                currCategory = selectedValue;
                setButtonFromExerciseList();
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {
                // 선택된 항목이 없는 경우 처리
            }
        });
    }

앞서 만들었던 readCategoryFromDb()를 이용해 카테고리 정보를 받아온 후 adapter를 생성한다. ArrayAdapter의 객체를 생성하는데 유의할 점은 여기서 제네릭 타입에서 String을 지정했다. (제네릭 타입에 대해서는 나중에 공부를 해야겠다..)

인자로는 3가지의 데이터를 받는다.

  1. 현재 context
  2. spinner item을 보여줄 layout 스타일
  3. item을 만들 String data list

직접 item을 지정한 layout을 이용해서 만드는 방법도 있는데 해당 예제는 DB와 직접 의사소통 해야하므로 layout을 이용해서 보여주지 않았다.
아이템을 지정한 후에는 setAdapter() method를 이용해 adapter를 등록했다.

그 다음 마지막으로 특정 item이 선택되었을 때를 다루는 이벤트리스너를 등록해주면 된다. 특정 아이템이 선택되었을 때 onItemSelected() 메소드를 오버라이딩해서 사용하고 전달받는 인자들을 이용해서 원하는 이벤트를 처리하면 된다. 해당 예제에서는 사전에 정의한 setButtonFromExerciseList()를 이용했다.

onItemSelected()에 전달되는 인자 3개를 유심히 살펴보고 사용하도록 하자.

🌌정리하며

Spinner 자체를 생성하는 것은 어렵지 않으나 이벤트가 발생했을 때 이벤트를 효율적으로 처리하는 방법에 대해서 고민을 해야할 것 같다. 특히 DB와 소통하며 데이터를 가져올 때 어떻게 하면 효율적일지, 또 DB에 날릴 query를 DBHelper에 정의하는 것이 좋을지 activity에 지정하는 것이 좋을 지 고민해보아야겠다.

profile
풀스택개발자가되고싶습니다:)

0개의 댓글