목차
- 인트로 (완성앱 & 구현 기능 소개)
- 기본 UI 그리기
- 자물쇠 페이지 구현하기 (로그인, 비밀번호 번경)
- 다이어리 화면 구현하기 (글 작성, 삭제)
- 아웃트로
결과화면


이 챕터를 통해 배우는 것
- Layout 을 그리는 법
- ConstraintLayout 사용하기 (2)
- Custom Font 사용하기
- Handler 사용하기
- SharedPreference 의 속성들과 사용하는 법
- Theme 사용하기
- AlertDialog 사용하기
Kotlin 문법
android-ktx 로 SharedPreference 사용하기 (Kotlin Android Extension)
비밀 다이어리
다이어리 처럼 UI 꾸며보기
비밀번호를 저장하는 기능, 변경하는 기능
다이어리 내용을 앱이 종료되더라도 기기에 저장하는 기능
ㅁ Layout 을 그리는 법
- ConstraintLayout 사용하기
ConstraintLayout안에 ConstraintLayout을 넣어 줄 수 있다.
<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"
android:background="#3F51B5"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:fontFamily="@font/bm_font"
android:text="@string/bm_font"
android:textSize="30sp"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@id/passwordLayout"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"></TextView>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/passwordLayout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#CDCDCD"
android:padding="15dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/openButton"
android:layout_width="40dp"
android:layout_height="60dp"
android:layout_marginEnd="10dp"
android:background="#A3A3A3"
app:layout_constraintBottom_toBottomOf="@id/numberPicker_01"
app:layout_constraintEnd_toStartOf="@id/numberPicker_01"
app:layout_constraintTop_toTopOf="@id/numberPicker_01"></androidx.appcompat.widget.AppCompatButton>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/changePasswordButton"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_marginTop="10dp"
android:background="#A3A3A3"
app:layout_constraintEnd_toEndOf="@id/openButton"
app:layout_constraintStart_toStartOf="@id/openButton"
app:layout_constraintTop_toBottomOf="@id/openButton"></androidx.appcompat.widget.AppCompatButton>
<NumberPicker
android:id="@+id/numberPicker_01"
android:layout_width="30dp"
android:layout_height="120dp"
android:background="#A3A3A3"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/numberPicker_02"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"></NumberPicker>
<NumberPicker
android:id="@+id/numberPicker_02"
android:layout_width="30dp"
android:layout_height="120dp"
android:background="#A3A3A3"
app:layout_constraintBottom_toBottomOf="@id/numberPicker_01"
app:layout_constraintEnd_toStartOf="@id/numberPicker_03"
app:layout_constraintStart_toEndOf="@id/numberPicker_01"
app:layout_constraintTop_toTopOf="@id/numberPicker_01"></NumberPicker>
<NumberPicker
android:id="@+id/numberPicker_03"
android:layout_width="30dp"
android:layout_height="120dp"
android:background="#A3A3A3"
app:layout_constraintBottom_toBottomOf="@id/numberPicker_01"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/numberPicker_02"
app:layout_constraintTop_toTopOf="@id/numberPicker_01">
</NumberPicker>
</androidx.constraintlayout.widget.ConstraintLayout>
그리고 폰트도 사용 가능하다. res - font에 font.otf를 다운 받아 넣어주면 사용 가능하다. 여기서 bm_font로 배민 무료 폰트를 다운 받아 넣어주었다.
- Handler 사용하기
class DiaryActivity : AppCompatActivity() {
private val handler = Handler(Looper.getMainLooper())
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_diary)
val diraryEditText = findViewById<EditText>(R.id.diary_Edit)
val detailPreferences = getSharedPreferences("diary", Context.MODE_PRIVATE)
diraryEditText.setText(detailPreferences.getString("detail",""))
// 잠깐 멈칫할때 저장되는 기능! 한글자 한글자 말고
val runnable = Runnable {
getSharedPreferences("diary",Context.MODE_PRIVATE).edit {
putString("detail",diraryEditText.text.toString())
}
}
diraryEditText.addTextChangedListener{
handler.removeCallbacks(runnable)
handler.postDelayed(runnable,500)
}
// 핸들러 몇초 뒤에 실행시키는 방법!
}
}
핸들러를 사용하면 멈칫할때는 getSharedPreference가 작동하지 않고 입력후 작동하도록 하여 메모리 관리에 효율 성을 더 높여 준다.
ui에 접근하려면 Handler(Looper.getMainLooper())를 사용해야한다.
그리고 putString을 통해 editText내용(데이터)를 저장합니다.
이때 이 저장하는 기능을 Runnable로 작성하여 editText의 텍스트가 변경될때마다 돌아가고 있는 runnable을 removeCallbacks를 이용하여 제거합니다.
이렇게 되면 텍스트 작성중에는 저장이 되지 않고 중간에 작성하지 않고 0.5초가 지나면 자동 저장이 되게 됩니다.
0.5초를 기다리려면 handler.postDelayed(runnable,밀리초)를 사용하면 됩니다.
즉 정리하자면!
1. 다른 쓰레드에서 UI접근이 불가능하므로 메인쓰레드에 접근하기 위해 var handler = Handler(Looper.getMainLooper())를 사용한다.
2. 쓰레드에서 작동할 기능, Runnable를 정의한다.
3. 딜레이를 주고 싶으면 handler.postDelayed(runnable, 밀리초)를 사용하고 진행중인 runnable를 제거하고 싶다면 handler.removeCallbacks(runnable)를 사용하면된다.
- SharedPreference 의 속성들과 사용하는 법
openButton.setOnClickListener {
if (changePasswordMode) {
Toast.makeText(this, "비밀번호 변경 중입니다.", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
val passwordPreferences = getSharedPreferences("password", Context.MODE_PRIVATE)
// sharedPreferences는 기기 내부 storage에 저장 되는 값 앱을 껏을 때도 사라지지 않음,
val passwordFromUser = "${numberPicker1.value}${numberPicker2.value}${numberPicker3.value}"
if (passwordPreferences.getString("password", "000").equals(passwordFromUser)) {
initTextView.isVisible = false
initTextView.setText("")
startActivity(Intent(this,DiaryActivity::class.java))
// TODO 다이어리 작성 페이지 만들고 실행해야함!
} else {
initTextView.isVisible = true
initTextView.setText("비밀번호가 틀립니다.")
initTextView.setTextColor(Color.RED)
showAlertDialog()
}
}
sharedPreferences는 기기 내부 storage에 저장 되는 값 앱을 껏을 때도 사라지지 않는다.
val passwordPreferences = getSharedPreferences("password", Context.MODE_PRIVATE)
val passwordFromUser = "${numberPicker1.value}${numberPicker2.value}${numberPicker3.value}"
if (changePasswordMode) {
passwordPreferences.edit(commit = true) {
putString("password", passwordFromUser)
}
initTextView.setText("비밀번호 변경 완료")
initTextView.setTextColor(Color.BLACK)
비밀 번호 변경 시 putString을 통해 원하는 password를 넣어 준다.
비밀 번호 찾기 기능 추가
findPasswordButton.setOnClickListener {
val passwordPreferences = getSharedPreferences("password", Context.MODE_PRIVATE)
val realPassword = passwordPreferences.getString("password", "000")
initTextView.isVisible = true
initTextView.setText("비밀번호는 : ${realPassword} 입니다.")
initTextView.setTextColor(Color.GREEN)
}
getSharedPreferences로 getStringdmf을 통해 비밀번호를 찾아준다.
- AlertDialog 사용하기
private fun showAlertDialog() {
AlertDialog.Builder(this)
.setTitle("실패!!")
.setMessage("비밀번호가 잘못 됐습니다.")
.setPositiveButton("확인") { _, _ ->
}.create().show()
// Alert Dialog
}
- Thema 사용하기
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Aoppart2chapter03" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_500</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/white</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_700</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="Theme.Aoppart2chapter03.noActionBar" parent="Theme.MaterialComponents.DayNight.NoActionBar"/>
</resources>
둘다 NoActionBar를 설정해 주엇다.
그리고 마지막으로 Activity를 추가해 주려면 Manifast에 Activity를 넣어줘야 한다.
<activity
android:name=".DiaryActivity"
android:theme="@style/Theme.Aoppart2chapter03.noActionBar"
>
</activity>'안드로이드 > 앱개발(Android)' 카테고리의 다른 글
| (코틀린 kotlin) 타이머 앱 (0) | 2022.01.22 |
|---|---|
| (코틀린 kotlin) 전자액자 앱 (0) | 2022.01.21 |
| (코틀린 kotlin) 계산기 앱 (0) | 2022.01.21 |
| (코틀린 kotlin) BMI계산기 (0) | 2022.01.15 |
| (코틀린 kotlin) 로또번호생성기 앱 (0) | 2021.12.26 |