Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin LiveData不更新UI(使用ViewModel和Room数据库)_Kotlin_Mvvm_Viewmodel_Android Livedata_Room - Fatal编程技术网

Kotlin LiveData不更新UI(使用ViewModel和Room数据库)

Kotlin LiveData不更新UI(使用ViewModel和Room数据库),kotlin,mvvm,viewmodel,android-livedata,room,Kotlin,Mvvm,Viewmodel,Android Livedata,Room,因此,我使用LiveData和ViewModel设置获取和插入数据的功能,并使用Room数据库保存数据 将数据插入数据库后,我的RecyclerView不会更新数据 RecyclerAdapterTransaksi.kt class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) : RecyclerView.Adapter<RecyclerAdapte

因此,我使用LiveData和ViewModel设置获取和插入数据的功能,并使用Room数据库保存数据

将数据插入数据库后,我的RecyclerView不会更新数据

RecyclerAdapterTransaksi.kt

class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) :
RecyclerView.Adapter<RecyclerAdapterTransaksi.TransaksiViewHolder>() {

private var listTransaksi = arrayListOf<Transaksi>()

fun setListTransaksi(listTransaksi: ArrayList<Transaksi>) {
    this.listTransaksi = listTransaksi
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransaksiViewHolder {
    context = parent.context

    val binding = ListItemBinding.inflate(LayoutInflater.from(context), parent, false)

    return TransaksiViewHolder(binding)
}

override fun onBindViewHolder(holder: TransaksiViewHolder, position: Int) {
    holder.bindItem(listTransaksi[position], listener)
}

override fun getItemCount(): Int = listTransaksi.size

class TransaksiViewHolder(private val binding: ListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SimpleDateFormat")
    fun bindItem(transaksi: Transaksi, listener: (Transaksi) -> Unit) {
        binding.textViewNamaTransaksi.text = transaksi.namaTransaksi
        binding.textViewJmlTransaksi.text = transaksi.total.toString()
        binding.textViewTglTransaksi.text = SimpleDateFormat("dd MMM yyyy").format(transaksi.tglTransaksi!!)
        itemView.setOnClickListener {
            listener(transaksi)
        }

    }
}
}
class PemasukkanFragment : Fragment() {

    private var _binding: FragmentPemasukkanBinding? = null
    private val binding get() = _binding!!

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(requireContext()).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentPemasukkanBinding.inflate(inflater, container, false)

        binding.fabPemasukkan.setOnClickListener {
            val intent = Intent(requireContext(), TambahDataActivity::class.java)
            intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
            intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_TAMBAH)
            startActivity(intent)
        }
        getDataPemasukkan()
        return binding.root
    }


    private fun getDataPemasukkan() {
        binding.recyclerViewPemasukan.setHasFixedSize(true)
        binding.recyclerViewPemasukan.layoutManager = LinearLayoutManager(requireContext())

        val adapter = RecyclerAdapterTransaksi(requireContext()) {
            //action when item clicked
           showKonfirmasiEdit(it)
        }
        binding.recyclerViewPemasukan.adapter = adapter

        viewModel.getData(Date(), Constant.PEMASUKKAN)
        viewModel.dataTransaksi.observe(viewLifecycleOwner, Observer {
            adapter.setListTransaksi(it as ArrayList<Transaksi>)
        })
    }

    private fun showKonfirmasiEdit(transaksi: Transaksi){
        val intent = Intent(requireContext(),TambahDataActivity::class.java)

        val builder = AlertDialog.Builder(requireContext())
            .setMessage(R.string.edit_message)
            .setPositiveButton(R.string.edit){_,_ ->
                intent.putExtra(Constant.DATA_PEMASUKKAN, transaksi)
                intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
                intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_EDIT)
                startActivity(intent)
            }
            .setNegativeButton(R.string.batal){dialog, _ ->
                dialog.cancel()
            }
        builder.show()
    }

}
class TransaksiViewModel(private val dao: TransaksiDao) : ViewModel() {

    private var _dataTransaksi = MutableLiveData<List<Transaksi>>()
    val dataTransaksi: LiveData<List<Transaksi>>
        get() = _dataTransaksi

    private suspend fun getDataTransaksi(tgl : Date, tipe : String) = withContext(Dispatchers.IO) {
        dao.getData(tgl, tipe)
    }

    fun getData(tgl : Date, tipe : String) {
        viewModelScope.launch {
            _dataTransaksi.postValue(getDataTransaksi(tgl, tipe))
        }
    }

    fun inserDataTransaksi(transaksi: Transaksi) {
        viewModelScope.launch {
            insertTransaksi(transaksi)
        }
    }

    private suspend fun insertTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO) {
            dao.insertDataTransaksi(transaksi)
        }
    }

    fun updateDataTransaksi(transaksi: Transaksi){
        viewModelScope.launch {
            updateTransaksi(transaksi)
        }
    }

    private suspend fun updateTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO){
            dao.updateDataTransaksi(transaksi)
        }
    }
}
@Dao
interface TransaksiDao {
    @Insert
    fun insertDataTransaksi(transaksi: Transaksi)

    @Query("SELECT * FROM transaksi WHERE datetime(tanggal/1000,'unixepoch','start of month') = datetime(:tgl/1000,'unixepoch','start of month') AND jenis = :tipe ORDER BY id DESC")
    fun getData(tgl : Date, tipe : String): List<Transaksi>

    @Update
    fun updateDataTransaksi(transaksi: Transaksi)
}
class TambahDataActivity : AppCompatActivity() {

    private lateinit var binding: ActivityTambahDataBinding

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(this).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }

    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTambahDataBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)

        val getAksi = intent.getStringExtra(Constant.TIPE_AKSI)
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)
            if(dataPemasukan != null){
                getDataFromIntent(dataPemasukan)
            }
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)
            if(dataPengeluaran != null){
                getDataFromIntent(dataPengeluaran)
            }
        }
        if(getAksi == Constant.AKSI_EDIT){
            binding.buttonTambah.text = getString(R.string.edit)
            title = getString(R.string.edit_data)
        }
        binding.textViewTanggal.setOnClickListener { showDatePickerDialog() }
        binding.buttonTambah.setOnClickListener {
            if(getAksi == Constant.AKSI_TAMBAH){
                insertData()
            }else if(getAksi == Constant.AKSI_EDIT){
                updateData()
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun insertData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        val transaksi = Transaksi(
            0,
            namaTransaksi.toString(),
            jenisTransaksi,
            jumlahTransaki.toString().toInt(),
            tanggalTransaksi
        )
        viewModel.inserDataTransaksi(transaksi).apply { finish() }
    }

    @SuppressLint("SimpleDateFormat")
    private fun updateData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)!!
            val transaksi = Transaksi(dataPemasukan.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)!!
            val transaksi = Transaksi(dataPengeluaran.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun getDataFromIntent(data : Transaksi?){
        if(data != null){
            binding.editTextKeterangan.setText(data.namaTransaksi)
            binding.editTextJumlah.setText(data.total.toString())
            binding.textViewTanggal.text = SimpleDateFormat("dd-MM-yyyy").format(data.tglTransaksi!!)
        }

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> finish()
        }
        return true
    }

    @SuppressLint("SetTextI18n")
    private fun showDatePickerDialog() {
        val calendar = Calendar.getInstance()
        val tahun = calendar.get(Calendar.YEAR)
        val bulan = calendar.get(Calendar.MONTH)
        val hari = calendar.get(Calendar.DAY_OF_MONTH)
        val datePicker = DatePickerDialog(
            this,
            DatePickerDialog.OnDateSetListener { view, _year, monthOfYear, dayOfMonth ->
                binding.textViewTanggal.text = "$dayOfMonth-${monthOfYear + 1}-$_year "
            },
            tahun,
            bulan,
            hari
        )
        datePicker.show()
    }
class RecyclerAdapterTransaksi(变量上下文:上下文,私有val侦听器:(Transaksi)->Unit):
RecyclerView.Adapter(){
私有变量listTransaksi=arrayListOf()
趣味设置listTransaksi(listTransaksi:ArrayList){
this.listTransaksi=listTransaksi
notifyDataSetChanged()
}
override fun onCreateViewHolder(父级:ViewGroup,viewType:Int):TransaksiViewHolder{
context=parent.context
val binding=ListItemBinding.inflate(LayoutFlater.from(上下文),父项,false)
返回传动轴万向节(绑定)
}
覆盖BindViewHolder(支架:TransaksiViewHolder,位置:Int){
holder.bindItem(listTransaksi[位置],侦听器)
}
重写fun getItemCount():Int=listTransaksi.size
类TransaksiViewHolder(私有值绑定:ListItemBinding):
RecyclerView.ViewHolder(binding.root){
@SuppressLint(“SimpleDataFormat”)
fun bindItem(transaksi:transaksi,listener:(transaksi)->单位){
binding.textViewNamaTransaksi.text=transaksi.namaTransaksi
binding.textViewJmlTransaksi.text=transaksi.total.toString()
binding.textViewTglTransaksi.text=SimpleDataFormat(“dd-MMM-yyyy”).format(transaksi.tglTransaksi!!)
itemView.setOnClickListener{
监听器(transaksi)
}
}
}
}
使用RecyclerView显示数据库数据的片段

pemasukanfragment.kt

class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) :
RecyclerView.Adapter<RecyclerAdapterTransaksi.TransaksiViewHolder>() {

private var listTransaksi = arrayListOf<Transaksi>()

fun setListTransaksi(listTransaksi: ArrayList<Transaksi>) {
    this.listTransaksi = listTransaksi
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransaksiViewHolder {
    context = parent.context

    val binding = ListItemBinding.inflate(LayoutInflater.from(context), parent, false)

    return TransaksiViewHolder(binding)
}

override fun onBindViewHolder(holder: TransaksiViewHolder, position: Int) {
    holder.bindItem(listTransaksi[position], listener)
}

override fun getItemCount(): Int = listTransaksi.size

class TransaksiViewHolder(private val binding: ListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SimpleDateFormat")
    fun bindItem(transaksi: Transaksi, listener: (Transaksi) -> Unit) {
        binding.textViewNamaTransaksi.text = transaksi.namaTransaksi
        binding.textViewJmlTransaksi.text = transaksi.total.toString()
        binding.textViewTglTransaksi.text = SimpleDateFormat("dd MMM yyyy").format(transaksi.tglTransaksi!!)
        itemView.setOnClickListener {
            listener(transaksi)
        }

    }
}
}
class PemasukkanFragment : Fragment() {

    private var _binding: FragmentPemasukkanBinding? = null
    private val binding get() = _binding!!

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(requireContext()).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentPemasukkanBinding.inflate(inflater, container, false)

        binding.fabPemasukkan.setOnClickListener {
            val intent = Intent(requireContext(), TambahDataActivity::class.java)
            intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
            intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_TAMBAH)
            startActivity(intent)
        }
        getDataPemasukkan()
        return binding.root
    }


    private fun getDataPemasukkan() {
        binding.recyclerViewPemasukan.setHasFixedSize(true)
        binding.recyclerViewPemasukan.layoutManager = LinearLayoutManager(requireContext())

        val adapter = RecyclerAdapterTransaksi(requireContext()) {
            //action when item clicked
           showKonfirmasiEdit(it)
        }
        binding.recyclerViewPemasukan.adapter = adapter

        viewModel.getData(Date(), Constant.PEMASUKKAN)
        viewModel.dataTransaksi.observe(viewLifecycleOwner, Observer {
            adapter.setListTransaksi(it as ArrayList<Transaksi>)
        })
    }

    private fun showKonfirmasiEdit(transaksi: Transaksi){
        val intent = Intent(requireContext(),TambahDataActivity::class.java)

        val builder = AlertDialog.Builder(requireContext())
            .setMessage(R.string.edit_message)
            .setPositiveButton(R.string.edit){_,_ ->
                intent.putExtra(Constant.DATA_PEMASUKKAN, transaksi)
                intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
                intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_EDIT)
                startActivity(intent)
            }
            .setNegativeButton(R.string.batal){dialog, _ ->
                dialog.cancel()
            }
        builder.show()
    }

}
class TransaksiViewModel(private val dao: TransaksiDao) : ViewModel() {

    private var _dataTransaksi = MutableLiveData<List<Transaksi>>()
    val dataTransaksi: LiveData<List<Transaksi>>
        get() = _dataTransaksi

    private suspend fun getDataTransaksi(tgl : Date, tipe : String) = withContext(Dispatchers.IO) {
        dao.getData(tgl, tipe)
    }

    fun getData(tgl : Date, tipe : String) {
        viewModelScope.launch {
            _dataTransaksi.postValue(getDataTransaksi(tgl, tipe))
        }
    }

    fun inserDataTransaksi(transaksi: Transaksi) {
        viewModelScope.launch {
            insertTransaksi(transaksi)
        }
    }

    private suspend fun insertTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO) {
            dao.insertDataTransaksi(transaksi)
        }
    }

    fun updateDataTransaksi(transaksi: Transaksi){
        viewModelScope.launch {
            updateTransaksi(transaksi)
        }
    }

    private suspend fun updateTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO){
            dao.updateDataTransaksi(transaksi)
        }
    }
}
@Dao
interface TransaksiDao {
    @Insert
    fun insertDataTransaksi(transaksi: Transaksi)

    @Query("SELECT * FROM transaksi WHERE datetime(tanggal/1000,'unixepoch','start of month') = datetime(:tgl/1000,'unixepoch','start of month') AND jenis = :tipe ORDER BY id DESC")
    fun getData(tgl : Date, tipe : String): List<Transaksi>

    @Update
    fun updateDataTransaksi(transaksi: Transaksi)
}
class TambahDataActivity : AppCompatActivity() {

    private lateinit var binding: ActivityTambahDataBinding

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(this).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }

    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTambahDataBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)

        val getAksi = intent.getStringExtra(Constant.TIPE_AKSI)
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)
            if(dataPemasukan != null){
                getDataFromIntent(dataPemasukan)
            }
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)
            if(dataPengeluaran != null){
                getDataFromIntent(dataPengeluaran)
            }
        }
        if(getAksi == Constant.AKSI_EDIT){
            binding.buttonTambah.text = getString(R.string.edit)
            title = getString(R.string.edit_data)
        }
        binding.textViewTanggal.setOnClickListener { showDatePickerDialog() }
        binding.buttonTambah.setOnClickListener {
            if(getAksi == Constant.AKSI_TAMBAH){
                insertData()
            }else if(getAksi == Constant.AKSI_EDIT){
                updateData()
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun insertData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        val transaksi = Transaksi(
            0,
            namaTransaksi.toString(),
            jenisTransaksi,
            jumlahTransaki.toString().toInt(),
            tanggalTransaksi
        )
        viewModel.inserDataTransaksi(transaksi).apply { finish() }
    }

    @SuppressLint("SimpleDateFormat")
    private fun updateData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)!!
            val transaksi = Transaksi(dataPemasukan.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)!!
            val transaksi = Transaksi(dataPengeluaran.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun getDataFromIntent(data : Transaksi?){
        if(data != null){
            binding.editTextKeterangan.setText(data.namaTransaksi)
            binding.editTextJumlah.setText(data.total.toString())
            binding.textViewTanggal.text = SimpleDateFormat("dd-MM-yyyy").format(data.tglTransaksi!!)
        }

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> finish()
        }
        return true
    }

    @SuppressLint("SetTextI18n")
    private fun showDatePickerDialog() {
        val calendar = Calendar.getInstance()
        val tahun = calendar.get(Calendar.YEAR)
        val bulan = calendar.get(Calendar.MONTH)
        val hari = calendar.get(Calendar.DAY_OF_MONTH)
        val datePicker = DatePickerDialog(
            this,
            DatePickerDialog.OnDateSetListener { view, _year, monthOfYear, dayOfMonth ->
                binding.textViewTanggal.text = "$dayOfMonth-${monthOfYear + 1}-$_year "
            },
            tahun,
            bulan,
            hari
        )
        datePicker.show()
    }
类pemasukanfragment:Fragment(){
私有变量绑定:FragmentPemasukkanBinding?=null
private val binding get()=\u binding!!
private val viewModel:TransaksiViewModel by lazy{
val dataSource=UwangkuDatabase.getInstance(requireContext()).transactionDao
val工厂=TransakSiveWModelFactory(数据源)
ViewModelProvider(这个,工厂).get(TransaksiViewModel::class.java)
}
覆盖创建视图(
充气器:布局充气器,容器:视图组?,
savedInstanceState:捆绑?
):查看{
//为该碎片膨胀布局
_装订=碎片装订。充气(充气机、容器、假)
binding.fabPemasukkan.setOnClickListener{
val intent=intent(requireContext(),TambahDataActivity::class.java)
意向。额外支付(常量。TIPE_TRANSAKSI,常量。PEMASUKKAN)
intent.putExtra(Constant.TIPE_-AKSI,Constant.AKSI_-TAMBAH)
星触觉(意图)
}
getDataPemasukkan()
返回binding.root
}
私人娱乐getDataPemasukkan(){
binding.RecycleServiceWPEmasukan.setHasFixedSize(true)
binding.RecycleServiceWPemasukan.layoutManager=LinearLayoutManager(requireContext())
val适配器=RecyclerAdapterTransaksi(requireContext()){
//单击项目时的操作
showKonfirmasiEdit(it)
}
binding.recyclerivewpemasukan.adapter=适配器
viewModel.getData(Date(),Constant.pemasukan)
viewModel.dataTransaksi.observe(viewLifecycleOwner,Observer{
adapter.setListTransaksi(它作为ArrayList)
})
}
私人娱乐showKonfirmasiEdit(transaksi:transaksi){
val intent=intent(requireContext(),TambahDataActivity::class.java)
val builder=AlertDialog.builder(requireContext())
.setMessage(R.string.edit_消息)
.setPositiveButton(R.string.edit){{},{->
意图.额外支出(常量.数据_pemasukan,transaksi)
意向。额外支付(常量。TIPE_TRANSAKSI,常量。PEMASUKKAN)
intent.putExtra(Constant.TIPE_-AKSI,Constant.AKSI_-EDIT)
星触觉(意图)
}
.setNegativeButton(R.string.batal){dialog,\->
dialog.cancel()
}
builder.show()
}
}
使用LiveData的ViewModel类

Transaksivewmodel.kt

class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) :
RecyclerView.Adapter<RecyclerAdapterTransaksi.TransaksiViewHolder>() {

private var listTransaksi = arrayListOf<Transaksi>()

fun setListTransaksi(listTransaksi: ArrayList<Transaksi>) {
    this.listTransaksi = listTransaksi
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransaksiViewHolder {
    context = parent.context

    val binding = ListItemBinding.inflate(LayoutInflater.from(context), parent, false)

    return TransaksiViewHolder(binding)
}

override fun onBindViewHolder(holder: TransaksiViewHolder, position: Int) {
    holder.bindItem(listTransaksi[position], listener)
}

override fun getItemCount(): Int = listTransaksi.size

class TransaksiViewHolder(private val binding: ListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SimpleDateFormat")
    fun bindItem(transaksi: Transaksi, listener: (Transaksi) -> Unit) {
        binding.textViewNamaTransaksi.text = transaksi.namaTransaksi
        binding.textViewJmlTransaksi.text = transaksi.total.toString()
        binding.textViewTglTransaksi.text = SimpleDateFormat("dd MMM yyyy").format(transaksi.tglTransaksi!!)
        itemView.setOnClickListener {
            listener(transaksi)
        }

    }
}
}
class PemasukkanFragment : Fragment() {

    private var _binding: FragmentPemasukkanBinding? = null
    private val binding get() = _binding!!

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(requireContext()).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentPemasukkanBinding.inflate(inflater, container, false)

        binding.fabPemasukkan.setOnClickListener {
            val intent = Intent(requireContext(), TambahDataActivity::class.java)
            intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
            intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_TAMBAH)
            startActivity(intent)
        }
        getDataPemasukkan()
        return binding.root
    }


    private fun getDataPemasukkan() {
        binding.recyclerViewPemasukan.setHasFixedSize(true)
        binding.recyclerViewPemasukan.layoutManager = LinearLayoutManager(requireContext())

        val adapter = RecyclerAdapterTransaksi(requireContext()) {
            //action when item clicked
           showKonfirmasiEdit(it)
        }
        binding.recyclerViewPemasukan.adapter = adapter

        viewModel.getData(Date(), Constant.PEMASUKKAN)
        viewModel.dataTransaksi.observe(viewLifecycleOwner, Observer {
            adapter.setListTransaksi(it as ArrayList<Transaksi>)
        })
    }

    private fun showKonfirmasiEdit(transaksi: Transaksi){
        val intent = Intent(requireContext(),TambahDataActivity::class.java)

        val builder = AlertDialog.Builder(requireContext())
            .setMessage(R.string.edit_message)
            .setPositiveButton(R.string.edit){_,_ ->
                intent.putExtra(Constant.DATA_PEMASUKKAN, transaksi)
                intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
                intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_EDIT)
                startActivity(intent)
            }
            .setNegativeButton(R.string.batal){dialog, _ ->
                dialog.cancel()
            }
        builder.show()
    }

}
class TransaksiViewModel(private val dao: TransaksiDao) : ViewModel() {

    private var _dataTransaksi = MutableLiveData<List<Transaksi>>()
    val dataTransaksi: LiveData<List<Transaksi>>
        get() = _dataTransaksi

    private suspend fun getDataTransaksi(tgl : Date, tipe : String) = withContext(Dispatchers.IO) {
        dao.getData(tgl, tipe)
    }

    fun getData(tgl : Date, tipe : String) {
        viewModelScope.launch {
            _dataTransaksi.postValue(getDataTransaksi(tgl, tipe))
        }
    }

    fun inserDataTransaksi(transaksi: Transaksi) {
        viewModelScope.launch {
            insertTransaksi(transaksi)
        }
    }

    private suspend fun insertTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO) {
            dao.insertDataTransaksi(transaksi)
        }
    }

    fun updateDataTransaksi(transaksi: Transaksi){
        viewModelScope.launch {
            updateTransaksi(transaksi)
        }
    }

    private suspend fun updateTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO){
            dao.updateDataTransaksi(transaksi)
        }
    }
}
@Dao
interface TransaksiDao {
    @Insert
    fun insertDataTransaksi(transaksi: Transaksi)

    @Query("SELECT * FROM transaksi WHERE datetime(tanggal/1000,'unixepoch','start of month') = datetime(:tgl/1000,'unixepoch','start of month') AND jenis = :tipe ORDER BY id DESC")
    fun getData(tgl : Date, tipe : String): List<Transaksi>

    @Update
    fun updateDataTransaksi(transaksi: Transaksi)
}
class TambahDataActivity : AppCompatActivity() {

    private lateinit var binding: ActivityTambahDataBinding

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(this).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }

    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTambahDataBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)

        val getAksi = intent.getStringExtra(Constant.TIPE_AKSI)
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)
            if(dataPemasukan != null){
                getDataFromIntent(dataPemasukan)
            }
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)
            if(dataPengeluaran != null){
                getDataFromIntent(dataPengeluaran)
            }
        }
        if(getAksi == Constant.AKSI_EDIT){
            binding.buttonTambah.text = getString(R.string.edit)
            title = getString(R.string.edit_data)
        }
        binding.textViewTanggal.setOnClickListener { showDatePickerDialog() }
        binding.buttonTambah.setOnClickListener {
            if(getAksi == Constant.AKSI_TAMBAH){
                insertData()
            }else if(getAksi == Constant.AKSI_EDIT){
                updateData()
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun insertData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        val transaksi = Transaksi(
            0,
            namaTransaksi.toString(),
            jenisTransaksi,
            jumlahTransaki.toString().toInt(),
            tanggalTransaksi
        )
        viewModel.inserDataTransaksi(transaksi).apply { finish() }
    }

    @SuppressLint("SimpleDateFormat")
    private fun updateData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)!!
            val transaksi = Transaksi(dataPemasukan.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)!!
            val transaksi = Transaksi(dataPengeluaran.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun getDataFromIntent(data : Transaksi?){
        if(data != null){
            binding.editTextKeterangan.setText(data.namaTransaksi)
            binding.editTextJumlah.setText(data.total.toString())
            binding.textViewTanggal.text = SimpleDateFormat("dd-MM-yyyy").format(data.tglTransaksi!!)
        }

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> finish()
        }
        return true
    }

    @SuppressLint("SetTextI18n")
    private fun showDatePickerDialog() {
        val calendar = Calendar.getInstance()
        val tahun = calendar.get(Calendar.YEAR)
        val bulan = calendar.get(Calendar.MONTH)
        val hari = calendar.get(Calendar.DAY_OF_MONTH)
        val datePicker = DatePickerDialog(
            this,
            DatePickerDialog.OnDateSetListener { view, _year, monthOfYear, dayOfMonth ->
                binding.textViewTanggal.text = "$dayOfMonth-${monthOfYear + 1}-$_year "
            },
            tahun,
            bulan,
            hari
        )
        datePicker.show()
    }
class transaksivewmodel(私有val-dao:TransaksiDao):ViewModel(){
私有变量_dataTransaksi=MutableLiveData()
val dataTransaksi:LiveData
get()=\u数据传输
私有的getDataTransaksi(tgl:Date,tipe:String)=withContext(Dispatchers.IO){
dao.getData(tgl、tipe)
}
fun-getData(tgl:Date,tipe:String){
viewModelScope.launch{
_dataTransaksi.postValue(getDataTransaksi(tgl,tipe))
}
}
有趣的插曲transaksi(transaksi:transaksi){
viewModelScope.launch{
插入transaksi(transaksi)
}
}
私家车暂停乐趣插入transaksi(transaksi:transaksi){
withContext(Dispatchers.IO){
dao.insertDataTransaksi(transaksi)
}
}
有趣的最新情况(transaksi:transaksi){
viewModelScope.launch{
updateTransaksi(transaksi)
}
}
私有挂起更新transaksi(transaksi:transaksi){
withContext(Dispatchers.IO){
dao.UpdateDataransaksi(transaksi)
}
}
}

TransakiDao.kt

class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) :
RecyclerView.Adapter<RecyclerAdapterTransaksi.TransaksiViewHolder>() {

private var listTransaksi = arrayListOf<Transaksi>()

fun setListTransaksi(listTransaksi: ArrayList<Transaksi>) {
    this.listTransaksi = listTransaksi
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransaksiViewHolder {
    context = parent.context

    val binding = ListItemBinding.inflate(LayoutInflater.from(context), parent, false)

    return TransaksiViewHolder(binding)
}

override fun onBindViewHolder(holder: TransaksiViewHolder, position: Int) {
    holder.bindItem(listTransaksi[position], listener)
}

override fun getItemCount(): Int = listTransaksi.size

class TransaksiViewHolder(private val binding: ListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SimpleDateFormat")
    fun bindItem(transaksi: Transaksi, listener: (Transaksi) -> Unit) {
        binding.textViewNamaTransaksi.text = transaksi.namaTransaksi
        binding.textViewJmlTransaksi.text = transaksi.total.toString()
        binding.textViewTglTransaksi.text = SimpleDateFormat("dd MMM yyyy").format(transaksi.tglTransaksi!!)
        itemView.setOnClickListener {
            listener(transaksi)
        }

    }
}
}
class PemasukkanFragment : Fragment() {

    private var _binding: FragmentPemasukkanBinding? = null
    private val binding get() = _binding!!

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(requireContext()).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentPemasukkanBinding.inflate(inflater, container, false)

        binding.fabPemasukkan.setOnClickListener {
            val intent = Intent(requireContext(), TambahDataActivity::class.java)
            intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
            intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_TAMBAH)
            startActivity(intent)
        }
        getDataPemasukkan()
        return binding.root
    }


    private fun getDataPemasukkan() {
        binding.recyclerViewPemasukan.setHasFixedSize(true)
        binding.recyclerViewPemasukan.layoutManager = LinearLayoutManager(requireContext())

        val adapter = RecyclerAdapterTransaksi(requireContext()) {
            //action when item clicked
           showKonfirmasiEdit(it)
        }
        binding.recyclerViewPemasukan.adapter = adapter

        viewModel.getData(Date(), Constant.PEMASUKKAN)
        viewModel.dataTransaksi.observe(viewLifecycleOwner, Observer {
            adapter.setListTransaksi(it as ArrayList<Transaksi>)
        })
    }

    private fun showKonfirmasiEdit(transaksi: Transaksi){
        val intent = Intent(requireContext(),TambahDataActivity::class.java)

        val builder = AlertDialog.Builder(requireContext())
            .setMessage(R.string.edit_message)
            .setPositiveButton(R.string.edit){_,_ ->
                intent.putExtra(Constant.DATA_PEMASUKKAN, transaksi)
                intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
                intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_EDIT)
                startActivity(intent)
            }
            .setNegativeButton(R.string.batal){dialog, _ ->
                dialog.cancel()
            }
        builder.show()
    }

}
class TransaksiViewModel(private val dao: TransaksiDao) : ViewModel() {

    private var _dataTransaksi = MutableLiveData<List<Transaksi>>()
    val dataTransaksi: LiveData<List<Transaksi>>
        get() = _dataTransaksi

    private suspend fun getDataTransaksi(tgl : Date, tipe : String) = withContext(Dispatchers.IO) {
        dao.getData(tgl, tipe)
    }

    fun getData(tgl : Date, tipe : String) {
        viewModelScope.launch {
            _dataTransaksi.postValue(getDataTransaksi(tgl, tipe))
        }
    }

    fun inserDataTransaksi(transaksi: Transaksi) {
        viewModelScope.launch {
            insertTransaksi(transaksi)
        }
    }

    private suspend fun insertTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO) {
            dao.insertDataTransaksi(transaksi)
        }
    }

    fun updateDataTransaksi(transaksi: Transaksi){
        viewModelScope.launch {
            updateTransaksi(transaksi)
        }
    }

    private suspend fun updateTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO){
            dao.updateDataTransaksi(transaksi)
        }
    }
}
@Dao
interface TransaksiDao {
    @Insert
    fun insertDataTransaksi(transaksi: Transaksi)

    @Query("SELECT * FROM transaksi WHERE datetime(tanggal/1000,'unixepoch','start of month') = datetime(:tgl/1000,'unixepoch','start of month') AND jenis = :tipe ORDER BY id DESC")
    fun getData(tgl : Date, tipe : String): List<Transaksi>

    @Update
    fun updateDataTransaksi(transaksi: Transaksi)
}
class TambahDataActivity : AppCompatActivity() {

    private lateinit var binding: ActivityTambahDataBinding

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(this).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }

    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTambahDataBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)

        val getAksi = intent.getStringExtra(Constant.TIPE_AKSI)
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)
            if(dataPemasukan != null){
                getDataFromIntent(dataPemasukan)
            }
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)
            if(dataPengeluaran != null){
                getDataFromIntent(dataPengeluaran)
            }
        }
        if(getAksi == Constant.AKSI_EDIT){
            binding.buttonTambah.text = getString(R.string.edit)
            title = getString(R.string.edit_data)
        }
        binding.textViewTanggal.setOnClickListener { showDatePickerDialog() }
        binding.buttonTambah.setOnClickListener {
            if(getAksi == Constant.AKSI_TAMBAH){
                insertData()
            }else if(getAksi == Constant.AKSI_EDIT){
                updateData()
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun insertData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        val transaksi = Transaksi(
            0,
            namaTransaksi.toString(),
            jenisTransaksi,
            jumlahTransaki.toString().toInt(),
            tanggalTransaksi
        )
        viewModel.inserDataTransaksi(transaksi).apply { finish() }
    }

    @SuppressLint("SimpleDateFormat")
    private fun updateData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)!!
            val transaksi = Transaksi(dataPemasukan.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)!!
            val transaksi = Transaksi(dataPengeluaran.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun getDataFromIntent(data : Transaksi?){
        if(data != null){
            binding.editTextKeterangan.setText(data.namaTransaksi)
            binding.editTextJumlah.setText(data.total.toString())
            binding.textViewTanggal.text = SimpleDateFormat("dd-MM-yyyy").format(data.tglTransaksi!!)
        }

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> finish()
        }
        return true
    }

    @SuppressLint("SetTextI18n")
    private fun showDatePickerDialog() {
        val calendar = Calendar.getInstance()
        val tahun = calendar.get(Calendar.YEAR)
        val bulan = calendar.get(Calendar.MONTH)
        val hari = calendar.get(Calendar.DAY_OF_MONTH)
        val datePicker = DatePickerDialog(
            this,
            DatePickerDialog.OnDateSetListener { view, _year, monthOfYear, dayOfMonth ->
                binding.textViewTanggal.text = "$dayOfMonth-${monthOfYear + 1}-$_year "
            },
            tahun,
            bulan,
            hari
        )
        datePicker.show()
    }
@Dao
接口传输{
@插入
fun insertDataTransaksi(transaksi:transaksi)
@查询(“从transaksi中选择*,其中datetime(tanggal/1000,'unixepoch','start of month')=日期时间(:tgl/1000,'unixepoch','start of month'),jenis=:tipe ORDER BY id DESC”)
fun-getData(tgl:Date,tipe:String):列表
@更新
有趣的最新情况(transaksi:transaksi)
}
将数据插入数据库的活动

TambahDataActivity.kt

class RecyclerAdapterTransaksi(var context: Context, private val listener: (Transaksi) -> Unit) :
RecyclerView.Adapter<RecyclerAdapterTransaksi.TransaksiViewHolder>() {

private var listTransaksi = arrayListOf<Transaksi>()

fun setListTransaksi(listTransaksi: ArrayList<Transaksi>) {
    this.listTransaksi = listTransaksi
    notifyDataSetChanged()
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransaksiViewHolder {
    context = parent.context

    val binding = ListItemBinding.inflate(LayoutInflater.from(context), parent, false)

    return TransaksiViewHolder(binding)
}

override fun onBindViewHolder(holder: TransaksiViewHolder, position: Int) {
    holder.bindItem(listTransaksi[position], listener)
}

override fun getItemCount(): Int = listTransaksi.size

class TransaksiViewHolder(private val binding: ListItemBinding) :
    RecyclerView.ViewHolder(binding.root) {
    @SuppressLint("SimpleDateFormat")
    fun bindItem(transaksi: Transaksi, listener: (Transaksi) -> Unit) {
        binding.textViewNamaTransaksi.text = transaksi.namaTransaksi
        binding.textViewJmlTransaksi.text = transaksi.total.toString()
        binding.textViewTglTransaksi.text = SimpleDateFormat("dd MMM yyyy").format(transaksi.tglTransaksi!!)
        itemView.setOnClickListener {
            listener(transaksi)
        }

    }
}
}
class PemasukkanFragment : Fragment() {

    private var _binding: FragmentPemasukkanBinding? = null
    private val binding get() = _binding!!

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(requireContext()).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        _binding = FragmentPemasukkanBinding.inflate(inflater, container, false)

        binding.fabPemasukkan.setOnClickListener {
            val intent = Intent(requireContext(), TambahDataActivity::class.java)
            intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
            intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_TAMBAH)
            startActivity(intent)
        }
        getDataPemasukkan()
        return binding.root
    }


    private fun getDataPemasukkan() {
        binding.recyclerViewPemasukan.setHasFixedSize(true)
        binding.recyclerViewPemasukan.layoutManager = LinearLayoutManager(requireContext())

        val adapter = RecyclerAdapterTransaksi(requireContext()) {
            //action when item clicked
           showKonfirmasiEdit(it)
        }
        binding.recyclerViewPemasukan.adapter = adapter

        viewModel.getData(Date(), Constant.PEMASUKKAN)
        viewModel.dataTransaksi.observe(viewLifecycleOwner, Observer {
            adapter.setListTransaksi(it as ArrayList<Transaksi>)
        })
    }

    private fun showKonfirmasiEdit(transaksi: Transaksi){
        val intent = Intent(requireContext(),TambahDataActivity::class.java)

        val builder = AlertDialog.Builder(requireContext())
            .setMessage(R.string.edit_message)
            .setPositiveButton(R.string.edit){_,_ ->
                intent.putExtra(Constant.DATA_PEMASUKKAN, transaksi)
                intent.putExtra(Constant.TIPE_TRANSAKSI, Constant.PEMASUKKAN)
                intent.putExtra(Constant.TIPE_AKSI, Constant.AKSI_EDIT)
                startActivity(intent)
            }
            .setNegativeButton(R.string.batal){dialog, _ ->
                dialog.cancel()
            }
        builder.show()
    }

}
class TransaksiViewModel(private val dao: TransaksiDao) : ViewModel() {

    private var _dataTransaksi = MutableLiveData<List<Transaksi>>()
    val dataTransaksi: LiveData<List<Transaksi>>
        get() = _dataTransaksi

    private suspend fun getDataTransaksi(tgl : Date, tipe : String) = withContext(Dispatchers.IO) {
        dao.getData(tgl, tipe)
    }

    fun getData(tgl : Date, tipe : String) {
        viewModelScope.launch {
            _dataTransaksi.postValue(getDataTransaksi(tgl, tipe))
        }
    }

    fun inserDataTransaksi(transaksi: Transaksi) {
        viewModelScope.launch {
            insertTransaksi(transaksi)
        }
    }

    private suspend fun insertTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO) {
            dao.insertDataTransaksi(transaksi)
        }
    }

    fun updateDataTransaksi(transaksi: Transaksi){
        viewModelScope.launch {
            updateTransaksi(transaksi)
        }
    }

    private suspend fun updateTransaksi(transaksi: Transaksi){
        withContext(Dispatchers.IO){
            dao.updateDataTransaksi(transaksi)
        }
    }
}
@Dao
interface TransaksiDao {
    @Insert
    fun insertDataTransaksi(transaksi: Transaksi)

    @Query("SELECT * FROM transaksi WHERE datetime(tanggal/1000,'unixepoch','start of month') = datetime(:tgl/1000,'unixepoch','start of month') AND jenis = :tipe ORDER BY id DESC")
    fun getData(tgl : Date, tipe : String): List<Transaksi>

    @Update
    fun updateDataTransaksi(transaksi: Transaksi)
}
class TambahDataActivity : AppCompatActivity() {

    private lateinit var binding: ActivityTambahDataBinding

    private val viewModel: TransaksiViewModel by lazy {
        val dataSource = UwangkuDatabase.getInstance(this).transactionDao
        val factory = TransaksiViewModelFactory(dataSource)
        ViewModelProvider(this, factory).get(TransaksiViewModel::class.java)
    }

    @SuppressLint("SimpleDateFormat")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityTambahDataBinding.inflate(layoutInflater)
        setContentView(binding.root)
        supportActionBar!!.setDisplayHomeAsUpEnabled(true)

        val getAksi = intent.getStringExtra(Constant.TIPE_AKSI)
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)
            if(dataPemasukan != null){
                getDataFromIntent(dataPemasukan)
            }
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)
            if(dataPengeluaran != null){
                getDataFromIntent(dataPengeluaran)
            }
        }
        if(getAksi == Constant.AKSI_EDIT){
            binding.buttonTambah.text = getString(R.string.edit)
            title = getString(R.string.edit_data)
        }
        binding.textViewTanggal.setOnClickListener { showDatePickerDialog() }
        binding.buttonTambah.setOnClickListener {
            if(getAksi == Constant.AKSI_TAMBAH){
                insertData()
            }else if(getAksi == Constant.AKSI_EDIT){
                updateData()
            }
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun insertData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        val transaksi = Transaksi(
            0,
            namaTransaksi.toString(),
            jenisTransaksi,
            jumlahTransaki.toString().toInt(),
            tanggalTransaksi
        )
        viewModel.inserDataTransaksi(transaksi).apply { finish() }
    }

    @SuppressLint("SimpleDateFormat")
    private fun updateData(){
        val namaTransaksi = binding.editTextKeterangan.text
        val jumlahTransaki = binding.editTextJumlah.text
        val getJenisTransaksi = intent.getStringExtra(Constant.TIPE_TRANSAKSI)
        val jenisTransaksi = if (getJenisTransaksi == Constant.PEMASUKKAN) {
            Constant.PEMASUKKAN
        } else {
            Constant.PENGELUARAN
        }
        val tanggalTransaksi =
            SimpleDateFormat("dd-MM-yyyy").parse(binding.textViewTanggal.text.toString())
        if(getJenisTransaksi == Constant.PEMASUKKAN){
            val dataPemasukan = intent.getParcelableExtra<Transaksi>(Constant.DATA_PEMASUKKAN)!!
            val transaksi = Transaksi(dataPemasukan.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        } else if(getJenisTransaksi == Constant.PENGELUARAN){
            val dataPengeluaran = intent.getParcelableExtra<Transaksi>(Constant.DATA_PENGELUARAN)!!
            val transaksi = Transaksi(dataPengeluaran.id,
                namaTransaksi.toString(),
                jenisTransaksi,
                jumlahTransaki.toString().toInt(),
                tanggalTransaksi
            )
            viewModel.updateDataTransaksi(transaksi)
        }
    }

    @SuppressLint("SimpleDateFormat")
    private fun getDataFromIntent(data : Transaksi?){
        if(data != null){
            binding.editTextKeterangan.setText(data.namaTransaksi)
            binding.editTextJumlah.setText(data.total.toString())
            binding.textViewTanggal.text = SimpleDateFormat("dd-MM-yyyy").format(data.tglTransaksi!!)
        }

    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            android.R.id.home -> finish()
        }
        return true
    }

    @SuppressLint("SetTextI18n")
    private fun showDatePickerDialog() {
        val calendar = Calendar.getInstance()
        val tahun = calendar.get(Calendar.YEAR)
        val bulan = calendar.get(Calendar.MONTH)
        val hari = calendar.get(Calendar.DAY_OF_MONTH)
        val datePicker = DatePickerDialog(
            this,
            DatePickerDialog.OnDateSetListener { view, _year, monthOfYear, dayOfMonth ->
                binding.textViewTanggal.text = "$dayOfMonth-${monthOfYear + 1}-$_year "
            },
            tahun,
            bulan,
            hari
        )
        datePicker.show()
    }
类TambahDataActivity:appcompativity(){ 私有lateinit变量绑定:ActivityTambahData