Boolean condition in kotlin was not executing - kotlin

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_create_event)
activity = this#CreateEventActivity
var clicable = true
val set_data : ArrayList<Category_Spinner_model> = ArrayList<Category_Spinner_model>()
if(clicable) dropdown_lay.setOnClickListener{
category_recycler.layoutManager = LinearLayoutManager(this)
set_data.add(Category_Spinner_model(R.drawable.ic_facebook,"Entertainment",R.drawable.ic_dropdown_arrow))
set_data.add(Category_Spinner_model(R.drawable.ic__entertainment,"Entertainment",R.drawable.ic_dropdown_arrow))
set_data.add(Category_Spinner_model(R.drawable.ic__entertainment,"Entertainment",R.drawable.ic_dropdown_arrow))
val adapter = Category_recycler_view(set_data)
category_recycler.adapter = adapter
clicable = false
Log.e("clicable->","$clicable")
}
else if(!clicable) dropdown_lay.setOnClickListener{
set_data.clear()
val adapter = Category_recycler_view(set_data)
category_recycler.adapter = adapter
clicable = true
}
}
I have a recycler view and set data to that recycler view via adapter i need to show the recycler view when clicked and remove the recycler on other click

Your condition is out of place.
if(clicable) dropdown_lay.setOnClickListener{
...
}
Put it inside the onClickListener like this instead.
dropdown_lay.setOnClickListener{
if (clicable) {
category_recycler.layoutManager = LinearLayoutManager(this)
...
...
clicable = false
} else {
set_data.clear()
...
...
clicable = true
}
}

Related

Update firestore data from populated recycler View

I want to update firestore data which I have got in a Recycler view.
Recycler View Activity Code
class AdminActivity : AppCompatActivity() {
private val dB = Firebase.firestore
private lateinit var userRecyclerView: RecyclerView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportActionBar?.title = "Admin Panel"
userRecyclerView = findViewById(R.id.user_list)
userRecyclerView.layoutManager = LinearLayoutManager(this)
userRecyclerView.setHasFixedSize(true)
val query = dB.collection("users")
val options = FirestoreRecyclerOptions.Builder<User>().setQuery(query, User::class.java)
.setLifecycleOwner(this).build()
//adapter
val adapter = object : FirestoreRecyclerAdapter<User, UserViewHolder>(options) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): UserViewHolder {
val view = LayoutInflater.from(this#AdminActivity)
.inflate(R.layout.user_item, parent, false)
return UserViewHolder(view)
}
override fun onBindViewHolder(holder: UserViewHolder, position: Int, model: User) {
val nameTv: TextView = holder.itemView.findViewById(R.id.name_textview)
val idTv: TextView = holder.itemView.findViewById(R.id.id_textview)
val phoneTv: TextView = holder.itemView.findViewById(R.id.phone_textview)
nameTv.text = model.name
idTv.text = model.id
phoneTv.text = model.phone
holder.itemView.setOnClickListener {
val intent = Intent(baseContext, AdminViewActivity::class.java)
startActivity(intent)
}
}
}
userRecyclerView.adapter = adapter
}
}
I want to update the data when i click on the holder.
Only update the data of the user whose recycler view I clicked.
Firestore Database Image

Kotlin retrofit recyclerview intent to new activity

so, i have a little problem here. in my Main Activity (CovidActivity) i want to show only "key" on my Adapter and then in my Second Activity (DetailCovidActivity) i want to show "kasus","sembuh","meninggal",and "dirawat". how to do that?
this is my CovidActivity
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityCovidBinding.inflate(layoutInflater)
setContentView(binding.root)
adapterCovid = CovidAdapter(
listener = object: CovidAdapter.EventListener{
override fun onClick(itemList: CovidProvinceResponse.ListData) {
startActivity(
Intent(this#CovidActivity, DetailCovidActivity::class.java)
.putExtra("key",itemList.key)
.putExtra("kasus",itemList.jumlahKasus)
.putExtra("sembuh",itemList.jumlahSembuh)
.putExtra("meninggal",itemList.jumlahMeninggal)
.putExtra("dirawat",itemList.jumlahDirawat)
)
}
},listCovid = emptyList()
)
binding.rvShowCovid.adapter = adapterCovid
bindViewModel()
viewModel.getCovidProvince()
}
this is the onBindViewHolder in my Adapter
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val itemList = listCovid[position]
holder.binding.tvDaerah.text = itemList.key
holder.binding.tvJumlahKasus.text = itemList.jumlahKasus.toString()
holder.binding.tvJumlahSembuh.text = itemList.jumlahSembuh.toString()
holder.binding.tvJumlahMeninggal.text = itemList.jumlahMeninggal.toString()
holder.binding.tvJumlahDirawat.text = itemList.jumlahDirawat.toString()
holder.itemView.setOnClickListener {
listener.onClick(itemList)
}
}
and then this is the Second Activity (DetailCovidActivity)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityDetailCovidBinding.inflate(layoutInflater)
setContentView(binding.root)
val province = intent.getStringExtra("key")
val kasus = intent.getIntExtra("kasus",0)
val sembuh = intent.getIntExtra("sembuh",0)
val meninggal = intent.getIntExtra("meninggal",0)
val dirawat = intent.getIntExtra("dirawat",0)
binding.tvDetailDaerah.text = province
binding.tvDetailKasus.text = kasus.toString()
binding.tvDetailSembuh.text = sembuh.toString()
binding.tvDetailMeninggal.text = meninggal.toString()
binding.tvDetailDirawat.text = dirawat.toString()
}

Android Bottom Sheet is not working in Fragment

I have added the bottom sheet dialog on a fragment.
Right now I can't open it.
Whenever I click on the show button it doesn't work at all.
How can I fix this problem?
CreateFragment.kt
class CreateFragment : Fragment() {
lateinit var binding: FragmentCreateBinding;
val viewModel: NotesViewModel by viewModels()
private var color = -1
private val currentDate = SimpleDateFormat.getInstance().format(Date())
private lateinit var result: String
private val job = CoroutineScope(Dispatchers.Main)
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
binding = FragmentCreateBinding.inflate(layoutInflater, container, false)
val animation = MaterialContainerTransform().apply {
drawingViewId = R.id.createFragment
scrimColor = Color.TRANSPARENT
duration = 300L
}
binding.backbutton.setOnClickListener {
requireView().hideKeyboard()
Navigation.findNavController(it).popBackStack()
}
sharedElementEnterTransition = animation
sharedElementReturnTransition = animation
binding.fabcolorpick.setOnClickListener {
val bottomSheetDialog = BottomSheetDialog(
requireContext(),
R.style.BottomSheetDialogTheme
)
val bottomSheetView: View = layoutInflater.inflate(
R.layout.bottomsheetlayout,
null,
)
val bottomSheetBinding = BottomsheetlayoutBinding.bind(bottomSheetView)
bottomSheetBinding.apply {
colorpicker.apply {
setSelectedColor(color)
setOnColorSelectedListener { value ->
color = value
binding.apply {
createFragmentxmlid.setBackgroundColor(color)
toolbarfragmentnotecontent.setBackgroundColor(color)
bottombar.setBackgroundColor(color)
activity?.window?.statusBarColor = color
}
bottomSheetBinding.bottomSheetparent.setCardBackgroundColor(color)
}
}
bottomSheetparent.setCardBackgroundColor(color)
}
bottomSheetView.post {
bottomSheetDialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
}
binding.btndonenotes.setOnClickListener {
createNotes(it)
}
try {
binding.edittextnote.setOnFocusChangeListener { _, hasFocus ->
if (hasFocus) {
binding.bottombar.visibility = View.VISIBLE
binding.edittextnote.setStylesBar(binding.styleBar)
} else {
binding.bottombar.visibility = View.GONE
}
}
} catch (e: Throwable) {
Log.d("TAG", e.stackTraceToString())
}
return binding.root
}
this is how I would do it
create the view
set view as content of dialog
call the dialog's show() method to show it or dismiss() method to dismiss it
// the content view
val bottomSheetView: View = layoutInflater.inflate(
R.layout.bottomsheetlayout,
null,
)
// and the dialog
val bottomSheetDialog = BottomSheetDialog( requireContext(),R.style.BottomSheetDialogTheme).apply{
setContent(bottomSheetView)
// or if I am using viewBinding
setContent(bottomSheetBinding.root)
}
// then in button's onClick
button.setOnClickListener{
bottomSheetDialog.show()
}

How to show user dialog box after recyclerview item click

I have an image button in my recylerview and when users click it, I want a dialog box to pop up and allow the user to edit the data in the reyclerview and save the changes.
My Adapter code
class Adapter(private var records: ArrayList<AudioRecord>, var listener: OnItemClickListener) : RecyclerView.Adapter<Adapter.ViewHolder>() {
private var editMode = false
fun isEditMode() :Boolean{return editMode}
#SuppressLint("NotifyDataSetChanged")
fun setEditMode(mode: Boolean){
if(editMode != mode){
editMode = mode
notifyDataSetChanged()
}
}
inner class ViewHolder(val binding: ItemviewLayoutBinding): RecyclerView.ViewHolder(binding.root ), View.OnClickListener, View.OnLongClickListener{
private var tvFileName : TextView = itemView.findViewById(R.id.tvFilename)
private var tvMeta : TextView = itemView.findViewById(R.id.tvMeta)
var checkbox : CheckBox = itemView.findViewById(R.id.checkBox)
val editBtn: ImageButton = itemView.findViewById(R.id.btnEdit)
init {
itemView.setOnClickListener(this)
itemView.setOnLongClickListener(this)
}
fun binding (audioRecord: AudioRecord) {
tvFileName.text = audioRecord.filename
tvMeta.text = audioRecord.duration
// checkbox.text = audioRecord.
}
override fun onClick(p0: View?) {
val position = adapterPosition
if(position != RecyclerView.NO_POSITION)
listener.onItemClickListener(position)
}
override fun onLongClick(p0: View?): Boolean {
val position = adapterPosition
if(position != RecyclerView.NO_POSITION)
listener.onItemLongClickListener(position)
return true
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(ItemviewLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false))
}
#SuppressLint("SetTextI18n", "SimpleDateFormat")
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
if (position != RecyclerView.NO_POSITION){
val record: AudioRecord = records[position]
val sdf = SimpleDateFormat("dd/MM/yyyy")
val date = Date(record.timestamp)
val strDate = sdf.format(date)
holder.binding.tvFilename.text = record.filename
holder.binding.tvMeta.text = "${record.duration} $strDate"
if(editMode){
holder.checkbox.visibility = View.VISIBLE
holder.checkbox.isChecked = record.isChecked
holder.editBtn.visibility = View.GONE
}else{
holder.checkbox.visibility = View.GONE
holder.checkbox.isChecked = false
holder.editBtn.visibility = View.VISIBLE
}
holder.binding.btnEdit.setOnClickListener {
}
}
}
override fun getItemCount(): Int {
return records.size
}
}
Summary
When users click image button. Input dialog pops up
User must be able to edit data in recyclerview and save it.
change class like this inner class ViewHolder(val binding: ItemviewLayoutBinding), var imageListener:(position:Int)->Unit)
where you call adapter , use imageListener function. Whatever you want to do you can do it inside this function. Then call it in your adapter.
in init
editBtn.setOnClickListener {
imageListener(adapterPosition)
}

How to change recyclerview item and sub items when clicked and also get the data in the position clicked from a fragment?

I have 2 Recyclerviews in a fragment. Each item consists of 2 textview. When clicked, i want to change the color of item background and the 2 tvs and get the listofData(position) clicked also then send these s pieces of data to an activity.
The problem is 2 rvs each have its own adapter so i can't call the activity and check if data is selected from both adapters. And when i try it from the fragment i get the adapter position right but the view colors are not being changed correctly.
My RV element
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="2dp"
android:paddingBottom="10dp"
android:paddingStart="20dp"
android:paddingEnd="20dp"
android:background="#drawable/date_time_background"
android:elevation="0dp"
android:gravity="center"
android:layout_marginEnd="5dp"
android:orientation="vertical"
android:id="#+id/item_linear_layout">
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/dateNameTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="Sat"
android:textColor="#color/black_65"
android:textSize="16sp" />
<androidx.appcompat.widget.AppCompatTextView
android:id="#+id/dateNumTV"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="23/5"
android:textColor="#color/black_65"
android:textSize="16sp" />
</LinearLayout>
My RV adapter
class TimesAdapter(private var availableTimes: List<String>?, private val onTimeListener: OnTimeListener) :
RecyclerView.Adapter<TimesAdapter.TimeViewHolder>() {
private var itemIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeViewHolder {
val v = LayoutInflater.from(parent.context)
.inflate(R.layout.date_time_element, parent, false)
return TimeViewHolder(v, onTimeListener)
}
override fun getItemCount(): Int = availableTimes?.size!!
#SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: TimeViewHolder, position: Int) {
val currentDate: String? = availableTimes?.get(position) // i.e Sun 23/5
val parts = currentDate?.split(" ")
try {
val part1 = parts?.get(0)
holder.dateNameTV.text = part1
val part2 = parts?.get(1)
holder.dateNumTV.text = part2
} catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
holder.itemLinearLayout.setOnClickListener {
itemIndex = position
notifyItemChanged(position)
}
val ctx = holder.itemLinearLayout.context
if (itemIndex == position) {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background_selected))
holder.dateNameTV.setTextColor(loadColor(ctx, android.R.color.white))
holder.dateNumTV.setTextColor(loadColor(ctx, android.R.color.white))
} else {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background))
holder.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
holder.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
}
}
class TimeViewHolder(itemView: View, onTimeListener: OnTimeListener) :
RecyclerView.ViewHolder(itemView), View.OnClickListener{
var dateNameTV: TextView = itemView.findViewById(R.id.dateNameTV)
var dateNumTV: TextView = itemView.findViewById(R.id.dateNumTV)
var itemLinearLayout: LinearLayout = itemView.findViewById(R.id.item_linear_layout)
private var onTimeListener: OnTimeListener? = null
init {
itemView.setOnClickListener(this)
this.onTimeListener = onTimeListener
}
override fun onClick(v: View?) {
onTimeListener?.onTimeClick(adapterPosition, itemView)
}
}
interface OnTimeListener{
fun onTimeClick(position: Int, itemView: View)
}
}
My fragment
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"
/**
* A simple [Fragment] subclass.
* Use the [DoctorAppointmentsFragment.newInstance] factory method to
* create an instance of this fragment.
*/
class DoctorAppointmentsFragment : Fragment(),
DatesAdapter.OnDateListener, TimesAdapter.OnTimeListener {
private lateinit var datesRV: RecyclerView
private lateinit var timesRV: RecyclerView
private lateinit var linearLayoutManager: LinearLayoutManager
private lateinit var datesAdapter: DatesAdapter
private lateinit var timesAdapter: TimesAdapter
private lateinit var dateNameTV: TextView
private lateinit var dateNumTV: TextView
private lateinit var dateLinearLayout: LinearLayout
private var dates: List<String>? = null
private var times: List<String>? = null
private var isDateSelected = false
private var isTimeSelected = false
private var selectedDate: String? = null
private var selectedTime: String? = null
// TODO: Rename and change types of parameters
private var param1: String? = null
private var param2: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
arguments?.let {
param1 = it.getString(ARG_PARAM1)
param2 = it.getString(ARG_PARAM2)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?): View? {
// Inflate the layout for this fragment
val view = inflater.inflate(R.layout.fragment_doctor_appointments, container, false)
datesRV = view.findViewById(R.id.datesRV)
datesRV.setHasFixedSize(true)
linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
linearLayoutManager.isAutoMeasureEnabled = false
datesRV.layoutManager = linearLayoutManager
timesRV = view.findViewById(R.id.timesRV)
timesRV.setHasFixedSize(true)
linearLayoutManager = LinearLayoutManager(activity, LinearLayoutManager.HORIZONTAL, false)
linearLayoutManager.isAutoMeasureEnabled = false
timesRV.layoutManager = linearLayoutManager
val bookNowBT = view.findViewById<Button>(R.id.bookNowBT)
bookNowBT.setOnClickListener {
if (isDateSelected && isTimeSelected) {
val i = Intent(activity, ConfirmPaymentActivity::class.java)
i.putExtra(SELECTED_DATE, selectedDate)
i.putExtra(SELECTED_TIME, selectedTime)
startActivity(i)
}
}
getDoctorAvailableAppointments("7ab63fd2461bfb0008b72f5d8c0033fs", "basic")
return view
}
companion object {
/**
* Use this factory method to create a new instance of
* this fragment using the provided parameters.
*
* #param param1 Parameter 1.
* #param param2 Parameter 2.
* #return A new instance of fragment DoctorAppointmentsFragment.
*/
// TODO: Rename and change types and number of parameters
#JvmStatic
fun newInstance(param1: String, param2: String) =
DoctorAppointmentsFragment().apply {
arguments = Bundle().apply {
putString(ARG_PARAM1, param1)
putString(ARG_PARAM2, param2)
}
}
}
private fun getDoctorAvailableAppointments(doctorID: String, type: String) {
setProgressDialog(this.requireActivity())
if (!InternetConnection.isInternetAvailable(this.requireActivity())) {
alertError(this.requireActivity(),
R.string.no_internet_connection,
R.string.check_internet_connection)
} else {
showProgressDialog()
val builder = ServiceBuilder()
val appointments = builder.getDoctorAvailableReservations()
val call = appointments.getDoctorAvailableReservations(
RequestAvailableReservations(doctorID,type))
call?.enqueue(object : Callback<ResponseAvailableReservations?> {
override fun onResponse(call: Call<ResponseAvailableReservations?>, response: Response<ResponseAvailableReservations?>) {
dismissProgressDialog()
if (!response.isSuccessful) {
alertError(requireActivity(),
R.string.code_not_200,
R.string.try_later)
return
}
val body: ResponseAvailableReservations? = response.body()
if (body == null) {
alertError(requireActivity(),
R.string.null_body,
R.string.try_later)
return
}
val status = body.status
val message = body.message
val data = body.data
if (status == null || message == null || data == null) {
alertError(requireActivity(),
R.string.null_body,
R.string.try_later)
return
}
if (status == "error") {
alertError(requireActivity(), R.string.error, message)
} else if (status == "success") {
dates = data.availableDatesList
datesAdapter = DatesAdapter(dates, this#DoctorAppointmentsFragment)
datesRV.adapter = datesAdapter
times = data.availableTimesList
timesAdapter = TimesAdapter(times, this#DoctorAppointmentsFragment)
timesRV.adapter = timesAdapter
}
}
override fun onFailure(call: Call<ResponseAvailableReservations?>, t: Throwable) {
t.printStackTrace()
dismissProgressDialog()
alertError(requireActivity(),
R.string.fail,
R.string.login_fail)
}
})
}
}
private var dateIndex = -1
override fun onDateClick(position: Int) {
selectedDate = dates?.get(position)
isDateSelected = true
Log.e("selectedDate", "selectedDate")
dateIndex = position
datesAdapter.notifyDataSetChanged()
}
private var timeIndex = -1
override fun onTimeClick(position: Int, itemView: View) {
// selectedTime = times?.get(position)
// isTimeSelected = true
// Log.e("isSelectedTime", "true")
// timeIndex = position
// timesAdapter.notifyItemChanged(position)
// Log.e("timeIndex", timeIndex.toString())
//
// val ctx = itemView.context
// if (timeIndex == position) {
// Log.e("timeIndex", "timeIndex == position")
//
// itemView.background = loadDrawable(ctx, R.drawable.date_time_background_selected)
// itemView.dateNameTV?.setTextColor(loadColor(ctx, android.R.color.white))
// itemView.dateNumTV?.setTextColor(loadColor(ctx, android.R.color.white))
// } else {
// itemView.background = (loadDrawable(ctx, R.drawable.date_time_background))
// itemView.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
// itemView.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
// }
}
}
Solved
For anyone interested i ended up using a very simple idea. Instead of accessing the RecyclerView selected element from outside the adapter, i did all i wanted to do inside the adapter and used 4 static variables in the Fragment. 2 booleans to check
if date and time are selected or not and 2 Strings having the date and time actually selected.
Inside the Fragment:
companion object {
#JvmStatic var isTimeSelected = false
#JvmStatic var selectedTime = ""
#JvmStatic var isDateSelected = false
#JvmStatic var selectedDate = ""
....
}
Inside the Adapter's onBindViewHolder()
holder.itemLinearLayout.setOnClickListener {
selectedDate = dates?.get(position)!!
isDateSelected = true
listener?.onDateClick(position)
selectedIndex = position
notifyDataSetChanged()
}
val ctx = holder.itemLinearLayout.context
if (selectedIndex == position) {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background_selected))
holder.dateNameTV.setTextColor(loadColor(ctx, android.R.color.white))
holder.dateNumTV.setTextColor(loadColor(ctx, android.R.color.white))
} else {
holder.itemLinearLayout.background = (loadDrawable(ctx, R.drawable.date_time_background))
holder.dateNameTV.setTextColor(loadColor(ctx, R.color.black_65))
holder.dateNumTV.setTextColor(loadColor(ctx, R.color.black_65))
}
And i made sure static variables don't have old values using this
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
isTimeSelected = false
selectedTime = ""
isDateSelected = false
selectedDate = ""
}
I know it's bad practice to put onClickListener inside onBindViewHolder but i don't konw if the static variables thing is good or bad practice. Either way it's working fine for now.
There is many ways to do this, And I recommend the first one.
Using shared ViewModels for communication between fragments in the same activity. The idea is that you will tie up the ViewModel with activity and every fragment can access this ViewModel and in this ViewModel you will have a LiveData object that holds the data and observing it from both fragments and every change in the value of LiveData will affect each fragment. Shared ViewModel
Using interfaces for communication between fragments and it's a hard thing to do these days. Basic communication between fragments
Using EventBus it's easy but not recommended while you can use ViewModel at the first solution. EventBus
Try this
TimesAdapter
class TimesAdapter(
availableTimes: List<String>
) : RecyclerView.Adapter<TimesAdapter.TimeViewHolder>() {
var availableTimes:List<String> = availableTimes
set(value) {
field = value
notifyDataSetChanged()
}
var listener:TimeSelectedListener?=null
var selectedIndex:Int = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TimeViewHolder {
return TimeViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.date_time_element, parent, false)
)
}
override fun getItemCount(): Int = availableTimes.count()
override fun onBindViewHolder(holder: TimeViewHolder, position: Int) {
val currentDate: String? = availableTimes[position] // i.e Sun 23/5
val parts = currentDate?.split(" ")
try {
val part1 = parts?.get(0)
val part2 = parts?.get(1)
holder.dateNameTV.text = part2
holder.dateNumTV.text = part1
} catch (e: IndexOutOfBoundsException) {
e.printStackTrace()
}
holder.itemLinearLayout.setOnClickListener {
listener?.onTimeClick(position)
selectedIndex = position
}
if (selectedIndex == position) {
// Selection Code
} else {
// De selection code
}
}
class TimeViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
var dateNameTV: TextView = itemView.findViewById(R.id.dateNameTV)
var dateNumTV: TextView = itemView.findViewById(R.id.dateNumTV)
var itemLinearLayout: LinearLayout = itemView.findViewById(R.id.item_linear_layout)
}
interface TimeSelectedListener {
fun onTimeClick(position: Int)
}
}
Usage from fragment
times = data.availableTimesList
timesAdapter = TimesAdapter(times).apply {
listener = object :TimesAdapter.TimeSelectedListener{
override fun onTimeClick(position: Int) {
// TODO here is where you should implement when an item is selected
}
}
}
timesRV.adapter = timesAdapter