In my application I want show diseases to users and users can multi select these data.
But I want when user select the diabetes from the list, just select one item.
Can not be multi select diabetes disease but can multi select for other diseases.
For this I write this codes:
My Adapter codes:
class OptionsAdapter(val context: Context, itemList: List<Data>) : RecyclerView.Adapter<OptionsAdapter.ViewHolder>() {
private var currentList = itemList.toList()
private var lastSelectedDiabetesPosition = -1
private val boldFont: Typeface = Typeface.createFromAsset(context.assets, "fonts/iransans_bold.ttf")
private val normalFont: Typeface = Typeface.createFromAsset(context.assets, "fonts/iransans.ttf")
inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val textView: TextView = view.findViewById(R.id.itemTitle)
val checkBox: CheckBox = view.findViewById(R.id.itemCheck)
init {
checkBox.setOnCheckedChangeListener { _, isChecked ->
val item = currentList[adapterPosition]
if (item.faName!!.contains(context.getString(R.string.diabetes))) {
if (isChecked) {
if (lastSelectedDiabetesPosition != -1 && lastSelectedDiabetesPosition != adapterPosition) {
currentList[lastSelectedDiabetesPosition].isSelected = false
//itemView.post {
notifyItemChanged(lastSelectedDiabetesPosition)
//}
}
lastSelectedDiabetesPosition = adapterPosition
} else if (lastSelectedDiabetesPosition == adapterPosition) {
lastSelectedDiabetesPosition = -1
}
}
item.isSelected = isChecked
textView.typeface = if (isChecked) boldFont else normalFont
}
itemView.setOnClickListener {
checkBox.isChecked = !checkBox.isChecked
}
}
}
fun getSelectedItems(): List<Data> {
return currentList.filter { it.isSelected }
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_with_checkbox_checkable, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val item = currentList[position]
holder.textView.text = item.faName
holder.checkBox.isChecked = item.isSelected
}
override fun getItemCount() = currentList.size
}
Fragment codes:
class LoginPage3YourStatusFragment : Fragment() {
//Binding
private var _binding: FragmentLoginPage3YourStatusBinding? = null
private val binding get() = _binding!!
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
_binding = FragmentLoginPage3YourStatusBinding.inflate(layoutInflater)
return binding.root
}
@SuppressLint("ClickableViewAccessibility", "SetTextI18n")
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//InitViews
binding.apply {
//Back
loginBackImg.setOnClickListener {
findNavController().popBackStack()
}
//Auto show dialog
lifecycleScope.launch {
delay(400)
DiseaseOptionsFragment().show(parentFragmentManager, DiseaseOptionsFragment().tag)
}
//Step
loginStepTxt.text = "4 از $TOTAL_LOGIN_PAGES"
//Slider
loginStepSlider.setOnTouchListener { _, _ -> true }
//Show dialog
loginPage4SelectTxt.setOnClickListener {
DiseaseOptionsFragment().show(parentFragmentManager, DiseaseOptionsFragment().tag)
}
//Text
loginPage4SelectTxt.apply {
isSelected = true
text = REGISTER_DISEASE_OPTIONS_NAMES
}
//Get count
lifecycleScope.launch {
FlowEventBus.subscribe<FlowEvents.DiseaseOptionsCount> {
val names = StringBuilder()
REGISTER_DISEASE_OPTIONS_DATA.forEach { item ->
names.append(item.faName).append(", ")
}
REGISTER_DISEASE_OPTIONS_NAMES = names.dropLast(2).toString()
loginPage4SelectTxt.text = REGISTER_DISEASE_OPTIONS_NAMES
findNavController().navigate(R.id.actionLogin3To6)
}
}
//Next page
loginSubmitBtn.setOnClickListener {
if (REGISTER_DISEASE_OPTION_IDS.isNotEmpty()) {
findNavController().navigate(R.id.actionLogin3To6)
} else {
root.showSnackBar(getString(R.string.notEmpty))
}
}
}
}
}
When navigate between pages and go to this list, some time show me below error :
Error:
java.lang.IllegalStateException: Cannot call this method while RecyclerView is computing a layout or scrolling androidx.recyclerview.widget.RecyclerView{521822a VFED.V... ......ID 0,31-772,31 #7f0a0188 app:id/dialogList}, adapter:com.myapp.login.pages.page3_2.OptionsAdapter@b69681b, layout:androidx.recyclerview.widget.LinearLayoutManager@97bbdb8, context:dagger.hilt.android.internal.managers.ViewComponentManager$FragmentContextWrapper@1ce0791
at androidx.recyclerview.widget.RecyclerView.assertNotInLayoutOrScroll(RecyclerView.java:3185)
at androidx.recyclerview.widget.RecyclerView$RecyclerViewDataObserver.onItemRangeChanged(RecyclerView.java:5712)
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:12674)
at androidx.recyclerview.widget.RecyclerView$AdapterDataObservable.notifyItemRangeChanged(RecyclerView.java:12664)
at androidx.recyclerview.widget.RecyclerView$Adapter.notifyItemChanged(RecyclerView.java:7599)
at com.myapp.login.pages.page3_2.OptionsAdapter$ViewHolder._init_$lambda$0(OptionsAdapter.kt:35)
at com.myapp.login.pages.page3_2.OptionsAdapter$ViewHolder.$r8$lambda$x8ngCtHvaBFI0LD68qfwqYMQupM(Unknown Source:0)
at com.myapp.login.pages.page3_2.OptionsAdapter$ViewHolder$$ExternalSyntheticLambda1.onCheckedChanged(Unknown Source:4)
at android.widget.CompoundButton.setChecked(CompoundButton.java:222)
at com.myapp.login.pages.page3_2.OptionsAdapter.onBindViewHolder(OptionsAdapter.kt:67)
at com.myapp.login.pages.page3_2.OptionsAdapter.onBindViewHolder(OptionsAdapter.kt:14)
at androidx.recyclerview.widget.RecyclerView$Adapter.onBindViewHolder(RecyclerView.java:7254)
at androidx.recyclerview.widget.RecyclerView$Adapter.bindViewHolder(RecyclerView.java:7337)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(RecyclerView.java:6194)
at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6460)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6300)
at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6296)
at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2330)
at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1631)
at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1591)
at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:668)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4309)
at androidx.recyclerview.widget.RecyclerView.onMeasure(RecyclerView.java:3686)
at android.view.View.measure(View.java:28120)
at androidx.constraintlayout.widget.ConstraintLayout$Measurer.measure(ConstraintLayout.java:811)
at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measure(BasicMeasure.java:466)
at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.measureChildren(BasicMeasure.java:134)
at androidx.constraintlayout.core.widgets.analyzer.BasicMeasure.solverMeasure(BasicMeasure.java:278)
at androidx.constraintlayout.core.widgets.ConstraintWidgetContainer.measure(ConstraintWidgetContainer.java:120)
at androidx.constraintlayout.widget.ConstraintLayout.resolveSystem(ConstraintLayout.java:1594)
at androidx.constraintlayout.widget.ConstraintLayout.onMeasure(ConstraintLayout.java:1708)
at android.view.View.measure(View.java:28120)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:735)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:481)
at android.view.View.measure(View.java:28120)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7034)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
2024-07-21 19:27:40.550 24629-24629 AndroidRuntime com.myapp E at android.view.View.measure(View.java:28120) (Ask Gemini)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7034)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at android.view.View.measure(View.java:28120)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:7034)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:194)
at com.android.internal.policy.DecorView.onMeasure(DecorView.java:745)
at android.view.View.measure(View.java:28120)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:4627)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:3108)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3444)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2836)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:10145)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1406)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1415)
at android.view.Choreographer.doCallbacks(Choreographer.java:1015)
at android.view.Choreographer.doFrame(Choreographer.java:945)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1389)
at android.os.Handler.handleCallback(Handler.java:959)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loopOnce(Looper.java:232)
at android.os.Looper.loop(Looper.java:317)
at android.app.ActivityThread.main(ActivityThread.java:8674)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:886)
When added this lines into adapter error is OK and don’t show me any error!
But users can multi select diabetes!
itemView.post {
notifyItemChanged(lastSelectedDiabetesPosition)
}
How can I fix it?