diff --git a/app/build.gradle.kts b/app/build.gradle.kts index e86faf7..26c4f89 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -17,6 +17,9 @@ android { testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } + buildFeatures{ + viewBinding = true + } buildTypes { release { isMinifyEnabled = false @@ -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) + } \ No newline at end of file diff --git a/app/src/main/java/com/alom/androidstudy1/MainActivity.kt b/app/src/main/java/com/alom/androidstudy1/MainActivity.kt index c1bcbbf..53c0dbc 100644 --- a/app/src/main/java/com/alom/androidstudy1/MainActivity.kt +++ b/app/src/main/java/com/alom/androidstudy1/MainActivity.kt @@ -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()) } } } \ No newline at end of file diff --git a/app/src/main/java/com/alom/androidstudy1/MemoRepository.kt b/app/src/main/java/com/alom/androidstudy1/MemoRepository.kt new file mode 100644 index 0000000..346495c --- /dev/null +++ b/app/src/main/java/com/alom/androidstudy1/MemoRepository.kt @@ -0,0 +1,7 @@ +package com.alom.androidstudy1 + +interface MemoRepository { + //메모를 가져오는 추상함수와 메모를 설정하는 추상함수 설정 + fun getMemo():String + fun setMemo(input:String):Unit +} diff --git a/app/src/main/java/com/alom/androidstudy1/MemoRepositoryImpl.kt b/app/src/main/java/com/alom/androidstudy1/MemoRepositoryImpl.kt new file mode 100644 index 0000000..50f6f83 --- /dev/null +++ b/app/src/main/java/com/alom/androidstudy1/MemoRepositoryImpl.kt @@ -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() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/alom/androidstudy1/MemoViewModel.kt b/app/src/main/java/com/alom/androidstudy1/MemoViewModel.kt new file mode 100644 index 0000000..c41b712 --- /dev/null +++ b/app/src/main/java/com/alom/androidstudy1/MemoViewModel.kt @@ -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("") + val currentValue: StateFlow + get() = _currentValue + + init { //초기값 설정 + viewModelScope.launch { + _currentValue.emit(repository.getMemo()) + } + } + + fun saveMemo(memo: String) { + viewModelScope.launch { + _currentValue.emit(memo) + repository.setMemo(memo) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/alom/androidstudy1/MemoViewModelFactory.kt b/app/src/main/java/com/alom/androidstudy1/MemoViewModelFactory.kt new file mode 100644 index 0000000..cbecd91 --- /dev/null +++ b/app/src/main/java/com/alom/androidstudy1/MemoViewModelFactory.kt @@ -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 create(modelClass: Class): T { + if(modelClass.isAssignableFrom(MemoViewModel::class.java)){ + return MemoViewModel(memoRepository) as T + } + throw IllegalArgumentException("Unknown ViewModel Class") + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 86a5d97..3097e15 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -7,13 +7,37 @@ android:layout_height="match_parent" tools:context=".MainActivity"> + + + + + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/et_memo" + app:layout_constraintBottom_toBottomOf="parent" + /> + \ No newline at end of file diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index e0e8c2c..b4d3171 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -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" }