카테고리 없음

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

}