카테고리 없음
1-6. 메모를 작성하는 액티비티로
잘할수있을거야
2021. 9. 14. 18:54
툴바와 메뉴 아이템은 없어도 상관없다. 메뉴 아이템 클릭 대신 버튼하나를 넣어 메모를 저장하도록 해도 좋다.
- activity_write_memo.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- root layout tag use data binding-->
<layout 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">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".ui.WriteMemoActivity">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar_WriteMemoActivity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
android:theme="?attr/actionBarTheme" />
<EditText
android:id="@+id/et_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="제목"
android:inputType="text"
android:maxLength="25"
android:minHeight="48dp"
tools:text="제목" />
<EditText
android:id="@+id/et_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="start"
android:ems="10"
android:hint="내용"
android:inputType="text"
tools:text="내용" />
</LinearLayout>
</layout>
- menu_item_write_memo.xml(menu폴더의 리소스)
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/item_memo_save"
android:title="save"
android:icon="@android:drawable/ic_menu_save"
app:showAsAction="ifRoom" />
</menu>
- AndroidViewModelWriteMemo
WriteMemoActivity와 관련된 데이터를 가진다.
액티비티가 비정상 종료될수도 있어 액티비티의 메모 제목, 내용에 해당하는 EditText의 내용을 ViewModel에 실시간으로 저장하기 위해 TextWatcher와 관련된 String 두개를 선언
class AndroidViewModelWriteMemo(application: Application) : AndroidViewModel(application) {
//EditText TextWatcher통해 String값 전달받음
var titleTextWatcher: String
var contentTextWatcher: String
var _db: MemoRoomDatabase?
val db get() = _db!!
init {
printLog("initialization")
titleTextWatcher = ""
contentTextWatcher = ""
_db = null
}
fun prepareMemoDatabase() { //worker thread
val runnable: Runnable = object : Runnable {
override fun run() {
_db = MemoRoomDatabase.getInstance(getApplication())
}
}
Thread(runnable).start()
}
fun checkAndSave() {
insertMemo()
}
private fun insertMemo() { //worker thread
val runnable: Runnable = object : Runnable {
override fun run() {
db.memoDao().insert(titleTextWatcher, contentTextWatcher)
}
}
Thread(runnable).start()
}
override fun onCleared() {
printLog("onCleared()")
}
fun printLog(str: String) {
Log.d("APPLICATIONTEST", "AndroidViewModelWriteMemo: $str")
}
}
밑의 두 부분은 코드 일관성이 없어 보기 불편할 수도 있을 것 같다.
- WriteMemoActivity
EditText에 텍스트 변화를 감지할 수 있도록 리스너를 단다. text가 변경됨에 따라 ViewModel의 String멤버에 저장한다.
class WriteMemoActivity : AppCompatActivity() {
//lateinit private var mViewModel: ViewModelWriteMemo
lateinit private var mViewModel: AndroidViewModelWriteMemo
private var mActionBar: ActionBar? = null
lateinit private var binding: ActivityWriteMemoBinding
lateinit private var mTextWatcherTitle: TextWatcher
lateinit private var mTextWatcherContent: TextWatcher
companion object {
private const val TOOLBAR_TITLE: String = "메모 작성"
}
override fun onCreate(savedInstanceState: Bundle?) {
printLog("onCreate")
super.onCreate(savedInstanceState)
//viewmodel
mViewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))
.get(AndroidViewModelWriteMemo::class.java)
//data binding
binding = DataBindingUtil.setContentView(this, R.layout.activity_write_memo)
//set Toolbar
setSupportActionBar(binding.toolbarWriteMemoActivity)
mActionBar = supportActionBar
mActionBar?.setTitle(TOOLBAR_TITLE)
//Memo Title TextWatcher
mTextWatcherTitle = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
}
override fun afterTextChanged(s: Editable?) {
printLog("afterTextChanged")
val str: String = s.toString()
mViewModel.titleTextWatcher = str
}
}
//Memo Content TextWatcher
mTextWatcherContent = object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
// printLog("beforeTextChanged")
// printLog(s.toString())
// printLog("start: $start, count: $count, after: $after")
// printLog("\n")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
// printLog("onTextChanged")
// printLog(s.toString())
// printLog("start: $start, count: $count, before: $before")
// printLog("\n")
}
override fun afterTextChanged(s: Editable?) {
printLog("afterTextChanged")
val str: String = s.toString()
mViewModel.contentTextWatcher = str
}
}
}
override fun onStart() {
printLog("onStart")
super.onStart()
//register listener
binding.etTitle.addTextChangedListener(mTextWatcherTitle)
binding.etContent.addTextChangedListener(mTextWatcherContent)
//prepare Room Database
mViewModel.prepareMemoDatabase()
}
override fun onStop() {
printLog("onStop")
super.onStop()
//remove listener
binding.etTitle.removeTextChangedListener(mTextWatcherTitle)
binding.etContent.removeTextChangedListener(mTextWatcherContent)
}
override fun onDestroy() {
printLog("onDestroy")
super.onDestroy()
}
// onCreateOptionsMenu() 앱바(App Bar)에 메뉴 리소스 XML을 표시하는데 사용
// The onCreate method is called first, and before it finishes onCreateOptionsMenu is called.
override fun onCreateOptionsMenu(menu: Menu?): Boolean {
menuInflater.inflate(R.menu.menu_item_write_memo, menu)
//MenuInflater(this).inflate(R.menu.menu_test, menu) 항상 오버플로우에 표시되었음...
return true
}
//Activity의 invalidateOptionsMenu()통해 자동으로 호출된다.
override fun onPrepareOptionsMenu(menu: Menu?): Boolean {
return true
}
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.itemId) {
R.id.item_memo_save -> {
mViewModel.checkAndSave()
Toast.makeText(this, "메모를 저장하였습니다", Toast.LENGTH_LONG).show()
finish()
}
}
return true
}
fun printLog(str: String) {
Log.d("MYTEST", "WriteMemoActivity: $str")
}
}