<Day30>动手做 Demo App(下)

使用 room 来建立Database

abstract class AppDatabase: RoomDatabase() {
    companion object {
        private const val DATABASE_NAME = "_db"

        // For Singleton instantiation
        @Volatile private var instance: AppDatabase? = null

        fun getInstance(context: Context): AppDatabase {
            return instance ?: synchronized(this) {
                instance ?: buildDatabase(context).also { instance = it }
            }
        }

        private fun buildDatabase(context: Context): AppDatabase {
            return Room.databaseBuilder(context, AppDatabase::class.java, DATABASE_NAME).build()
        }
    }

      abstract fun peopleDao(): PeopleDao
}

//建立table 所需要的栏位

@Entity(
    tableName = Person.TABLE_NAME
)
data class Person (
    @ColumnInfo(name = COLUMN_Name) var title: String,
    @ColumnInfo(name = COLUMN_CREATED_DATE) var createdDate: Date
) {
    companion object {
        const val TABLE_NAME = "person"
        const val COLUMN_ID = "id"
        const val COLUMN_NAME = "name"
        const val COLUMN_CREATED_DATE = "created_date"
    }
    
    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = COLUMN_ID) var id: Int = 0
}

// 实作 新增与查询

class PersonRepository(
    private val database: AppDatabase
) {
    suspend fun insertPerson(person: Person) {
        database.peopleDao().insert(person)
    }

    suspend fun updatePerson(person: Person) {
        database.peopleDao().update(person)
    }

    fun getAll(): LiveData<List<Person>> {
        return database.peopleDao().findAll()
    }
}

ViewModel conncet repository Data


class PeopleViewModel(private val repository: PersonRepository) : ViewModel() {

    private val title = Person.Title("联络人清单")

    val todoLiveData: LiveData<List<Todo>> = MediatorLiveData<List<Todo>>().apply {
        val source = repository.getAll().map {
            it.map { person ->
                Person.Item(
                    person.id,
                    person.name,
                    person.done,
                    person.createdDate
                )
            }
        }
        addSource(source) {
            this.value = mutableListOf(title) + it
        }
        value = mutableListOf(title)
    }

    fun createNewTodo(name: String) {
        val person = Person(
            name = name,
            createdDate = Date()
        )
        viewModelScope.launch {
            repository.insertPerson(person)
        }
    }

    fun updateTodo(person: Person.Item) {
        val person = Person(
            name = person.name,
            createdDate = person.createdDate
        ).apply { id = person.id }

        viewModelScope.launch {
            repository.updatePerson(person)
        }
    }
}

从DB读取资料,显示清单页 data放入recyclerView

class ListFragment : Fragment() {

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        ...........
        val peopleDb = AppDatabase.getInstance(requireActivity().applicationContext)
        val peopleRepo = PersonRepository(peopleDb)
        val viewModelFactory = AnyViewModelFactory {
            peopleViewModel(peopleRepo)
        }
        
        //  recyclerView  ListAdapter  Listener  data change
         val adapter = PersonAdapter().apply {
            onTodoChangeListener = object : OnTodoChangeListener {
                override fun onChange(person: Person.Item) {
                    peopleViewModel.updateTodo(person)
                }
            }
        }
        
        recyclerView.adapter = adapter
        recyclerView.layoutManager =
            LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        recyclerView.addItemDecoration(
            DividerItemDecoration(
                requireContext(),
                LinearLayoutManager.VERTICAL
            )
        )
        
       val peopleViewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(PeopleViewModel::class.java)
       
         peopleViewModel.personLiveData.observe(viewLifecycleOwner, Observer { todos: List<Todo> ->
            adapter.submitList(todos)
        })

}
}

新增页面,点选新增按钮


 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        .....
        val peopleDb = AppDatabase.getInstance(requireActivity().applicationContext)
        val peopleRepo = PersonRepository(peopleDb)
        val viewModelFactory = AnyViewModelFactory {
            peopleViewModel(peopleRepo)
        }
        
          val peopleViewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(PeopleViewModel::class.java)
       
         ........
        buttonAdd.setOnClickListener {
            if (name.text.isNullOrEmpty()) {
                name.error = "尚未填写新增联络人"
            } else {
                name.error = null
                val name = name.text.toString()
                peopleViewModel.createNewPerson(name)
                findNavController().popBackStack()
            }
        }
    }

资料存在app db 里, app 关掉再打开後资料仍存在,完成简单新增联络人

https://ithelp.ithome.com.tw/upload/images/20201013/20130598Jk3dTuZUXC.png

reference:https://www.notion.so/Navigation-component-9-9-Andy-a1245a1b31c5453fbf1b28f887ec0d73
reference:https://enginebai.com/2019/04/03/android-database-room/
reference:https://givemepass.blogspot.com/2015/12/recyclerview.html
reference:https://medium.com/evan-android-note/android-fragment-%E5%85%B1%E7%94%A8-viewmodel-19a6d9161421


<<:  Day28:HTML(26) form(5)

>>:  JS AJAX基础实作(3) DAY28

[Day7] Array Cardio Day 2

[Day7] Array Cardio Day 2 Javascript 的技巧 需要用到的技巧与练...

Day 11:Router 怎麽绕-router-link、router-view

大家应该也发现到了,目前点选 Navbar 项目并没有任何反应;但是点选公版中的 Home 和 Ab...

Day 16 撰写一个 dockerfile,和 vue-cli 服务进行整合开发

使用 Vue 作为前端框架的开发者,对於 vue-cli 想必不陌生。将 Docker 和 vue-...

最完整!转专业 CS 补学分:你适合哪种路线?

学校:University of Colorado Boulder 科系:post-baccala...

最终章:Todo List实作

前面提到了物件、阵列、DOM元素的选取、事件监听,以及最後的localStorage。这些足够我们...