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) {
}
}
'Development > JAVA 앱 개발노트' 카테고리의 다른 글
(My Voca) Day 14. 현재 문제 상황 (0) | 2023.06.20 |
---|---|
(My Voca) Day 14. 사전기능 및 시험문제 만들기 기능 구현 (2) | 2023.05.21 |
(My Voca) Day 12. Build Process 5 (0) | 2023.04.23 |
(My Voca) Day 11. Build Process 4 (0) | 2023.04.16 |
(My Voca) Day 10. Build Process 3 (0) | 2023.04.11 |