Kotlin:How to make a popup date pick when click the EditText - kotlin

I would love to make a popup datepicker ,while click the EditText ,And the date can be set to different languages according to the device 's language .I will need it use Kotlin.
More or less like as below :
Could anyone show me an example please ?
Thank you so much in advance !
I have tried this link ,but apppears two problems:
The pop up dialog design is not what I expected .
2.The selected result can't fill into the EditText
https://developer.android.com/guide/topics/ui/controls/pickers
DatePickerActivity.kt
class DatePickerActivity : AppCompatActivity() {
val myCalendar: Calendar = Calendar.getInstance()
lateinit var edt : EditText
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_date_picker)
val day :Int = myCalendar.get(Calendar.DAY_OF_MONTH)
val month:Int = myCalendar.get(Calendar.MONTH)
val year :Int = myCalendar.get(Calendar.YEAR)
edt = findViewById(R.id.edt_birthday)
edt.setOnClickListener {
showDatePickerDialog(it)
edt.setText("" + day+ " " + month+1 + ", " + year)
}
}
fun showDatePickerDialog(v: View){
val newFragment = DatePickerFragment()
newFragment.show(supportFragmentManager,"datePicker")
}
}
DatePickerFragment.kt
import android.app.DatePickerDialog
import android.app.Dialog
import android.os.Bundle
import android.widget.DatePicker
import androidx.fragment.app.DialogFragment
import java.util.*
class DatePickerFragment : DialogFragment(), DatePickerDialog.OnDateSetListener {
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
// Use the current date as the default date in the picker
val c = Calendar.getInstance()
val year = c.get(Calendar.YEAR)
val month = c.get(Calendar.MONTH)
val day = c.get(Calendar.DAY_OF_MONTH)
// Create a new instance of DatePickerDialog and return it
return DatePickerDialog(requireActivity(), this, year, month, day)
}
override fun onDateSet(view: DatePicker, year: Int, month: Int, day: Int) {
}
}
And it turns out like this :

The default DatePicker looks like a calendar. You can change the behavior back to the old spinner style by adding this extra style in themes.xml.
<style name="MyDatePickerStyle" parent="android:Widget.Material.DatePicker">
<item name="android:datePickerMode">spinner</item>
</style>
and then inside your style for the app's theme, add this line:
<item name="android:datePickerStyle">#style/MyDatePickerStyle</item>
Note that the calendar style is the default because it has been found to be preferred by most users.

Related

Can you change the color of a textview in a recyclerview adapter after a certain condition is met in Main Activity?

I have a basic function that displays the elapsed time every time the button is pressed. I cannot get the logic in MainActivity to transfer to the recyclerview adapter. I simply want the text output color to change to red after the time passes 5 seconds. I have tried to research how to do this for the past week and I cannot find the exact answer. I'm hoping someone can help.
I have tried it with and without the boolean in the data class. I wasn't sure if that was required.
Here is my code:
Main Activity:`
class MainActivity : AppCompatActivity() {
var startTime = SystemClock.elapsedRealtime()
var displaySeconds = 0
private lateinit var binding: ActivityMainBinding
private val secondsList = generateSecondsList()
private val secondsAdapter = Adapter(secondsList)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
recyclerView.adapter = secondsAdapter
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.setHasFixedSize(false)
binding.button.setOnClickListener {
getDuration()
addSecondsToRecyclerView()
}
}
fun getDuration(): Int {
val endTime = SystemClock.elapsedRealtime()
val elapsedMilliSeconds: Long = endTime - startTime
val elapsedSeconds = elapsedMilliSeconds / 1000.0
displaySeconds = elapsedSeconds.toInt()
return displaySeconds
}
private fun generateSecondsList(): ArrayList<Seconds> {
return ArrayList()
}
fun addSecondsToRecyclerView() {
val addSeconds =
Seconds(getDuration(), true)
secondsList.add(addSeconds)
secondsAdapter.notifyItemInserted(secondsList.size - 1)
}
}
Adapter:
var adapterSeconds = MainActivity().getDuration()
class Adapter(
private val rvDisplay: MutableList<Seconds>
) : RecyclerView.Adapter<Adapter.AdapterViewHolder>() {
class AdapterViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val textView1: TextView = itemView.tv_seconds
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AdapterViewHolder {
val myItemView = LayoutInflater.from(parent.context).inflate(
R.layout.rv_item,
parent, false
)
return AdapterViewHolder(myItemView)
}
override fun onBindViewHolder(holder: Adapter.AdapterViewHolder, position: Int) {
val currentDisplay = rvDisplay[position]
currentDisplay.isRed = adapterSeconds > 5
holder.itemView.apply {
val redColor = ContextCompat.getColor(context, R.color.red).toString()
val blackColor = ContextCompat.getColor(context, R.color.black).toString()
if (currentDisplay.isRed) {
holder.textView1.setTextColor(redColor.toInt())
holder.textView1.text = currentDisplay.rvSeconds.toString()
} else {
holder.textView1.setTextColor(blackColor.toInt())
holder.textView1.text = currentDisplay.rvSeconds.toString()
}
}
}
override fun getItemCount() = rvDisplay.size
}
Data Class:
data class Seconds(
var rvSeconds: Int,
var isRed: Boolean
)
when you call secondsList.add(addSeconds) then the data that is already inside secondsList should be updated too.
you could do something like
private var secondsList = generateSecondsList() // make this var
fun addSecondsToRecyclerView() {
val addSeconds =
Seconds(getDuration(), true)
secondsList.add(addSeconds)
if ( /* TODO check if time has passed */) {
secondsList = secondsList.map { it.isRed = true }
secondsAdapter.rvDisplay = secondsList // TODO also make rvDisplay a var
secondsAdapter.notifyDatasetChanged() // also need to tell rv to redraw the all views
} else {
secondsAdapter.notifyItemInserted(secondsList.size - 1)
}
}
that might work, but to be honest it looks bad... There is already a lot of logic inside Activity. Read about MVVM architecture and LiveData, there should be another class called ViewModel that would keep track of time and the data. Activity should be as simple as possible, because it has lifecycle, so if you rotate the screen, all your state will be lost.
Your code isn't really working because of this:
var adapterSeconds = MainActivity().getDuration()
override fun onBindViewHolder(holder: Adapter.AdapterViewHolder, position: Int) {
...
currentDisplay.isRed = adapterSeconds > 5
...
}
You're only setting adapterSeconds right there, so it never updates as time passes. I assume you want to know the moment 5 seconds has elapsed, and then update the RecyclerView at that moment - in that case you'll need some kind of timer task that will fire after 5 seconds, and can tell the adapter to display things as red. Let's deal with that first:
class Adapter( private val rvDisplay: MutableList ) : RecyclerView.Adapter<Adapter.AdapterViewHolder>() {
private var displayRed = false
set(value) {
field = value
// Refresh the display - the ItemChanged methods mean something about the items
// has changed, rather than a structural change in the list
// But you can use notifyDataSetChanged if you want (better to be specific though)
notifyItemRangeChanged(0, itemCount)
}
override fun onBindViewHolder(holder: Adapter.AdapterViewHolder, position: Int) {
if (displayRed) {
// show things as red - you shouldn't need to store that state in the items
// themselves, it's not about them - it's an overall display state, right?
} else {
// display as not red
}
}
So with that setter function, every time you update displayRed it'll refresh the display, which calls onBindViewHolder, which checks displayRed to see how to style things. It's better to put all this internal refreshing stuff inside the adapter - just pass it data and events, let it worry about what needs to happen internally and to the RecyclerView it's managing, y'know?
Now we have a thing we can set to control how the list looks, you just need a timer to change it. Lots of ways to do this - a CountdownTimer, a coroutine, but let's keep things simple for this example and just post a task to the thread's Looper. We can do that through any View instead of creating a Handler:
// in MainActivity
recyclerView.postDelayed({ secondsAdapter.displayRed = true }, 5000)
That's it! Using any view, post a delayed function that tells the adapter to display as red.
It might be more helpful to store that runnable as an object:
private val showRedTask = Runnable { secondsAdapter.displayRed = true }
...
recyclerView.postDelayed(showRedTask, 5000)
because then you can easily cancel it
recyclerView.removeCallbacks(showRedTask)
Hopefully that's enough for you to put some logic together to get what you want. Set displayRed = false to reset the styling, use removeCallbacks to cancel any running task, and postDelayed to start a new countdown. Not the only way to do it, but it's pretty neat!
I finally figured it out using a companion object in Main Activity with a boolean set to false. If the time exceeded 5 seconds, then it set to true.
The adapter was able to recognize the companion object and change the color of seconds to red if they exceeded 5.

Can't select date with datepickerdialog

I have some trouble using the DataPickerDialog in kotlin...
This is how I would like it to work:
First, when the user selects a date, it must update a textview and the dialog must close
But for now, when the user selects a date, nothing happens (apart from the update in the dialog itself).
Here is my code :
#AndroidEntryPoint
class AppointmentListFragment : Fragment() {
private var _binding: FragmentAppointmentListBinding? = null
private val binding: FragmentAppointmentListBinding
get() = _binding!!
private val viewModel: AppointmentMainViewModel by viewModels()
private val today = Calendar.getInstance()
private val day = today.get(Calendar.DAY_OF_MONTH)
private val month = today.get(Calendar.MONTH) + 1
private val year = today.get(Calendar.YEAR)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
_binding = FragmentAppointmentListBinding.inflate(inflater)
setDateText(
getString(
R.string.date_placeholder,
String.format("%02d", day),
String.format("%02d", month),
year
)
)
binding.appointmentDateButton.setOnClickListener {
val dpd = DatePickerDialog(
it.context,
{ datePicker, y, m, d ->
datePicker.minDate = System.currentTimeMillis()
setDateText(
getString(
R.string.date_placeholder,
String.format("%02d", d),
String.format("%02d", m),
y
)
)
},
year,
month,
day
)
dpd.show()
}
return binding.root
}
private fun setDateText(date: String) {
binding.appointmentDateButton.text = date
}
What am I missing ?
Thanks in advance
What do you get in setDateText? I copied almost all code and launched. Then got y, m, d inside onDateSet callback. So, a string
getString(
R.string.date_placeholder,
String.format("%02d", d),
String.format("%02d", m),
y
)
should be right (but I don't know what you have put in date_placeholder).
So, this string is passed to setDateText and is written in appointmentDateButton (19 05 2022). I don't know, what happened.
By the way, initial month is incremented by 1. It's a mistake (you open the picker on 19th' June).

function call in onActivityCreated() triggers Observer every time the app restarts

in my fragment I am observing a live data in a function and in that observer, some sharedPreferences are changed. The function is then called inside onActivityCreated() .The problem is whenever I restart my app the onActivityCreated() gets called which in turn calls that function which in turn observes the live data and thus changes the value of sharedPreference which I don't want.
code to my fragment is attached.
package com.example.expensemanager.ui
import android.app.AlertDialog
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Color
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.expensemanager.R
import com.github.mikephil.charting.data.PieData
import com.github.mikephil.charting.data.PieDataSet
import com.github.mikephil.charting.data.PieEntry
import kotlinx.android.synthetic.main.fragment_transaction_list.*
import kotlinx.android.synthetic.main.set_balance_details.view.*
import org.eazegraph.lib.models.PieModel
class TransactionListFragment : Fragment() {
//declaring the view model
private lateinit var viewModel: TransactionListViewModel
var cashAmount:Float = 0F
var bankAmount:Float = 0F
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
//setHasOptionsMenu(true)
//(activity as AppCompatActivity?)!!.setSupportActionBar(addAppBar)
viewModel = ViewModelProvider(this)
.get(TransactionListViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_transaction_list, container, false)
}
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
//recycler view for showing all the transactions
with(transaction_list){
layoutManager = LinearLayoutManager(activity)
adapter = TransactionAdapter {
findNavController().navigate(
TransactionListFragmentDirections.actionTransactionListFragmentToTransactionDetailFragment(
it
)
)
}
}
//code for the floating action button in the main screen
add_transaction.setOnClickListener{
findNavController().navigate(
//here id is passed 0 because the transaction is being added the first time
TransactionListFragmentDirections.actionTransactionListFragmentToTransactionDetailFragment(
0
)
)
}
addAppBar.setOnMenuItemClickListener { menuItem ->
when(menuItem.itemId){
R.id.calendar_button -> {
findNavController().navigate(TransactionListFragmentDirections.actionTransactionListFragmentToCalanderViewFragment())
true
}
R.id.monthly_cards -> {
findNavController().navigate(TransactionListFragmentDirections.actionTransactionListFragmentToMonthlyCardsFragment())
true
}
else -> false
}
}
see_all_transactions.setOnClickListener {
findNavController().navigate(TransactionListFragmentDirections.actionTransactionListFragmentToAllTransactionsFragment())
}
//submitting the new list of upcoming Transactions after getting it from the db
viewModel.upcomingTransactions.observe(viewLifecycleOwner, Observer {
(transaction_list.adapter as TransactionAdapter).submitList(it)
})
val sharedPreferences: SharedPreferences = this.requireActivity().getSharedPreferences("OnboardingDetails", Context.MODE_PRIVATE)
val monthlyBudget = sharedPreferences.getFloat("monthlyBudget",0F)
var totalBalance = monthlyBudget*12
net_balance.text = totalBalance.toString()
Log.d("netbalance",totalBalance.toString())
//the net balance (yearly) is calculated wrt the transactions already done
viewModel.sumOfTransactions.observe(viewLifecycleOwner, Observer {
if (it != null) {
totalBalance += it
net_balance.text = totalBalance.toString()
}
})
val budgetPreferences: SharedPreferences =
this.requireActivity().getSharedPreferences("Balance_details", Context.MODE_PRIVATE)
val editor: SharedPreferences.Editor = budgetPreferences.edit()
//setting pie chart initially to 0
setPieChart(budgetPreferences,editor)
//observing the cash details and the bank details to update the text view and the pie chart
observeBalance(budgetPreferences,editor)
//GraphCardView code
//button for setting the balance details
set_balance_details.setOnClickListener {
setBalanceDetails(budgetPreferences,editor)
}
}
//dialog box for setting the balance details
private fun setBalanceDetails(budgetPreferences: SharedPreferences,editor: SharedPreferences.Editor) {
val dialog = LayoutInflater.from(requireContext()).inflate(
R.layout.set_balance_details,
null
)
//AlertDialogBuilder
val mBuilder = AlertDialog.Builder(requireContext())
.setView(dialog)
//show dialog
val mAlertDialog = mBuilder.show()
dialog.save_details.setOnClickListener {
cashAmount = dialog.cash_amount.editText?.text.toString().toFloat()
bankAmount = dialog.bank_amount.editText?.text.toString().toFloat()
//saving the cashAmount and bankAmount to shared preferences for future use
editor.putFloat("cashAmount", cashAmount).apply()
editor.putFloat("bankAmount", bankAmount).apply()
//setting the pie chart with new values
setPieChart(budgetPreferences, editor)
mAlertDialog.dismiss()
}
dialog.cancel_details.setOnClickListener { mAlertDialog.dismiss() }
mAlertDialog.show()
}
private fun observeBalance(budgetPreferences: SharedPreferences,editor: SharedPreferences.Editor) {
//getting the cashAmount and bankAmount and updating the views with live data
var cashAmount = budgetPreferences.getFloat("cashAmount", 0F)
var bankAmount = budgetPreferences.getFloat("bankAmount", 0F)
viewModel.cashAmount.observe(viewLifecycleOwner, Observer {
if (it != null) {
cashAmount += it
cash.text = "CASH : ${cashAmount}"
Log.d("observeCash",cashAmount.toString())
editor.putFloat("cashAmount",cashAmount).apply()//find solution to this
setPieChart(budgetPreferences,editor)
}
})
viewModel.bankAmount.observe(viewLifecycleOwner, Observer {
if (it != null) {
bankAmount+=it
bank.text = "BANK : ${bankAmount}"
Log.d("observeBank",bankAmount.toString())
editor.putFloat("cashAmount",cashAmount).apply()
setPieChart(budgetPreferences,editor)
}
})
setPieChart(budgetPreferences,editor)
}
//https://www.geeksforgeeks.org/how-to-add-a-pie-chart-into-an-android-application/ use this for reference
private fun setPieChart(budgetPreferences: SharedPreferences,editor: SharedPreferences.Editor) {
val cashAmount = budgetPreferences.getFloat("cashAmount", 0f)
val bankAmount = budgetPreferences.getFloat("bankAmount", 0f)
Log.d("pieCank",cashAmount.toString())
Log.d("pieBank",bankAmount.toString())
cash.text = "CASH : ${cashAmount}"
bank.text = "BANK : ${bankAmount}"
val pieEntries = arrayListOf<PieEntry>()
pieEntries.add(PieEntry(cashAmount))
pieEntries.add(PieEntry(bankAmount))
pieChart.animateXY(1000, 1000)
// setup PieChart Entries Colors
val pieDataSet = PieDataSet(pieEntries, "This is Pie Chart Label")
pieDataSet.setColors(
ContextCompat.getColor(requireActivity(), R.color.blue1),
ContextCompat.getColor(requireActivity(), R.color.blue2)
)
val pieData = PieData(pieDataSet)
// setip text in pieChart centre
//piechart.setHoleColor(R.color.teal_700)
pieChart.setHoleColor(getColorWithAlpha(Color.BLACK, 0.0f))
// hide the piechart entries tags
pieChart.legend.isEnabled = false
// now hide the description of piechart
pieChart.description.isEnabled = false
pieChart.description.text = "Expanses"
pieChart.holeRadius = 40f
// this enabled the values on each pieEntry
pieData.setDrawValues(true)
pieChart.data = pieData
}
fun getColorWithAlpha(color: Int, ratio: Float): Int {
var newColor = 0
val alpha = Math.round(Color.alpha(color) * ratio)
val r = Color.red(color)
val g = Color.green(color)
val b = Color.blue(color)
newColor = Color.argb(alpha, r, g, b)
return newColor
}
}
As seen when app restarts , viewModel.cashAmount gets triggered giving undesired outputs.
What can i do to avoid this .
Activities can get recreated a lot, like when you rotate the screen, or if it's in the background and the system destroys it to free up some memory. Right now, every time that happens your code doesn't know whether it's getting the current value, or a brand new one, but one of those should perform a calculation, and the other should just update the display.
The problem is your calculation logic is tied in with the UI state - it's being told what to display, and also deciding if that counts as a new user action or not. And it has no way of knowing that. Your logic needs to go something like
things observe LiveData values -> update to display new values when they come in
user clicks a button -> do calculation with the value they've entered
calculation result returns -> LiveData gets updated with new value
LiveData value changes -> things update to show the new value
that way a calculation happens specifically in response to a user action, like through a button click. LiveData observers only reflect the current state, so it doesn't matter if they see the same value lots of times, they're just redrawing a pie chart or whatever.
You can use a LiveData to watch for a stream of values, but the thing about UI components is that sometimes they're there to see them, and sometimes they're not. And LiveData is specifically made to push updates to active observers, but not inactive ones - and always provide the most recent value to a new observer, or one that becomes active.
So in that case it works more like "here's the current situation", and that fits better with displaying things, where it doesn't matter if you repeat yourself. That's why you can't do this kind of "handle everything exactly one time" thing in your UI - unless you're literally responding to a UI event like a button click

How to use getHour() to get current hour in kotlin

fun getHours() = int
val openHours = 7
val now = getHours()
val office: String
office = if (now > 7){
"Office already open"
} else if(now == openHours){
"wait a minute, office will be open"
}else{
"office is closed"
}
println(office)
The following code doesn't seem to get me the current hour from my computer, what am I missing?
The right syntax of defining a function in Kotlin would be:
// function without params and returns Unit
fun functionName1() {}
// function with one parameter and returns Int
fun functionName2(text: String): Int {
return 6
}
// short syntax for one line function with two params and Boolean as return value
fun functionName3(text: String, isVisible: Boolean): Boolean = text.isEmpty && isVisible
Code provided by you has incorrect syntax, please fix it. It should be something like this:
fun getHours(): String {
val openHours = 7
val now = getCurrentHour()
val office = when {
now > 7 -> "Office already open"
now == openHours -> "wait a minute, office will be open"
else -> "office is closed"
}
println(office)
return office
}
fun getCurrentHour(): Int {
// somehow get current hour, for example using java.util.Calendar class
return Calendar.getInstance().get(Calendar.HOUR_OF_DAY)
}
You can get the current system time using LocalDateTime class like :
import java.time.LocalDateTime
val currentDateTime = LocalDateTime.now()
And to get hours specifically you could use DateTimeFormatter class like:
import java.time.format.DateTimeFormatter
currentDateTime.format(DateTimeFormatter.ofPattern("HH"))
Basically, the answer given by #Sergey is correct.
Just one minor nit:
I would not use java.util.Date for it but one of the classes from java.time, see this example:
fun getHours(): String {
val openHours = 7
val now = java.time.ZonedDateTime.now(java.time.ZoneId.systemDefault()).hour
val office = when {
now > 7 -> "Office already open"
now == openHours -> "wait a minute, office will be open"
else -> "office is closed"
}
return office
}
using that in a fun main() like
fun main() {
println(getHours())
}
would then result in the (system dependent) output
office is closed
on my system at 08:48 o'clock in UTC+2.

Setters don't modify two-dimensional array

Kotlin. I want a button to display values from a two-dimensional ArrayList, and a second button to modify one of them. But the setters don't modify the two-dimensional ArrayList. We can see the values with the first button, and after modifying the values at index 2 (third) with the second button, the values don't change:
model.get(2).setDateStrs("03/03/20")
model.get(2).setHourStrs("10:27")
What's wrong?
ReModel.kt file:
package com.example.updatearraylist
class ReModel {
var dateStr:String = "12/31/2029"
var hourStr: String = "00:00"
fun getDateStrs(): String {
return dateStr
}
fun setDateStrs(dateStr: String) {
this.dateStr = dateStr
}
fun getHourStrs(): String {
return hourStr
}
fun setHourStrs(hourStr: String) {
this.hourStr = hourStr
}
}
MainActivity.kt file:
package com.example.updatearraylist
import android.R.attr
import android.app.Activity
import android.content.Intent
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.activity_main.*
import java.lang.reflect.Array.get
import java.util.*
import kotlin.collections.ArrayList
class MainActivity : AppCompatActivity() {
private var displayValueBtn: Button? = null
private var changeValueBtn: Button? = null
val model: ArrayList<ReModel>
get() {
val list = ArrayList<ReModel>()
for (i in 0..7) {
val model = ReModel()
model.setDateStrs("01/16/2020")
model.setHourStrs("01:08")
list.add(model)
}
return list
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
displayValueBtn =findViewById<Button>(R.id.displayValueBtn)
changeValueBtn=findViewById<Button>(R.id.changeValueBtn)
displayValueBtn!!.setOnClickListener {
for(i in 0..7){
Toast.makeText(this, "Value position "+i+" "+model.get(i).getDateStrs()+" "+
model.get(i).getHourStrs()
,Toast.LENGTH_SHORT).show()
}
}
changeValueBtn!!.setOnClickListener {
model.get(2).setDateStrs("03/03/20")
model.get(2).setHourStrs("10:27")
Toast.makeText(this,"List Modified",Toast.LENGTH_LONG).show()
}
}
}
The custom getter on model will be executed each time model is accessed so any changes to the array are overwritten. If you want to verify that use a single println in the custom getter and whatever you print will display multiple times.
By "custom getter" I mean the get() on model and the associated block of code.
One solution is to use lazy initialization instead of a custom getter so that model is initialized only once. Here's how that would look:
val model: ArrayList<ReModel> by lazy {
val list = ArrayList<ReModel>()
for (i in 0..7) {
val model = ReModel()
model.setDateStrs("01/16/2020")
model.setHourStrs("01:08")
list.add(model)
}
list
}
Note that the last line with just list on it returns the value of list. return is not allowed there.