sean.jin
Spark Code Blog
sean.jin
전체 방문자
오늘
어제
  • 분류 전체보기
    • 개발공부
      • Kotlin
      • LeetCode
      • Algorithm
      • React
    • 주식차트
    • 책리뷰
    • 유틸리티

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 자기개발
  • 책추천
  • 경제
  • 오
  • 초보
  • 쿼드러플위칭데이
  • 책
  • 트리플 위칭데이
  • 주식투자
  • 주식책리뷰
  • 아빠와 딸의 주식투자 레슨
  • 네마녀의날
  • 변동성
  • 주식입문자
  • 책리뷰
  • 부의 추월차선

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
sean.jin

Spark Code Blog

[Kotlin] MVVM Room Database : @Delete으로 Database에 데이터 삭제 - 간단한 저장소 만들기 5편
개발공부/Kotlin

[Kotlin] MVVM Room Database : @Delete으로 Database에 데이터 삭제 - 간단한 저장소 만들기 5편

2021. 7. 28. 17:40
반응형

지난 포스트

 

[Kotlin] MVVM Room Database 4편 : 간단한 저장소 만들기 - @Update로 Database 데이터 수정

지난 포스트 [Kotlin] MVVM Room Database 3편 : 간단한 저장소 만들기 - RecyclerView Adapter에 ViewModel LiveData 적용하기 지난 포스트 [Kotlin] MVVM Room Database 2편 : 간단한 저장소 만들기 - Navigatio..

underdog11.tistory.com

 

 

목표

 

이 포스트는 총 5편으로 이루어져 있습니다. 밑줄 친 항목이 이번 포스트에서 다룰 항목입니다. 

 

RoomDatabase 개념

  • Roomdatabase의 기본 요소인 Entity, Database, Dao 개념/구현 (1편)
  • LiveData, ViewModel, Repository를 이용하여 MVVM 아키텍처 구성(1편)

Insert 구성

  • Navigation Graph , NavHostFragment추가(2편)
  • 각 list, update, add fragment의 layout 및 프래그먼트 구현(2편)
  • Add Fragment를 여는 플로팅 버튼 추가 (2편)
  • DB browser를 통해 database 확인(2편)
  • RecyclerView에 들어갈 ItemLayout과 ListAdapter 추가(3편)
  • RecyclerView와 LiveData 적용하기(3편)
  • 위와 같이 Room database에 저장된 값을  Recyclerview와 연결하기 (3편)

Update 구성

  • Update layout 생성(4편)
  • Update Layout Navigation Graph에 연결(4편)
  • Navigation Argument 추가하기(4편)
  • 데이터베이스에 수정된 값 업데이트(4편)

 

Delete 구성

  • 제거 버튼 Action bar에 추가(5편)
  • 선택한 데이터 삭제(5편)
  • 모든 데이터 삭제(5편)

 

 

제거 버튼 Action bar에 추가

 

제거 아이콘 생성

 

제거할때 사용할 버튼 아이콘을 만들어보겠습니다. 

 

 

아래와 같이 만들어주었습니다. 

 

 

Action menu 생성

 

제거 버튼이 Action menu에 넣어줄 것이기 때문에, menu resource파일이 필요합니다. 아래와 같이 res아래에 새로운 menu파일을 만들어줍니다. 

 

 

  • res/menu/delete_menu

위에서 생성한 아이콘을 적용하였습니다.

 

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <item android:id="@+id/menu_delete"
        android:title="Delete"
        android:icon="@drawable/ic_baseline_delete_24"
        app:showAsAction="ifRoom"
        android:iconTint="@android:color/white"/> //tint적용은 min api level 26이 필요합니다.
</menu>

 

 

선택한 데이터 삭제

 

이제 만들어준 menu를 프래그먼트에 적용해보겠습니다. 

Dialog를 띄워서 정말 데이터를 지울것인지 한 번 더 물어보겠습니다. Yes를 누르면 args.currentuser가 뷰 모델에 deleteUser함수에게 전달되어 args.currentuser을 지우게 하겠습니다.  

 

  • fragments/update/UpdateFragments

 

class UpdateFragment : Fragment() {

    private val args by navArgs<UpdateFragmentArgs>()

    private lateinit var mUserViewModel:UserViewModel


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view =  inflater.inflate(R.layout.fragment_update, container, false)

        mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)

        view.updateFirstName_et.setText(args.currentUser.firstName)
        view.updateLastName_et.setText(args.currentUser.firstName)
        view.updateAge_et.setText(args.currentUser.age.toString())

        view.update_button.setOnClickListener{
            updateItem()
        }

        setHasOptionsMenu(true)

        return view
    }

    private fun updateItem(){
        val firstName = updateFirstName_et.text.toString()
        val lastName = updateLastName_et.text.toString()
        val age = Integer.parseInt(updateAge_et.text.toString())

        if (inputCheck(firstName,lastName,updateAge_et.text)){
            val updatedUser = User(args.currentUser.id, firstName, lastName,age)    
            mUserViewModel.updateUser(updatedUser)
            Toast.makeText(requireContext(),"UpdatedSuccessfully",Toast.LENGTH_SHORT).show()  
            findNavController().navigate(R.id.action_updateFragment_to_listFragment)
        } else{
            
            Toast.makeText(requireContext(),"Please fill out all field",Toast.LENGTH_SHORT).show()
        }
    }
    private fun inputCheck(firstName:String, lastName:String, age: Editable):Boolean{
        return !(TextUtils.isEmpty(firstName)&& TextUtils.isEmpty(lastName)&& age.isEmpty())
    }
    
    //추가 시작
    
    //action menu resource파일을 연결해줍니다. 
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.delete_menu, menu)
    }
	
    //action menu에 아이템이 클릭되었을때 
    override fun onOptionsItemSelected(item: MenuItem): Boolean {
    	//id.menu_delete이 클릭되면 deleteUser함수 실행
        if(item.itemId == R.id.menu_delete){
            deleteUser()//아래에 이어서 만들어보겠습니다.
        }
        return super.onOptionsItemSelected(item)
    }

    private fun deleteUser(){ //delteIcon이 나오면 Dialog를 띄워서 물어보겠습니다.
        val builder = AlertDialog.Builder(requireContext()) 
        builder.setPositiveButton("Yes"){ _, _ ->
        //yes클릭시 viewMOdel.deleteUser를 실행시킵니다. args.currentUser를 삭제하게됩니다.
            mUserViewModel.deleteUser(args.currentUser)
            Toast.makeText(requireContext(),"Suscessfully removed: ${args.currentUser.firstName}",Toast.LENGTH_SHORT).show()
        }
        builder.setNegativeButton("No") { _, _ ->
        //아무일도 일어나지않습니다.
        }
		
        //dialog의 UI세팅입니다.
        builder.setTitle("Delete ${args.currentUser.firstName}?")
        builder.setMessage("Are you sure to delete ${args.currentUser.firstName}")
        
        //dialog가 UI에 보여집니다.
        builder.create().show()
    }
    //추가 끝

}

 

선택할 리스트를 삭제할 @delete 을 Dao에 구현하겠습니다. 

 

  • data/UserDao

 

@Dao
interface UserDao {

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun addUser(user: User)

    @Update
    suspend fun updateUser(user:User)

//추가 시작
	
    //선택한 User를 지웁니다.
    @Delete
    suspend fun deleteUser(user:User)
    
    //모두지웁니다.
    @Query("DELETE FROM user_table")
    suspend fun deleteAllUsers()
//추가끝
       
    @Query("SELECT * FROM user_table ORDER BY id ASC")
    fun readAllData(): LiveData<List<User>>
}

 

  • repository/UserRepository

 

class UserRepository(private val userDao: UserDao) {

    val readAllData: LiveData<List<User>> = userDao.readAllData()

    suspend fun addUser(user: User){ 
        userDao.addUser(user) 
    }

    suspend fun updateUser(user:User){
        userDao.updateUser(user)
    }

//추가시작
    suspend fun deleteUser(user:User) { //
        userDao.deleteUser(user)
    }

    suspend fun deleteAllUsers() { //deleteAllUser을 실행합니다. 
        userDao.deleteAllUsers()
    }
    
//추가 끝


}

 

  • viewmodel/UserViewModel

 

class UserViewModel(application: Application): AndroidViewModel(application) {

    val readAllData:LiveData<List<User>>
    private val repository: UserRepository

    init {
        val userDao = UserDatabase.getDatabase(application).userDao()
        repository = UserRepository(userDao) //initialize repository
        readAllData = repository.readAllData
    }

    fun addUser(user: User){
        viewModelScope.launch(Dispatchers.IO) {
            repository.addUser(user)
        }
    }

    fun updateUser(user:User){
        viewModelScope.launch(Dispatchers.IO) {
            repository.updateUser(user)
        }
    }

//추가 시작
    fun deleteUser(user:User){
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteUser(user)
        }
    }

    fun deleteAllUsers(){
        viewModelScope.launch(Dispatchers.IO) {
            repository.deleteAllUsers()

        }
    }
    
//추가 끝

}

 

 

모든 데이터 삭제

 

모든데이터를 삭제하는 아이콘은 ListFragment actionmenu에 넣어주도록 하겠습니다. 

 

  • fragments/list/listFragment

 

class ListFragment : Fragment() {

    private lateinit var mUserViewModel: UserViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
    
        val view = inflater.inflate(R.layout.fragment_list, container, false)
        val adapter = ListAdapter()
        val recyclerView = view.recyclerview
        recyclerView.adapter = adapter
        recyclerView.layoutManager = LinearLayoutManager(requireContext())
        mUserViewModel = ViewModelProvider(this).get(UserViewModel::class.java)
        mUserViewModel.readAllData.observe(viewLifecycleOwner, Observer { user->
            
            adapter.setData(user)
        })

        view.floatingActionButton.setOnClickListener{
            findNavController().navigate(R.id.action_listFragment_to_addFragment) //플로팅 버튼을 누르면 addFragment로 화면전환합니다.
        }


//추가시작
		//메뉴 추가
        setHasOptionsMenu(true)

        return view
    }

	//delete user때와 같은 menu를 추가해주겠습니다.
    override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.delete_menu, menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if(item.itemId ==R.id.menu_delete){
            deleteAllUsers() //deleteAlluser 함수를 실행시킵니다.
        }
        return super.onOptionsItemSelected(item)
    }

    private fun deleteAllUsers() { //deleteUser를 만들어줬을때와 같이 dialog를 만들겠습니다.
        val builder = AlertDialog.Builder(requireContext())
        builder.setPositiveButton("Yse"){ _, _ ->
            mUserViewModel.deleteAllUsers()
            Toast.makeText(requireContext(),"Suscessfully removed everything ",
                Toast.LENGTH_SHORT).show()
        }
        builder.setNegativeButton("No") { _, _ ->
        }

        builder.setTitle("Delete delete everything?")
        builder.setMessage("Are you sure to delete everything?")
        builder.create().show()
    }
//추가 끝

}

 

repository와 viewmodel에 deleteAllUser에 해당하는 함수를 미리 작성해주었기 때문에, 완료되었습니다. 

 

이제 실행해봅시다. 

 

아래와같이 정상적으로 작동하는 걸 확인할 수 있습니다.

반응형

'개발공부 > Kotlin' 카테고리의 다른 글

[Kotlin] Activity, fragment 사이 데이터 결과 전달 2가지 방법 Fragment Result Api, ViewModel - Under Tech Blog  (0) 2022.02.09
[Android] 색상 선택창, 팔레트 구현하기 - Color Sheet 라이브러리 사용법  (2) 2021.08.16
[Kotlin] MVVM Room Database : @Update로 Database 데이터 수정 - 간단한 저장소 만들기 4편  (0) 2021.07.27
[Kotlin] MVVM Room Database : RecyclerView Adapter에 ViewModel LiveData 적용하기 - 간단한 저장소 만들기 3편  (1) 2021.07.27
[Kotlin] MVVM Room Database : Navigation Graph 사용법, NavHostFragment, Insert 구성하기 간단한 저장소 만들기 - 2편  (0) 2021.07.26
    '개발공부/Kotlin' 카테고리의 다른 글
    • [Kotlin] Activity, fragment 사이 데이터 결과 전달 2가지 방법 Fragment Result Api, ViewModel - Under Tech Blog
    • [Android] 색상 선택창, 팔레트 구현하기 - Color Sheet 라이브러리 사용법
    • [Kotlin] MVVM Room Database : @Update로 Database 데이터 수정 - 간단한 저장소 만들기 4편
    • [Kotlin] MVVM Room Database : RecyclerView Adapter에 ViewModel LiveData 적용하기 - 간단한 저장소 만들기 3편
    sean.jin
    sean.jin
    앱개발, 알고리즘, JS, Kotlin, 미국 취업준비

    티스토리툴바