-
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") } }