본문 바로가기

Development/JAVA 앱 개발노트

(My Voca) Day 13. V2 기록

1. 전체 수정

  1) 수정 전

    - 데이터 입력: 사용자가 직접 입력, 사전 검색 후 검색 내용 저장(문제점: 사용자 입력단이 복잡)

    - 통계: 데쉬보드형 통계를 직접 보여주고 학습 방향성을 제시(문제점: 사용자 관점에서 효율성 저하 및 이탈 상승)

    - 엑티비티 구조: 4개 엑티비티 전체에 무게를 부여하고 각 엑티비티 하위에 서브엑티비티까지 구성

 

  2) 수정 후

    - 홈 화면에 나머지 엑티비티 통합 정보 게시

    - 데이터 입력: 사용자는 직접 입력하지 않고 무조건 사전을 검색 후 검색 내용을 저장하여 일관적인 데이터 수집

    - 통계: 데쉬보드는 유지하되 설정 중 하나로 묶고 참고용으로만 제공, 홈화면에 통계를 기반으로 한 학습을 선택할 수 있도록 하는 데이터로 사용

    - 엑티비티 구조: A, B입력을 통합하여 버튼으로만 구동, 메인엑티비티(통계기반 학습추천, 직전 추가 단어 20개 리사이클러뷰, 시험 숏컷, 엑티비티2(단어장 검색, 고정, 삭제 기능), 엑티비티3(OX, 매칭, 빈 칸 넣기), 엑티비티4(통계, 테마 선택, 글 꼴, 푸쉬알림 수신, 데이터 리셋, 개발자 메일)

 

2. AI 활용 방안

  1) 통계 분석

    - 통계 기반 테스크 추천: 추천 암기 단어 리스트 

  2) 시험 문제 생성

    - 추천 리스트 기반 시험문제 생성

  3) 추가 확장 가능성

    - 오늘의 할 일 테스크의 유형 다양화 > 더욱 다각화 된 추천

 

3. 코드 정리

  1) activity_main

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_height="192dp"
        android:layout_width="match_parent">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:toolbarId="@+id/toolbar"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:layout_scrollInterpolator="@android:anim/decelerate_interpolator"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/app_bar_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/dictionary"
                android:scaleType="centerCrop"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_height="?attr/actionBarSize"
                android:layout_width="match_parent"
                android:background="#FBFBFB"
                app:contentInsetStart="0dp">
                <Button
                    android:id="@+id/btn_menu"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:drawableLeft="@drawable/baseline_menu_24"
                    android:background="#00000000"
                    android:text="메뉴 열기"/>
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Dictionary"
                    android:textSize="15pt"
                    android:textStyle="bold"
                    android:textColor="#3E3D3D"/>
                <Button
                    android:id="@+id/btn_search"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:drawableLeft="@drawable/baseline_search_24"
                    android:background="#00000000"
                    android:layout_gravity="end"
                    android:text="사전 검색"/>

                <SearchView
                    android:id="@+id/search_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="gone" />

            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <RelativeLayout
                android:id="@+id/drawer_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

            </RelativeLayout>
        </LinearLayout>
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:src="@android:drawable/ic_input_add"
        android:layout_gravity="bottom|end"
        android:backgroundTint="#EDEEF2"
        android:layout_margin="16dp"
        android:contentDescription="단어 추가"/>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

  2) activity_2

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appbar"
        android:layout_height="192dp"
        android:layout_width="match_parent">

        <com.google.android.material.appbar.CollapsingToolbarLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:toolbarId="@+id/toolbar"
            app:layout_scrollFlags="scroll|enterAlways|enterAlwaysCollapsed"
            app:layout_scrollInterpolator="@android:anim/decelerate_interpolator"
            app:contentScrim="?attr/colorPrimary">

            <ImageView
                android:id="@+id/app_bar_image"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:src="@drawable/notebook"
                android:scaleType="centerCrop"/>

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:elevation="20dp"
                android:background="#FBFBFB"
                app:contentInsetStart="0dp">

                <Button
                    android:id="@+id/btn_menu"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:background="#00000000"
                    android:drawableLeft="@drawable/baseline_menu_24"
                    android:text="메뉴 열기" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="My Voca"
                    android:textSize="15pt"
                    android:textStyle="bold"
                    android:textColor="#3E3D3D"/>

                <Button
                    android:id="@+id/btn_search"
                    android:layout_width="50dp"
                    android:layout_height="50dp"
                    android:drawableLeft="@drawable/baseline_search_24"
                    android:background="#00000000"
                    android:layout_gravity="end"
                    android:text="사전 검색"/>

                <SearchView
                    android:id="@+id/search_view"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:visibility="gone" />

            </androidx.appcompat.widget.Toolbar>
        </com.google.android.material.appbar.CollapsingToolbarLayout>
    </com.google.android.material.appbar.AppBarLayout>


    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <androidx.recyclerview.widget.RecyclerView
                app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
                android:id="@+id/rv2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintEnd_toEndOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                app:layout_constraintTop_toTopOf="parent" />

            <RelativeLayout
                android:id="@+id/drawer_layout"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MainActivity">

            </RelativeLayout>
        </FrameLayout>
    </androidx.core.widget.NestedScrollView>

    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:id="@+id/btn_add2"
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"
        android:src="@android:drawable/ic_input_add"
        android:layout_gravity="bottom|end"
        android:backgroundTint="#EDEEF2"
        android:layout_margin="16dp"/>


</androidx.coordinatorlayout.widget.CoordinatorLayout>

  3) activity_sub2

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <ImageView
        android:id="@+id/app_bar_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/notebook"
        app:layout_constraintDimensionRatio="4:2"
        app:layout_constraintTop_toTopOf="parent" />


    <!-- 기본정보 작성-->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/info_main"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        app:layout_constraintTop_toBottomOf="@id/app_bar_image">

        <TextView
            android:id="@+id/txt_main_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="기본 정보"
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.example.myvocaprojectv2.ClearEditText
            android:id="@+id/ed_word"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="새로운 단어를 입력하세요."
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="@id/txt_main_info"
            app:layout_constraintTop_toBottomOf="@id/txt_main_info"/>

        <Spinner
            android:id="@+id/spinner_class"
            android:layout_width="150dp"
            android:layout_height="48dp"
            android:entries="@array/wordClass"
            app:layout_constraintStart_toStartOf="@id/ed_word"
            app:layout_constraintTop_toBottomOf="@id/ed_word"/>

        <com.example.myvocaprojectv2.ClearEditText
            android:id="@+id/ed_meaning"
            android:layout_width="240dp"
            android:layout_height="wrap_content"
            android:hint="단어의 뜻을 입력하세요."
            android:textSize="20dp"
            app:layout_constraintBottom_toBottomOf="@+id/spinner_class"
            app:layout_constraintStart_toEndOf="@id/spinner_class"
            app:layout_constraintTop_toTopOf="@+id/spinner_class" />


    </androidx.constraintlayout.widget.ConstraintLayout>

    <!--예제 작성-->

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/info_sub"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        app:layout_constraintTop_toBottomOf="@id/info_main">

        <TextView
            android:id="@+id/txt_sub_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="예문"
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />


        <com.example.myvocaprojectv2.ClearEditText
            android:id="@+id/ed_ex"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="단어가 포함된 예문을 입력하세요."
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="@id/txt_sub_info"
            app:layout_constraintTop_toBottomOf="@id/txt_sub_info" />

        <com.example.myvocaprojectv2.ClearEditText
            android:id="@+id/ed_ex_meaning"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="예문의 해석을 입력하세요."
            android:textSize="20dp"
            app:layout_constraintStart_toStartOf="@id/ed_ex"
            app:layout_constraintTop_toBottomOf="@id/ed_ex" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <!--메모 작성-->
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/info_memo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        app:layout_constraintTop_toBottomOf="@id/info_sub">

        <TextView
            android:id="@+id/txt_memo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="메모"
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <com.example.myvocaprojectv2.ClearEditText
            android:id="@+id/ed_memo"
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:layout_marginTop="10dp"
            android:hint="기타 정보를 입력하세요."
            android:textSize="20sp"
            app:layout_constraintStart_toStartOf="@id/txt_memo"
            app:layout_constraintTop_toBottomOf="@id/txt_memo" />

    </androidx.constraintlayout.widget.ConstraintLayout>

    <Button
        android:id="@+id/btn_save"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:backgroundTint="#9F9F9F"
        android:textColor="#121212"
        android:text="저장"
        android:textStyle="bold"
        app:layout_constraintStart_toStartOf="@+id/info_memo"
        app:layout_constraintTop_toBottomOf="@+id/info_memo"/>
    <Button
        android:id="@+id/btn_cancel"
        android:layout_width="180dp"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:backgroundTint="#9F9F9F"
        android:textColor="#121212"
        android:text="취소"
        android:textStyle="bold"
        app:layout_constraintEnd_toEndOf="@+id/info_memo"
        app:layout_constraintTop_toBottomOf="@+id/info_memo"/>

</androidx.constraintlayout.widget.ConstraintLayout>

  4) detail

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <ImageView
        android:id="@+id/app_bar_image"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_margin="0dp"
        android:scaleType="centerCrop"
        android:src="@drawable/notebook"
        app:layout_constraintDimensionRatio="4:3"
        app:layout_constraintTop_toTopOf="parent"
        tools:layout_editor_absoluteX="196dp" />


    <com.google.android.material.floatingactionbutton.FloatingActionButton
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp"
        android:backgroundTint="#D8D8D8"
        android:contentDescription="즐겨챶기"
        android:src="@drawable/baseline_star_rate_24"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="1.0"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.41000003" />


    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/app_bar_image">


        <ImageView
            android:id="@+id/image_main"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="30dp"
            android:src="@drawable/baseline_radio_button_checked_24"
            app:layout_constraintEnd_toStartOf="@+id/info_detail1"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="@+id/info_detail1" />

        <androidx.constraintlayout.widget.ConstraintLayout
            android:id="@+id/info_detail1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.28"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">

            <TextView
                android:id="@+id/item_word1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="단어"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"
                app:layout_constraintTop_toTopOf="parent"
                app:layout_constraintStart_toStartOf="parent"
                android:transitionName="textTransition"/>

            <TextView
                android:id="@+id/item_class1_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="품사1"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"
                app:layout_constraintStart_toStartOf="@+id/item_word1"
                app:layout_constraintTop_toBottomOf="@id/item_word1"
                android:transitionName="textTransition"/>


            <TextView
                android:id="@+id/item_meaning1_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="뜻1"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"
                app:layout_constraintStart_toEndOf="@+id/item_class1_1"
                app:layout_constraintTop_toTopOf="@+id/item_class1_1"
                android:transitionName="textTransition"/>

            <TextView
                android:id="@+id/item_class1_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="품사2"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"
                app:layout_constraintStart_toStartOf="@+id/item_class1_1"
                app:layout_constraintTop_toBottomOf="@id/item_class1_1" />

            <TextView
                android:id="@+id/item_meaning1_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:text="뜻2"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"
                app:layout_constraintBottom_toBottomOf="parent"
                app:layout_constraintStart_toEndOf="@+id/item_class1_2"
                app:layout_constraintTop_toTopOf="@+id/item_class1_2" />

        </androidx.constraintlayout.widget.ConstraintLayout>

        <ImageButton
            android:id="@+id/btn_edit1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginEnd="20dp"
            android:background="#ffffff"
            android:contentDescription="기본정보 수정"
            android:padding="16dp"
            android:src="@drawable/baseline_mode_edit_24"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="1.0"
            app:layout_constraintStart_toEndOf="@+id/info_detail1"
            app:layout_constraintTop_toTopOf="@+id/info_detail1" />


        <ImageView
            android:id="@+id/image_sub"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/baseline_radio_button_unchecked_24"
            app:layout_constraintEnd_toEndOf="@+id/image_main"
            app:layout_constraintStart_toStartOf="@+id/image_main"
            app:layout_constraintTop_toTopOf="@+id/info_detail2" />

        <LinearLayout
            android:id="@+id/info_detail2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="vertical"
            app:layout_constraintStart_toStartOf="@+id/info_detail1"
            app:layout_constraintTop_toBottomOf="@+id/info_detail1">

            <TextView
                android:id="@+id/item_ex1_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="예문1"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"/>

            <TextView
                android:id="@+id/item_ex_meaning1_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="예문 해석1"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"/>

            <TextView
                android:id="@+id/item_ex1_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="예문2"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"/>

            <TextView
                android:id="@+id/item_ex_meaning1_2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="예문 해석2"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"/>

        </LinearLayout>

        <ImageButton
            android:id="@+id/btn_edit2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            android:src="@drawable/baseline_mode_edit_24"
            android:padding="16dp"
            app:layout_constraintEnd_toEndOf="@+id/btn_edit1"
            app:layout_constraintStart_toStartOf="@+id/btn_edit1"
            app:layout_constraintTop_toTopOf="@+id/info_detail2"
            android:contentDescription="예문 수정"/>

        <ImageView
            android:id="@+id/image_memo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/baseline_note_24"
            app:layout_constraintEnd_toEndOf="@+id/image_sub"
            app:layout_constraintStart_toStartOf="@+id/image_sub"
            app:layout_constraintTop_toTopOf="@+id/info_detail3" />

        <LinearLayout
            android:id="@+id/info_detail3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:orientation="vertical"
            app:layout_constraintStart_toStartOf="@+id/info_detail2"
            app:layout_constraintTop_toBottomOf="@id/info_detail2">

            <TextView
                android:id="@+id/text8"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="메모 임시 텍스트"
                android:textSize="20dp"
                android:textStyle="bold"
                android:constrainedWidth="true"/>


        </LinearLayout>

        <ImageButton
            android:id="@+id/btn_edit3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            android:src="@drawable/baseline_mode_edit_24"
            android:padding="16dp"
            app:layout_constraintEnd_toEndOf="@+id/btn_edit2"
            app:layout_constraintStart_toStartOf="@+id/btn_edit2"
            app:layout_constraintTop_toTopOf="@+id/info_detail3"
            android:contentDescription="메모 수채"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

  5) activity_drawer

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="240dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:id="@+id/drawer"
    android:background="#EAEAEA"
    android:orientation="vertical">

    <Button
        android:id="@+id/btn_open"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:drawableLeft="@drawable/baseline_menu_24"
        android:background="#00000000"
        android:text=""/>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout"
        android:layout_width="match_parent"
        android:layout_height="240dp"
        android:layout_margin="10dp"
        android:background="#EAEAEA"
        android:orientation="vertical">

        <Button
            android:id="@+id/btn_menu1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginTop="20dp"
            android:text="Dictionary"
            android:backgroundTint="#636262"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <Button
            android:id="@+id/btn_menu2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginTop="10dp"
            android:text="My Voca"
            android:backgroundTint="#636262"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_menu1" />

        <Button
            android:id="@+id/btn_menu3"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginTop="10dp"
            android:text="Voca Test"
            android:backgroundTint="#636262"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_menu2" />

        <Button
            android:id="@+id/btn_menu4"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:layout_marginTop="10dp"
            android:text="Setting"
            android:backgroundTint="#636262"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn_menu3" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</LinearLayout>

  6) card_view

<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:app="http://schemas.android.com/tools"
    android:id="@+id/card_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    card_view:cardCornerRadius="12dp"
    card_view:contentPadding="4dp"
    android:dividerHeight="5dp"
    android:divider="#6E6E6E"
    app:ignore="NamespaceTypo">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/info_detail1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.28"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/item_word1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="단어"
            android:textSize="20dp"
            android:textStyle="bold"
            android:constrainedWidth="true"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            android:transitionName="textTransition"/>

        <TextView
            android:id="@+id/item_class1_1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="품사1"
            android:textSize="20dp"
            android:textStyle="bold"
            android:constrainedWidth="true"
            app:layout_constraintStart_toStartOf="@+id/item_word1"
            app:layout_constraintTop_toBottomOf="@id/item_word1"
            android:transitionName="textTransition"/>


        <TextView
            android:id="@+id/item_meaning1_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="10dp"
            android:text="뜻1"
            android:textSize="20dp"
            android:textStyle="bold"
            android:constrainedWidth="true"
            app:layout_constraintStart_toEndOf="@+id/item_class1_1"
            app:layout_constraintTop_toTopOf="@+id/item_class1_1"
            android:transitionName="textTransition"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.cardview.widget.CardView>

  7) array_list

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="wordClass">
        <item>n.</item>
        <item>pron.</item>
        <item>adj.</item>
        <item>ad.</item>
        <item>v.</item>
        <item>prep.</item>
        <item>conj.</item>
        <item>int.</item>
    </string-array>
</resources>

  8) MainActivity

package com.example.myvocaprojectv2;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

  9) Activity2

package com.example.myvocaprojectv2;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Spinner;

import java.util.ArrayList;

public class Activity2 extends AppCompatActivity {

    private ArrayList<Data2> arrayList;
    private Adapter2 adapter2;
    private RecyclerView recyclerView;
    private LinearLayoutManager linearLayoutManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {  // 생성자 중요
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_2);

        recyclerView = (RecyclerView) findViewById(R.id.rv2);
        linearLayoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(linearLayoutManager);

        arrayList = new ArrayList<>();   // arraylist를 만들고

        adapter2 = new Adapter2(arrayList);   // 생성된 아이템들을 어레이리스트에 담아라
        recyclerView.setAdapter(adapter2); // 담아져있는 데이터의 어뎁터를 리사이클러뷰에 셋팅해라


        Button btn_add2 = (Button)findViewById(R.id.btn_add2);
        btn_add2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Data2 data2 = new Data2("단어", "품사1", "뜻1");
                arrayList.add(data2);            // 어레이리스트에 메인데이터를 더해라
                adapter2.notifyDataSetChanged(); // 더하고 새로고침을 해라
            }
        });
    }
}

  10) ActivitySub2

package com.example.myvocaprojectv2;

import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

public class ActivitySub2 extends AppCompatActivity {

    private TextView txt_main_info, txt_sub_info, txt_memo;
    private Spinner spinner_class;
    private ClearEditText ed_word, ed_meaning, ed_ex, ed_ex_meaning, ed_memo;
    private Button btn_save, btn_cancel;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sub2);

        // 기본정보

        txt_main_info = findViewById(R.id.txt_main_info);
        ed_word = findViewById(R.id.ed_word);
        spinner_class = findViewById(R.id.spinner_class);
        ed_meaning = findViewById(R.id.ed_meaning);

        TextView textView1 = (TextView)findViewById(R.id.txt_main_info);
        Log.d(this.getClass().getName(), (String)textView1.getText());

        ClearEditText clearEditText1 = (ClearEditText)findViewById(R.id.ed_word);
        String clearEditTextString1 = clearEditText1.getText().toString();
        if (clearEditTextString1.isEmpty()) {
            // 사용자에게 값을 입력하도록 메시지를 표시
            clearEditText1.setError("단어를 입력하세요.");
        }


        Spinner spinner = (Spinner)findViewById(R.id.spinner_class);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
                this, R.array.wordClass, android.R.layout.simple_spinner_dropdown_item
        );

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);


        ClearEditText clearEditText2 = (ClearEditText)findViewById(R.id.ed_meaning);
        String clearEditTextString2 = clearEditText2.getText().toString();
        if (clearEditTextString2.isEmpty()) {
            // 사용자에게 값을 입력하도록 메시지를 표시
            clearEditText2.setError("뜻을 입력하세요.");
        }

        // 예제 정보

        txt_sub_info = findViewById(R.id.txt_sub_info);
        ed_ex = findViewById(R.id.ed_ex);
        ed_ex_meaning = findViewById(R.id.ed_ex_meaning);

        TextView textView2 = (TextView)findViewById(R.id.txt_sub_info);
        Log.d(this.getClass().getName(), (String)textView2.getText());

        ClearEditText clearEditText3 = (ClearEditText)findViewById(R.id.ed_ex);
        String clearEditTextString3 = clearEditText3.getText().toString();
        if (clearEditTextString3.isEmpty()) {
            // 사용자에게 값을 입력하도록 메시지를 표시
            clearEditText3.setError("예시를 입력하세요.");
        }

        ClearEditText clearEditText4 = (ClearEditText)findViewById(R.id.ed_meaning);
        String clearEditTextString4 = clearEditText4.getText().toString();
        if (clearEditTextString4.isEmpty()) {
            // 사용자에게 값을 입력하도록 메시지를 표시
            clearEditText4.setError("예시의 뜻을 입력하세요.");
        }

        // 메모 정보

        txt_memo = findViewById(R.id.txt_memo);
        ed_memo = findViewById(R.id.ed_memo);

        TextView textView3 = (TextView)findViewById(R.id.txt_memo);
        Log.d(this.getClass().getName(), (String)textView3.getText());

        ClearEditText clearEditText5 = (ClearEditText)findViewById(R.id.ed_ex);
        String clearEditTextString5 = clearEditText5.getText().toString();
        if (clearEditTextString5.isEmpty()) {
            // 사용자에게 값을 입력하도록 메시지를 표시
            clearEditText5.setError("예시를 입력하세요.");
        }
    }

    // 저장버튼, 취소버튼 구현 (저장 버튼을 누르면 데이터가 데이터베이스로 이동 + 카드뷰 생성 / 취소 버튼을 누르면 Activity2 페이지로 이동)


}

  11) Adapter2

package com.example.myvocaprojectv2;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;

public class Adapter2 extends RecyclerView.Adapter<Adapter2.CustomViewHolder> {

    private ArrayList<Data2> arrayList;

    public Adapter2(ArrayList<Data2> arrayList) {
        this.arrayList = arrayList;
    }


    @NonNull
    @Override
    public Adapter2.CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_view, parent, false);
        CustomViewHolder holder = new CustomViewHolder(view);

        return holder;
    }

    @Override
    public void onBindViewHolder(@NonNull Adapter2.CustomViewHolder holder, int position) {
        holder.item_word1.setText(arrayList.get(position).getItem_word1());
        holder.item_class1_1.setText(arrayList.get(position).getItem_class1_1());
        holder.item_meaning1_1.setText(arrayList.get(position).getItem_meaning1_1());
        holder.itemView.setTag(position);
        holder.itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String curName = holder.item_word1.getText().toString();
            }
        });

        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View view) {
                return true;
            }
        });
    }

    @Override
    public int getItemCount() {
        return arrayList.size();
    }

    public void remove(int position) {
        try {  //예외상황이 벌어졌을 때 강제로 실행
            arrayList.remove(position);
            notifyItemRemoved(position);
        } catch (IndexOutOfBoundsException ex) {
            ex.printStackTrace();
        }
    }

    public class CustomViewHolder extends RecyclerView.ViewHolder {

        protected TextView item_word1;
        protected TextView item_class1_1;
        protected TextView item_meaning1_1;

        public CustomViewHolder(@NonNull View itemView) {
            super(itemView);
            this.item_word1 = (TextView) itemView.findViewById(R.id.item_word1);
            this.item_class1_1 = (TextView) itemView.findViewById(R.id.item_class1_1);
            this.item_meaning1_1 = (TextView) itemView.findViewById(R.id.item_meaning1_1);
        }
    }
}

  12) ClearEditText

package com.example.myvocaprojectv2;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.AppCompatEditText;
import androidx.core.content.ContextCompat;
import androidx.core.graphics.drawable.DrawableCompat;

public class ClearEditText extends AppCompatEditText implements TextWatcher, View.OnTouchListener, View.OnFocusChangeListener {

    private Drawable clearDrawable;
    private OnFocusChangeListener onFocusChangeListener; // View 가 포커스를 받거나 잃으면 onFocusChange 호출
    private OnTouchListener onTouchListener; // View 의 터치 이벤트 처리 인터페이스, onTouch 를 통해 MotionEvent 전달

    // 환경정보 파라미터를 받음
    public ClearEditText(@NonNull Context context) {
        super(context);
        init();  // 초기화작업을 위한 메소드(기본제공X), X버튼을 누르면 Drawable까지 모두 초기화
    }
    // XML레이아웃에서 테그 속성 저장 객체를 받음
    public ClearEditText(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    // 미리 정의된 테마에서 속성값을 받아옴
    public ClearEditText(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    @Override
    public void setOnFocusChangeListener(OnFocusChangeListener onFocusChangeListener) {
        this.onFocusChangeListener = onFocusChangeListener;
    }

    @Override
    public void setOnTouchListener(OnTouchListener onTouchListener) {
        this.onTouchListener = onTouchListener;
    }

    private void init() {
        // 이미지 가져옴
        Drawable tempDrawable = ContextCompat.getDrawable(getContext(), R.drawable.baseline_clear_24);
        clearDrawable = DrawableCompat.wrap(tempDrawable);
        // 색상 설정
        DrawableCompat.setTintList(clearDrawable,getHintTextColors());
        // Drawable 객체영역 설정, 즉, X가 생기는 부분 설정
        clearDrawable.setBounds(0, 0, clearDrawable.getIntrinsicWidth(), clearDrawable.getIntrinsicHeight());
        // 위젯에서 X버튼이 보이지않도록 설정
        setClearIconVisible(false);
        // 각 메소드를 호출하여 객체 전달
        super.setOnTouchListener(this);
        super.setOnFocusChangeListener(this);
        // 텍스트가 변경되었을 때 호출되는 TextWatcher 인터페이스 구현
        addTextChangedListener(this);
    }

    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        //포커스를 받아서 텍스트가 0 이상으로 작성될 때 아이콘이 보이게
        if (hasFocus) {
            setClearIconVisible(getText().length()>0);
            // 그렇지 않으면
        } else {
            setClearIconVisible(false);
        }
        // null이 아니면 onFocusChangeListener 객체에 이벤트 전달
        if (onFocusChangeListener !=null) {
            onFocusChangeListener.onFocusChange(v, hasFocus);
        }
    }

    public boolean onTouch(final View view, final MotionEvent motionEvent) {
        // X 좌표 터치이벤트 정의
        final int X = (int)motionEvent.getX();
        // 오른쪽 끝 좌표를 터치하면
        if (clearDrawable.isVisible() && X > getWidth() - getPaddingRight() - clearDrawable.getIntrinsicWidth()) {
            // 사용자가 손가락으로 터치를 했다가 떼었을 때(action_up)
            if (motionEvent.getAction() == MotionEvent.ACTION_UP) {
                // 에러메시지 또는 텍스트를 지움
                setError(null);  // 에러메시지가 뜨도록 토스트메시지 설정 필요
                setText(null);
            }
            return true; // 이벤트가 소비되었음
        }
        // null이 아닌 경우
        if (onTouchListener != null) {
            // 메소드 반환
            return onTouchListener.onTouch(view, motionEvent);
            // 그렇지 않으면
        } else {
            // 이벤트가 실행되지 않음
            return false;
        }
    }

    // 문자열 s, 작성 전, 숫자의 파라미터를 받음
    public final void onTextChanged (final CharSequence s, final int before, final int count) {
        // 포커스를 받으면 아이콘이 보임
        if(isFocused()) {
            setClearIconVisible(s.length() > 0);
        }
    }
    // 사용하지 않음
    @Override
    public void beforeTextChanged(final CharSequence s, final int start, final int count, final int after) {

    }
    // 텍스트가 변동이 있음, 글자 길이가 1개 이상인 경우 아이콘이 보이지 않음
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        if (isFocused()){
            setClearIconVisible(s.length()>0);
        }
    }
    // 텍스트의 변동이 완료된 후
    @Override
    public void afterTextChanged(Editable s) {

    }
    // TextWatcher가 문자열이 존재함을 감지하면 clearDrawable을 표시하게 만드는 메소드 정의
    private void setClearIconVisible(boolean visible) {
        clearDrawable.setVisible(visible, false);
        setCompoundDrawables(null, null, visible ? clearDrawable : null, null);
    }
}

  13) Data2

package com.example.myvocaprojectv2;

public class Data2 {

    private String item_word1;
    private String item_class1_1;
    private String item_meaning1_1;

    public Data2 (String item_word1, String item_class1_1, String item_meaning1_1) {
        this.item_word1 = item_word1;
        this.item_class1_1 = item_class1_1;
        this.item_meaning1_1 = item_meaning1_1;
    }

    public String getItem_word1() {
        return item_word1;
    }
    public void setItem_word1() {
        this.item_word1 = item_word1;
    }

    public String getItem_class1_1() {
        return item_class1_1;
    }
    public void setItem_class1_1() {
        this.item_class1_1 = item_class1_1;
    }

    public String getItem_meaning1_1() {
        return item_meaning1_1;
    }
    public void setItem_meaning1_1() {
        this.item_meaning1_1 = item_meaning1_1;
    }

}

  14) SpinnerActivity

package com.example.myvocaprojectv2;

import android.view.View;
import android.widget.AdapterView;
import android.widget.Spinner;

public class SpinnerActivity extends ActivitySub2 implements AdapterView.OnItemClickListener {

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

    }

    public void onNothingSelected(AdapterView<?> parent) {

    }


}