Thursday, 13 May 2021

RecyclerView flashing data at start turning the rows invisible

In some devices the recyclerview are flashing items and nothing more, after that, appear from items in row. I can't debug that because in emulator and my phone it doesn't happen.

Has anyone ever experienced that?

enter image description here

The correct thing would be to keep as the follow img:

enter image description here

I'm creating the RecyclerView as below, in SubItemsActivity:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    subMainList = ArrayList()

    subMainList = db.listSubItems("AND id_main_item=$mainId")

    layoutManagerRecycler = LinearLayoutManager(this)
    subMainItemsRecycler.layoutManager = layoutManagerRecycler
    subMainItemsRecycler.addItemDecoration(DividerItemDecoration(this, 1))

    var subMainAdapter = SubMainAdapter(this, subMainList, this, activate)
    subMainAdapter.setHasStableIds(true)
    subMainItemsRecycler.adapter = subMainAdapter
}

The recyclerView layout is here: I have two ConstraintLayouts, the main is the first, with id "prioritize_edit", the other layout will not appear in the image example.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/prioritize_edit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            android:id="@+id/counter"
            android:layout_width="wrap_content"
            android:layout_height="0dp"
            android:textSize="17sp"
            android:textStyle="bold"
            android:textColor="@color/white"
            android:paddingStart="4dp"
            android:paddingEnd="2dp"
            android:paddingVertical="7.5dp"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="1dp"
            android:background="#BFBFBF"
            android:layout_marginStart="8dp"
            android:gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintEnd_toStartOf="@+id/arrows"
            app:layout_constraintTop_toTopOf="parent" >
        </TextView>

        <ImageView
            android:id="@+id/arrows"
            android:src="@drawable/icon_arrow_bottom"
            android:layout_height="0dp"
            android:layout_width="15dp"
            android:paddingEnd="1dp"
            android:layout_marginTop="4dp"
            android:layout_marginBottom="1dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/counter"
            app:layout_constraintEnd_toStartOf="@+id/check_item"
            app:layout_constraintTop_toTopOf="parent">

        </ImageView>

        <CheckBox
            android:id="@+id/check_item"
            android:layout_width="30dp"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:layout_gravity="start|center_vertical"
            android:gravity="start|center_vertical"
            android:layout_marginStart="3dp"
            android:layout_marginEnd="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/arrows"
            app:layout_constraintEnd_toStartOf="@+id/color_picker"
            app:layout_constraintTop_toTopOf="parent" />

        <Spinner
            android:id="@+id/color_picker"
            android:layout_width="35dp"
            android:layout_height="wrap_content"
            android:background="@null"
            android:gravity="center"
            android:layout_gravity="center"
            android:layout_marginRight="5dp"
            android:layout_marginEnd="5dp"
            android:layout_marginLeft="13dp"
            android:layout_marginStart="13dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/check_item"
            app:layout_constraintEnd_toStartOf="@+id/list_subitem"
            app:layout_constraintTop_toTopOf="parent" />

        <EditText
            android:id="@+id/list_subitem"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="0dp"
            android:layout_marginBottom="0dp"
            android:textSize="17sp"
            android:fontFamily="sans-serif-black"
            android:textColor="@color/text_gray"
            android:layout_alignParentStart="true"
            android:layout_alignParentEnd="true"
            app:layout_constrainedWidth="true"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/color_picker"
            app:layout_constraintEnd_toStartOf="@+id/menu_subitem"
            app:layout_constraintTop_toTopOf="parent" />


        <ImageView
            android:id="@+id/menu_subitem"
            android:layout_width="40dp"
            android:layout_height="wrap_content"
            android:layout_alignParentStart="true"
            android:layout_alignParentEnd="true"
            android:layout_alignParentTop="true"
            android:paddingEnd="8dp"
            android:src="@drawable/round_more_vert_black_36"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintStart_toEndOf="@+id/list_subitem"
            app:layout_constraintEnd_toStartOf="@+id/draggable_subitem"
            app:layout_constraintTop_toTopOf="parent"/>

    <ImageView
        android:id="@+id/draggable_subitem"
        android:layout_width="42dp"
        android:layout_height="42dp"
        android:adjustViewBounds="true"
        android:scaleType="fitCenter"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="10dp"
        android:layout_marginVertical="0dp"
        android:src="@drawable/icon_draggable"
        android:background="@null"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toEndOf="@+id/menu_subitem"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />


</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
    android:id="@+id/prioritize_sub"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="visible"
    android:layout_marginBottom="5dp">


    <Button
        android:id="@+id/prioritizer_button"
        android:layout_width="0dp"
        android:layout_height="45dp"
        android:fontFamily="sans-serif-black"
        android:text="@string/prioritize"
        android:textColor="@color/white"
        android:background="@color/colorPrimary"
        android:alpha="0.80"
        android:paddingHorizontal="15dp"
        android:layout_marginTop="5dp"
        android:layout_marginEnd="15dp"
        android:textSize="16sp"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toEndOf="@id/counter_invisible"/>

    <TextView
        android:id="@+id/counter_invisible"
        android:visibility="invisible"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="17sp"
        android:textStyle="bold"
        android:textColor="@color/white"
        android:paddingHorizontal="10dp"
        android:paddingVertical="7.5dp"
        android:layout_marginTop="7dp"
        android:background="#BFBFBF"
        android:layout_marginStart="8dp"
        app:layout_constrainedWidth="true"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/prioritizer_button"/>


</androidx.constraintlayout.widget.ConstraintLayout>

My Adapter is this:

class SubMainAdapter(
    var activity: SubMainActivity,
    var items: MutableList<SubItems>,
    var clickListener: OnSubMainItemClickListener,
    var activate: Boolean
) : RecyclerView.Adapter<SubMainViewHolder>(){

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

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SubMainViewHolder {

        val itemView = LayoutInflater.from(parent.context).inflate(
            R.layout.layout_subitem_view,
            parent,
            false
        )
        val viewHolder = SubMainViewHolder(itemView)

        return viewHolder
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onBindViewHolder(holder: SubMainViewHolder, position: Int) {
        holder.initialize(
            activity, items[position], clickListener, items.size,
            items,
            position
        )

        if (activate) {
            holder.dragButton.visibility = View.VISIBLE
            holder.check_item.visibility = View.GONE
            holder.menuButton.visibility = View.GONE
        } else {
            holder.dragButton.visibility = View.GONE
            holder.check_item.visibility = View.VISIBLE
            holder.menuButton.visibility = View.VISIBLE
        }

        holder.dragButton.setOnTouchListener { v, event ->
            if(event.actionMasked== MotionEvent.ACTION_DOWN){
                v.performClick()
                activity.touchHelper?.startDrag(holder)
            }
            false
        }
    }

    override fun getItemId(position: Int): Long {
        val subItems: SubItems = items[position]
        return subItems.id.toLong()
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }
}

class SubMainViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
    var subMainItem = itemView.list_subitem
    var counter = itemView.counter
    var arrows = itemView.arrows
    var counterInvisible = itemView.counter_invisible
    var prioritizeSub = itemView.prioritize_sub
    var prioritizerButton = itemView.prioritizer_button
    var prioritizeEdit = itemView.prioritize_edit
    var check_item = itemView.check_item
    var deleteButton = R.id.trash_subitem
    var menuButton = itemView.menu_subitem
    var dragButton = itemView.draggable_subitem
    var color_picker = itemView.color_picker

    fun initialize(
        activity: SubMainActivity,
        item: SubItems,
        action: OnSubMainItemClickListener,
        sizeArrayItems: Int,
        listItems: MutableList<SubItems>,
        position: Int
    ){
//        var counterValue: String = item.list_order.toString()
//        var digitsNumber: Int = sizeArrayItems.toString().length
//        while (counterValue.length<digitsNumber){
//            counterValue = "0$counterValue"
//        }
        var counterValue: String = item.path_index

        subMainItem.setText(item.sub_item)
        counterInvisible.text = "$counterValue"
        counter.text = "$counterValue"

        counter.setBackgroundColor(Color.parseColor("#a5a5a5"))
        counter.background.alpha = if(item.max_level==0) 0 else (255*item.level)/item.max_level
        arrows.setBackgroundColor(Color.parseColor("#a5a5a5"))
        arrows.background.alpha = if(item.max_level==0) 0 else (255*item.level)/item.max_level

        val prevItem = if(position <= listItems.size){listItems[position]}else{if(position-1 <= listItems.size){listItems[position]}else{listItems[position - 1]}}
        val childs = item.direct_childs
        val nextItem = if(position >= listItems.size){listItems[position]}else{if(position+1 >= listItems.size){listItems[position]}else{listItems[position + 1]}}

        if(childs==0){
            arrows.setImageResource(R.drawable.icon_arrow_right)
        }else{
            if(nextItem.visibility == 0){
                arrows.setImageResource(R.drawable.icon_arrow_right)
            }else {
                arrows.setImageResource(R.drawable.icon_arrow_bottom)
            }
            arrows.setOnClickListener {
                action.toggleSubItems(item, adapterPosition, itemView)
            }
            counter.setOnClickListener {
                action.toggleSubItems(item, adapterPosition, itemView)
            }

        }

        if (item.prioritizeButton){
            prioritizeSub.visibility = View.VISIBLE
            val prioritizeString = activity.getString(R.string.prioritize)
            val finalStr = String.format(prioritizeString, item.path_index)
            prioritizerButton.text = finalStr
            prioritizerButton.setOnClickListener{
                action.onPrioritizeItemsClick(item)
            }
            prioritizeEdit.visibility = View.GONE
        }else{
            prioritizeSub.visibility = View.GONE
            prioritizeEdit.visibility = View.VISIBLE
        }

        val param = itemView.layoutParams as RecyclerView.LayoutParams
        if (item.visibility==1) {
            param.height = LinearLayout.LayoutParams.WRAP_CONTENT
            param.width = LinearLayout.LayoutParams.MATCH_PARENT
            itemView.visibility = View.VISIBLE
        } else {
            itemView.visibility = View.GONE
            param.height = 0
            param.width = 0
        }
        itemView.layoutParams = param


        if (item.checked==Constants.TRUE){
            check_item.isChecked = true
            subMainItem.setTextColor(ContextCompat.getColor(activity, (R.color.checked)))
            counter.setTextColor(ContextCompat.getColor(activity, (R.color.checked)))
            subMainItem.apply {
                paintFlags = paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
            }
            counter.apply {
                paintFlags = paintFlags or Paint.STRIKE_THRU_TEXT_FLAG
            }
        }else{
            check_item.isChecked = false
            subMainItem.setTextColor(ContextCompat.getColor(activity, (R.color.text_grayer)))
            counter.setTextColor(ContextCompat.getColor(activity, (R.color.text_gray_darker)))
            subMainItem.apply {
                paintFlags = paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
            }
            counter.apply {
                paintFlags = paintFlags and Paint.STRIKE_THRU_TEXT_FLAG.inv()
            }
        }
        check_item.setOnClickListener{
            action.onCheckItemClick(item, adapterPosition, itemView)
        }

        menuButton.setOnClickListener{
            val popup = PopupMenu(activity, menuButton)
            popup.inflate(R.menu.submain_options)
            popup.setOnMenuItemClickListener(object : PopupMenu.OnMenuItemClickListener {
                override fun onMenuItemClick(menuItem: MenuItem): Boolean {
                    when (menuItem.itemId) {
                        R.id.trash_subitem -> {
                            action.onExcludeItemClick(item, adapterPosition)
                            return true
                        }
                        R.id.add_sub_subitem -> {
                            action.onAddChildItemClick(item, adapterPosition)
                            return true
                        }
                        R.id.prioritize_sub_subitem -> {
                            action.manageDragButtons(true, item.id, item.direct_childs)
                            return true
                        }
                        else -> return false
                    }
                }
            })
            popup.show()
        }

        val textWatcher = object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {}
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
            override fun onTextChanged(
                text: CharSequence?,
                start: Int,
                before: Int,
                count: Int
            ) {
                action.onKeyDownItem(item, itemView, text)
            }
        }
        subMainItem.addTextChangedListener(textWatcher)

        color_picker.adapter = CustomSpinnerAdapter(
            color_picker.context,
            listOf(
                SpinnerData(R.drawable.white_arrow),
                SpinnerData(R.drawable.red_arrow),
                SpinnerData(R.drawable.orange_arrow),
                SpinnerData(R.drawable.yellow_arrow),
                SpinnerData(R.drawable.green_arrow),
                SpinnerData(R.drawable.blue_arrow),
                SpinnerData(R.drawable.turquoise_arrow),
                SpinnerData(R.drawable.purple_arrow)
            )
        )
//        var checkSpinner: Int = 0
        color_picker.isSelected = false;
        color_picker.setSelection(item.color, false)
        color_picker.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
            override fun onItemSelected(
                adapterView: AdapterView<*>?,
                view: View,
                spinnerPosition: Int,
                l: Long
            ) {
//                if(++checkSpinner > 1) {
                    action.onSpinnerChange(item, spinnerPosition)
//                }
            }

            override fun onNothingSelected(adapterView: AdapterView<*>?) {
                return
            }
        }
    }
}

interface OnSubMainItemClickListener{
    fun onCheckItemClick(item: SubItems, position: Int, view: View)
    fun onExcludeItemClick(item: SubItems, position: Int)
    fun onAddChildItemClick(item: SubItems, position: Int)
    fun onPrioritizeItemsClick(item: SubItems)
    fun onKeyDownItem(item: SubItems, view: View, text: CharSequence?)
    fun onChangeItem(item: SubItems, view: View, text: CharSequence?)
    fun onSpinnerChange(item: SubItems, spinnerPosition: Int)
    fun manageDragButtons(activate: Boolean, parentId: Int, childs: Int)
    fun toggleSubItems(item: SubItems, position: Int, view: View)
}

As I'm using setHasStableIds(true) I've tried to change the getItemId function in adapter, but the problem remains. Has anyone had a similar problem?



from RecyclerView flashing data at start turning the rows invisible

No comments:

Post a Comment