프로젝트 [자문자답 앱] - 문제 태그 추가

유의선·2024년 1월 25일
0

앱을 실사용함에 있어서, 문제가 많아질수록 문제를 분야별로 모아서 볼 수 있다면 더 좋을꺼라 생각해 기능을 추가하였다.


데이터베이스 수정

데이터베이스 테이블에 TAG 속성을 추가하였다.

    private class DatabaseHelper extends SQLiteOpenHelper{

        public DatabaseHelper(Context context){
            super(context, DATABSE_NAME, null, DATABASE_VERSION);
        }

        @Override
        public void onCreate(SQLiteDatabase db) {

            // 이미 존재하는 테이블 DROP
            String DROP_SQL = "drop table [" + TABLE_QUESTION + "]";
            try{
                db.execSQL(DROP_SQL);
                println("Drop Table.");
            }catch (Exception ex){
                Log.e(TAG, "Exception in DROP_SQL", ex);
            }

            // 테이블 생성
            String CREAT_SQL = "create table " + TABLE_QUESTION + "("
                    +" _id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "
                    +" TITLE TEXT DEFAULT '', "
                    +" QUESTION TEXT DEFAULT '', "
                    +" ANSWER TEXT DEFAULT '', "
                    +" TAG TEXT DEFAULT '' "    // added in VERSION 2
                    +")";
            try{
                db.execSQL(CREAT_SQL);
                println("Create Table.");
            }catch (Exception ex){
                Log.e(TAG,"Exception in CREATE_SQL", ex);
            }

        }

데이터베이스를 수정함에 따라 onUpgrade메소드를 이용해 업그레이드 하였다.

        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            if(oldVersion < 2){
                try{
                    db.beginTransaction();
                    db.execSQL("ALTER TABLE " + TABLE_QUESTION + " ADD COLUMN TAG TEXT DEFAULT ''");
                    db.setTransactionSuccessful();
                    println("Upgrading Database from version : " + oldVersion + "to " + newVersion + ".");
                }catch (IllegalStateException ex){
                    Log.e(TAG, "Exception in onUpgrage", ex);
                }finally {
                    db.endTransaction();
                }
            }
        }

레이아웃 수정

문제를 만들거나 수정하는 화면에선 태그를 입력하는 EditTextView를 추가하였고,
문제를 확인하는 화면에선 태그를 보여주는 TextView를,
문제 리스트를 보여주는 화면에선 태그를 선택할 수 있는 Spinner을 추가하였다.


태그별로 문제 모아보기

문제 목록에서 spinner에서 태그를 고르면 그 태그의 문제들만 보여주도록 만들었다.

// ListActivity.java

...


 		spinner = findViewById(R.id.spinner);

        ArrayList<String> items = new ArrayList<>();
        items.add("ALL");

        String sql = "select DISTINCT TAG FROM " + QuestionDatabase.TABLE_QUESTION;
        QuestionDatabase database = QuestionDatabase.getInstance(this);
        if(database != null){
            Cursor cursor = database.rawQuery(sql);

            int recordCount = cursor.getCount();
            for(int i = 0; i < recordCount; i++){
                cursor.moveToNext();

                String tag = cursor.getString(0);
                items.add(tag);
            }

            cursor.close();
        }

        ArrayAdapter<String> spinnerAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, items);
        spinnerAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(spinnerAdapter);

        spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
                String tag = items.get(position);

                if(tag.equals("ALL"))
                    loadQuestionListData();
                else
                    loadQuestionListDataByTag(tag);
            }

            @Override
            public void onNothingSelected(AdapterView<?> parent) {

            }
        });
        
...

    	// 리사이클러뷰에 문제 추가 메소드
   		public void loadQuestionListData() {
        adapter.deleteAllItem();
        adapter.notifyDataSetChanged();

        int recyclerviewItemsCount = adapter.getItemCount();
        for(int i = 0; i < recyclerviewItemsCount; i++){

        }

        int recordCount = 0;

        String sql = "select _id, TITLE, QUESTION, ANSWER, TAG FROM " + QuestionDatabase.TABLE_QUESTION + " order by _id ASC";

        QuestionDatabase database = QuestionDatabase.getInstance(this);
        if(database != null){
            Cursor cursor = database.rawQuery(sql);

            recordCount = cursor.getCount();

            for(int i = 0; i < recordCount; i++){
                cursor.moveToNext();

                int _id = cursor.getInt(0);
                String Title = cursor.getString(1);
                String Question = cursor.getString(2);
                String Answer = cursor.getString(3);
                String Tag = cursor.getString(4);

                adapter.addItem(new Question(_id, Title, Question, Answer, Tag));
            }

            cursor.close();
            adapter.notifyDataSetChanged();
        }

    }

    public void loadQuestionListDataByTag(String tag) {
        adapter.deleteAllItem();
        adapter.notifyDataSetChanged();

        int recordCount = 0;

        String sql = "select _id, TITLE, QUESTION, ANSWER, TAG FROM " + QuestionDatabase.TABLE_QUESTION + " where TAG = '" + tag + "' order by _id ASC";

        QuestionDatabase database = QuestionDatabase.getInstance(this);
        if(database != null){
            Cursor cursor = database.rawQuery(sql);

            recordCount = cursor.getCount();

            for(int i = 0; i < recordCount; i++){
                cursor.moveToNext();

                int _id = cursor.getInt(0);
                String Title = cursor.getString(1);
                String Question = cursor.getString(2);
                String Answer = cursor.getString(3);
                String Tag = cursor.getString(4);

                adapter.addItem(new Question(_id, Title, Question, Answer, Tag));
            }

            cursor.close();
            adapter.notifyDataSetChanged();
        }
    }

이를 위해 리사이클러뷰에 담기는 아이템의 클래스에 tag를 추가하였고,

리사이클러뷰에 사용하는 어댑터에 그 내용을 전부 삭제하는 메소드 deleteAllItem()를 추가하였다.

또한 문제를 푸는 화면으로 이동할 때, 지정해둔 태그를 Intent를 통해 문제 푸는 화면으로 전달하여 지정된 태그의 문제만을 풀 수 있도록 만들었다.

// SolveActivity.java

        adapter.setOnItemClickListener(new OnQuestionClickListener() {
            @Override
            public void onItemClick(QuestionAdapter.ViewHolder holder, View view, int position) {
                Question item = adapter.getItem(position);

                Intent intent = new Intent(getApplicationContext(), SolveQActivity.class);

                intent.putExtra("id", item.getNum());
                intent.putExtra("tag", tag);

                intent.putExtra("start", start);
                intent.putExtra("end", end);

                startActivity(intent);
            }
        });
// SolveQActivity.java


		...
        
        
        Intent intent = getIntent();

        if(intent != null){
            Bundle bundle = intent.getExtras();
            id = bundle.getInt("id");

            start = bundle.getInt("start");
            end = bundle.getInt("end");

            tagNow = bundle.getString("tag");
        }

        // 데이터베이스와 커서를 설정하고, 처음 선택된 문제로 커서를 이동한 후 문제 설정
        initQuestion();


       ...
       
       
    private void initQuestion() {

        QuestionDatabase database = null;

        if(cursor != null){
            cursor.close();
            cursor = null;
        }

        database = QuestionDatabase.getInstance(this);

        String sql;

        if(tagNow.equals("ALL"))
            sql = "select _id, TITLE, QUESTION, ANSWER, TAG FROM " + QuestionDatabase.TABLE_QUESTION + " order by _id ASC";
        else
            sql = "select _id, TITLE, QUESTION, ANSWER, TAG FROM " + QuestionDatabase.TABLE_QUESTION + " where TAG = '" + tagNow + "' order by _id ASC";

        cursor = database.rawQuery(sql);

        int recordCount = cursor.getCount();

        for(int i = 0; i < recordCount; i++){
            cursor.moveToNext();

            int _id = cursor.getInt(0);

            if(_id == id){
                setQuestion();
                break;
            }
        }
    }

0개의 댓글