Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
2652027
design: Apply design
MisterJerry123 Oct 3, 2024
5769652
feat: Apply viewBinding
MisterJerry123 Oct 3, 2024
e1e8c86
setting: Set ViewBinding
MisterJerry123 Oct 3, 2024
8b90bb9
feat: Implement ViewModel Class
MisterJerry123 Oct 3, 2024
c2363f6
feat: Implement save logic by SharedPreference,Design MVVM pattern (b…
MisterJerry123 Oct 3, 2024
fad0a22
Create PULL_REQUEST_TEMPLATE.md
MisterJerry123 Oct 6, 2024
44e3af0
Delete .github directory
MisterJerry123 Oct 6, 2024
fa8e0f3
Create pull_request_template.md
MisterJerry123 Oct 6, 2024
376d528
Delete pull_request_template.md
MisterJerry123 Oct 6, 2024
1c1a89b
refactor: Replace LiveData with StateFlow
MisterJerry123 Oct 10, 2024
dfa425e
refactor: Replace LiveData with StateFlow
MisterJerry123 Oct 10, 2024
81c998c
chore: Add lifecycle implementation
MisterJerry123 Oct 10, 2024
6980ada
remove: file delete
MisterJerry123 Oct 10, 2024
e593f7e
Merge branch 'main' of https://github.com/MisterJerry123/Advanced-and…
MisterJerry123 Oct 10, 2024
32d0d2f
setting: Add LifeCycleScope implementation
MisterJerry123 Oct 11, 2024
098510c
feat: Define repository interface
MisterJerry123 Oct 11, 2024
c460850
feat: Implement repository pattern
MisterJerry123 Oct 11, 2024
bda98cd
refactor: Apply repository pattern, Add init block to ViewModel
MisterJerry123 Oct 11, 2024
4253215
feat: Add ViewModelFactory
MisterJerry123 Oct 11, 2024
05b4812
refactor: Refactor business logic (기존 MainActivity에서 저장하는 방식에서 Reposi…
MisterJerry123 Oct 11, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ android {
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildFeatures{
viewBinding = true
}
buildTypes {
release {
isMinifyEnabled = false
Expand All @@ -42,4 +45,8 @@ dependencies {
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)

implementation(libs.androidx.lifecycle.viewmodel.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)

}
41 changes: 32 additions & 9 deletions app/src/main/java/com/alom/androidstudy1/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,20 +1,43 @@
package com.alom.androidstudy1

import android.os.Bundle
import androidx.activity.enableEdgeToEdge
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import com.alom.androidstudy1.databinding.ActivityMainBinding
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {
private lateinit var memoViewModel: MemoViewModel
private lateinit var binding : ActivityMainBinding
private val TAG = "MainActivity"

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContentView(R.layout.activity_main)
ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main)) { v, insets ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom)
insets
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
val sharedPreferences = getSharedPreferences("memo", MODE_PRIVATE)
val memoRepository = MemoRepositoryImpl(sharedPreferences)

val memoViewModelFactory = MemoViewModelFactory(memoRepository)

memoViewModel = ViewModelProvider(this,memoViewModelFactory).get(MemoViewModel::class.java)

lifecycleScope.launch{
lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){
launch {
memoViewModel.currentValue.collect{
binding.etMemo.setText(it)
}
}
}
}

binding.btnSave.setOnClickListener {
memoViewModel.saveMemo(binding.etMemo.text.toString())
}
}
}
7 changes: 7 additions & 0 deletions app/src/main/java/com/alom/androidstudy1/MemoRepository.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.alom.androidstudy1

interface MemoRepository {
//메모를 가져오는 추상함수와 메모를 설정하는 추상함수 설정
fun getMemo():String
fun setMemo(input:String):Unit
}
14 changes: 14 additions & 0 deletions app/src/main/java/com/alom/androidstudy1/MemoRepositoryImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.alom.androidstudy1

import android.content.SharedPreferences

class MemoRepositoryImpl(private val sharedPreferences: SharedPreferences) : MemoRepository {
override fun getMemo(): String {
return sharedPreferences.getString("memo", "").toString()
}
override fun setMemo(input: String) {
val editor = sharedPreferences.edit()
editor.putString("memo", input)
editor.apply()
}
}
26 changes: 26 additions & 0 deletions app/src/main/java/com/alom/androidstudy1/MemoViewModel.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.alom.androidstudy1
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class MemoViewModel(private val repository: MemoRepository) : ViewModel() {

private val _currentValue = MutableStateFlow<String>("")
val currentValue: StateFlow<String>
get() = _currentValue

init { //초기값 설정
viewModelScope.launch {
_currentValue.emit(repository.getMemo())
}
}

fun saveMemo(memo: String) {
viewModelScope.launch {
_currentValue.emit(memo)
repository.setMemo(memo)
}
}
}
15 changes: 15 additions & 0 deletions app/src/main/java/com/alom/androidstudy1/MemoViewModelFactory.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.alom.androidstudy1

import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider


class MemoViewModelFactory(private val memoRepository: MemoRepository) : ViewModelProvider.Factory {
//ViewModel에 생성자가 있을 경우 factory를 만들어야함
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if(modelClass.isAssignableFrom(MemoViewModel::class.java)){
return MemoViewModel(memoRepository) as T
}
throw IllegalArgumentException("Unknown ViewModel Class")
}
}
32 changes: 28 additions & 4 deletions app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,37 @@
android:layout_height="match_parent"
tools:context=".MainActivity">


<TextView
android:id="@+id/tv_menu_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_height="0dp"
android:text="메모장"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="20sp"
/>

<EditText
android:id="@+id/et_memo"
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintTop_toBottomOf="@id/tv_menu_indicator"
app:layout_constraintBottom_toTopOf="@id/btn_save"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
/>
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/btn_save"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="저장하기"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/et_memo"
app:layout_constraintBottom_toBottomOf="parent"
/>


</androidx.constraintlayout.widget.ConstraintLayout>
3 changes: 3 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ junit = "4.13.2"
junitVersion = "1.2.1"
espressoCore = "3.6.1"
appcompat = "1.7.0"
lifecycleViewmodelKtx = "2.8.6"
material = "1.12.0"
activity = "1.9.2"
constraintlayout = "2.1.4"

[libraries]
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
androidx-lifecycle-runtime-ktx = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycleViewmodelKtx" }
androidx-lifecycle-viewmodel-ktx = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycleViewmodelKtx" }
junit = { group = "junit", name = "junit", version.ref = "junit" }
androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
Expand Down