Clans / FloatingActionButton

Android Floating Action Button based on Material Design specification
Apache License 2.0
5.23k stars 1.13k forks source link

FAB Menu in Recyclerview Adapter: fab menu click action repeating after every 7th position item #477

Closed DineshBalayan closed 4 years ago

DineshBalayan commented 4 years ago
<com.github.clans.fab.FloatingActionMenu
        android:id="@+id/menu"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        fab:menu_fab_size="mini"
        fab:menu_showShadow="true"
        fab:menu_shadowColor="#66000000"
        fab:menu_shadowRadius="1dp"
        fab:menu_shadowXOffset="1dp"
        fab:menu_shadowYOffset="1dp"
        fab:menu_colorNormal="#DA4336"
        fab:menu_colorPressed="#E75043"
        fab:menu_colorRipple="#99FFFFFF"
        fab:menu_animationDelayPerItem="50"
        fab:menu_icon="@drawable/btn_camera"
        fab:menu_buttonSpacing="0dp"
        fab:menu_openDirection="up"
        fab:menu_backgroundColor="@android:color/transparent"
        fab:menu_fab_show_animation="@anim/jump_from_down"
        fab:menu_fab_hide_animation="@anim/jump_to_down">

        <com.github.clans.fab.FloatingActionButton
            android:id="@+id/menu_gallery"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/btn_image"
            fab:fab_size="mini"/>
        <com.github.clans.fab.FloatingActionButton
            android:id="@+id/menu_camera"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/btn_camera_2"
            fab:fab_size="mini" />

    </com.github.clans.fab.FloatingActionMenu>

I simply added fab menu in adapter row, when i click on fab menu at 0th position fab buttons are visible its ok but it also updating UI for 7th, 14th .. and so on items items, this issue i found for all positions clicks.

means issue is fabmenu action repeating after 7th position.

or it is a issue of adapter taking same Reference after 6th positions myAdapter is:


import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.cars.cardatex.R
import com.cars.cardatex.room.Image
import kotlinx.android.extensions.LayoutContainer
import kotlinx.android.synthetic.main.exterior_row.view.*
import android.graphics.BitmapFactory
import android.widget.ImageView
import android.widget.TextView
import com.cars.cardatex.ImagesClick
import java.io.File

class ExteriorAdapter(val photos: MutableList, val listener1: ImagesClick) : RecyclerView.Adapter() {

override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): PhotoHolder {
    val mInflater = LayoutInflater.from(viewGroup.getContext())
    val mainGroup = mInflater.inflate(R.layout.exterior_row, viewGroup, false) as ViewGroup
    val holder = PhotoHolder(mainGroup)
    holder.view.fab.setTag(holder)
    holder.view.fab.setOnClickListener(clickItemListener())
    holder.view.fab_camera.setTag(holder)
    holder.view.fab_camera.setOnClickListener(clickItemListener())
    holder.view.fab_gallery.setTag(holder)
    holder.view.fab_gallery.setOnClickListener(clickItemListener())
    holder.view.img_delete.setTag(holder)
    holder.view.img_delete.setOnClickListener(clickItemListener())
    return holder
}

override fun getItemCount(): Int = photos.size

override fun onBindViewHolder(holder: PhotoHolder, position: Int) {
    holder.apply {
        if (photos.get(position).filepath != null) {
            val imgFile = File("" + photos.get(position).filepath)
            if (imgFile.exists()) {
                val myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath())
                view.body_image.setImageBitmap(myBitmap)
                view.fab.visibility = View.GONE
                view.img_delete.visibility = View.VISIBLE
            } else {
                view.body_image.setImageResource(photos.get(position).drawable!!)
                view.body_image.setAlpha(0.1f)
                view.fab.visibility = View.VISIBLE
                view.img_delete.visibility = View.GONE
            }
        } else {
            view.body_image.setImageResource(photos.get(position).drawable!!)
            view.body_image.setAlpha(0.1f)
            view.fab.visibility = View.VISIBLE
            view.img_delete.visibility = View.GONE
        }
    }
}

class PhotoHolder(itemview: View) : RecyclerView.ViewHolder(itemview) {
    val view= itemview
}

private fun clickItemListener(): View.OnClickListener {
    var l: View.OnClickListener? = null
    l = View.OnClickListener { view ->
        val holder = view.tag as PhotoHolder
        val id = holder.adapterPosition

        if (view.id == holder.view.fab_camera.id) {
           listener1.onCamera(id)
        }
        if (view.id == holder.view.fab_gallery.id) {
            listener1.onGallery(id)
        }
        if (view.id == holder.view.img_delete.id) {
            listener1.onGallery(id)
        }
    }
    return l
}

}


find attached video for clarification
https://www.youtube.com/watch?v=kg6vJAfbPcU

As i aware about RecyclerView reuses the existing views when scrolling (ScrappedViews)
i updated adapter with set/get Tag but Menu working from UI code.
Aashu-Dubey commented 4 years ago

This is not a library issue. this is happening because RecyclerView uses "Scrapped view" where it doesn't create new views instead use existing one to solve add this in you ViewHolder

override fun getItemId(position: Int): Long {
        return position.toLong()
    }

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

for more refernce refer this link and this

DineshBalayan commented 4 years ago

This is not a library issue. this is happening because RecyclerView uses "Scrapped view" where it doesn't create new views instead use existing one to solve add this in you ViewHolder

override fun getItemId(position: Int): Long {
        return position.toLong()
    }

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

for more refernce refer this link and this

Thanks it works @Aashu-Dubey