Просмотр вторичной переработки, показывающий два выделенных элемента

#android #arraylist #android-recyclerview #adapter #onclicklistener

Вопрос:

У меня есть два сценария для выделения элемента в recyclerview: первый-когда пользователь нажимает на любой элемент, чтобы выделенный элемент был выделен, и второй сценарий-когда последний или последний элемент, добавленный в список, должен быть выделен в тот момент, когда последний добавленный элемент должен быть выделен.

Итак, мой первый сценарий(onClick) работает нормально, но проблема в моем втором сценарии, поэтому всякий раз, когда я добавляю элемент в список, выделяются два элемента. Пожалуйста, подскажите мне, где я ошибаюсь. и еще одно, что недавний или последний элемент также должен выполнять автоматический щелчок. так как же я могу этого достичь?

 class CarItemAdapter(
        private val activity: MainActivity,
        private val carList: ArrayList<CarEntity>,
        private val carViewModel: CarViewModel,
        private val settings: Settings
) :
        RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    var listener: OnItemsClickListener? = null
    var rowIndex = 100
    var listItemCount = 0

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val layoutInflater = LayoutInflater.from(parent.context)
        return when (viewType) {
            VIEW_TYPE_ADDITEM -> ViewHolderAddCarItem(SettingsCarAddItemTileBinding.inflate(layoutInflater, parent, false))
            VIEW_TYPE_ITEM -> ViewHolderCarItem(SettingsCarItemTileBinding.inflate(layoutInflater, parent, false))
            else -> throw IllegalArgumentException("Invalid view type")
        }
    }

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {

        when (holder) {
            is ViewHolderCarItem -> holder.bind(carList[position -1], position-1)
            is ViewHolderAddCarItem -> holder.bind()
        }
    }

    inner class ViewHolderAddCarItem internal constructor(private var binding: SettingsCarAddItemTileBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind() {
            binding.lifecycleOwner = activity
            binding.handler = EventHandler()
            binding.userSpecificCarSubtitle.setText(R.string.user_specific_car_subtitle)
        }

        inner class EventHandler {
            fun onItemClicked() {
                activity.showSubPage(Car360AddVehiclePage(activity), true)
            }
        }
    }

    inner class ViewHolderCarItem internal constructor(private var binding: SettingsCarItemTileBinding) : RecyclerView.ViewHolder(binding.root) {
        fun bind(carEntity: CarEntity, position: Int) {
            Timber.d("Data store position %s %s", position, carList.size)
            listItemCount = itemCount

            binding.lifecycleOwner = activity
            val bmp = BitmapFactory.decodeByteArray(carEntity.image, 0, Objects.requireNonNull<ByteArray>(carEntity.image).size)
            binding.carImage.setImageBitmap(bmp)
            binding.carName.text = carEntity.label

            binding.layoutCar.setOnClickListener {
                listItemCount = 100
                listener?.onItemClick(carEntity)
                settings.finNumber = carEntity.finNumber
                settings.selectedCarType = activity.getString(R.string.settings_category_view_sub_title_for_user_specific_car)
                settings.isCarSelected = true
                rowIndex = position
                notifyDataSetChanged()
            }

            binding.deleteButton.setOnClickListener {
                GlobalScope.launch(Dispatchers.IO) { carViewModel.deleteByFinNumber(carEntity.finNumber) }
                carList.removeAt(position)
                notifyDataSetChanged()
            }

            if(position == listItemCount-2){
                binding.layoutCar.setBackgroundColor(activity.getColor(R.color.petrol))
                binding.carName.setTextColor(activity.getColor(R.color.white))
            }else{
                binding.layoutCar.setBackgroundColor(activity.getColor(R.color.coolGray))
                binding.carName.setTextColor(activity.getColor(R.color.coolGray_80k))
            }

            if (rowIndex == position) {
                binding.layoutCar.setBackgroundColor(activity.getColor(R.color.petrol))
                binding.carName.setTextColor(activity.getColor(R.color.white))
            }
        }
    }

    override fun getItemViewType(position: Int): Int {
        return if (position == 0 amp;amp; position <= carList.size) {
            VIEW_TYPE_ADDITEM
        } else VIEW_TYPE_ITEM
    }

    override fun getItemCount(): Int {
        return carList.size   1
    }

    interface OnItemsClickListener {
        fun onItemClick(carEntity: CarEntity)
    }

    fun setWhenClickListener(listener: OnItemsClickListener) {
        this.listener = listener
    }

    companion object {
        const val VIEW_TYPE_ITEM = 0
        const val VIEW_TYPE_ADDITEM = 1
    }
} 
 

MyFragmentSubPage : где я добавляю данные в список

  if (isDialogVisible) {
            Dialog imageDownloadCheckDialog = Dialog.createProgressBarDialog(getContext(), R.string.image_progressbar_title);
            imageDownloadCheckDialog.setCancelable(false);
            imageDownloadCheckDialog.show();
            carViewModel.getGetDismissDialog().observe(getActivity(), isDismissDialog -> {
                if (isDismissDialog) {
                    imageDownloadCheckDialog.dismiss();
                    carViewModel.dismissDialog(false);
                    new Thread(() -> {
                        CarEntity carEntity = carViewModel.getImageFor340Degree(vinNumber, "340");
                        // Here I am adding data into the list
                        recyclerImageList.add(carEntity);
                    }).start();
                }

            });
        }
        
          RecyclerView recyclerView = binding.getRoot().findViewById(R.id.list);
        if (recyclerView != null) {
            layoutManager = new GridLayoutManager(getContext(), 2);
            recyclerView.setLayoutManager(layoutManager);
        }

  carItemAdapter = new CarItemAdapter(getActivity(), recyclerImageList, eventHandler, carViewModel, settings);
            assert recyclerView != null;
            recyclerView.setAdapter(carItemAdapter);
            recyclerView.getRecycledViewPool().setMaxRecycledViews(carItemAdapter.VIEW_TYPE_ITEM, 50);
 

Ответ №1:

Сначала сделайте CarEntity var внутри вашего адаптера под названием selectedCar .

Создайте функцию внутри вашего адаптера под названием submitItem

   fun submitItem(car: CarEntity) {
            selectedCar = car //set the selected car to the new car
            notifyItemChanged(rowIndex)//rebind old selected car
            carList.add(car) //add new car to list
            rowIndex = carList.size() - 1 //set current selected index
            notifyItemInserted(rowIndex)//notify the change at selected index
    }
 

И ваш диалог

                 new Thread(() -> {
                    CarEntity carEntity = carViewModel.getImageFor340Degree(vinNumber, "340");
                    // Here I am adding data into the list
                    requireActivity().runOnUiThread{
                          carItemAdapter.submitItem(carEntity);   
                    }
                }).start();
 

и твоя пуговица

 binding.layoutCar.setOnClickListener {
                listItemCount = 100
                listener?.onItemClick(carEntity)
                settings.finNumber = carEntity.finNumber
                settings.selectedCarType = activity.getString(R.string.settings_category_view_sub_title_for_user_specific_car)
                

                selectedCar = carEntity //set the select car on click
                notifyItemChanged(rowIndex) //notify old row has changed
                notifyItemChanged(position) //notify new row has changed
                rowIndex = position // set current selected row
            }
 

и на привязке, чтобы установить выбранный материал для просмотра

 if(carEntity == selectedCar){
    //highlight row
}
 

Комментарии:

1. То есть вы хотите сказать , что если у вас есть 5 товары и вы выбрали товар 1 , то добавьте товар сейчас 5 , и 6 вы выбраны ИЛИ это товары 1 и 6 выбраны.

2. Я говорю, что если у меня есть 5 пунктов в списке, то я добавляю 6-й пункт в список, поэтому 5-й и 6-й выделяются вместо 6-го. Здесь я не нажимаю и не выбираю элемент.

3. просто всякий раз, когда я добавляю данные в список, который должен быть выбран последний элемент, и, поскольку я уже указал на этот вопрос, у меня есть 2 сценария, один из которых заключается в том, что я должен выделить выбранный элемент, а второй-если данные будут добавлены в список в тот раз, когда этот последний элемент должен быть выделен

4. Можете ли вы опубликовать фрагмент кода, в котором вы добавляете элементы в список, и уведомить адаптер об изменении?

5. возникает проблема при реализации той же логики «android.view.ViewRootImpl$CalledFromWrongThreadException: только исходный поток, создавший иерархию представлений, может касаться его представлений». в этой строке notifyItemChanged(RowIndex)//привязка старого выбранного автомобиля