RecyclerView item selection not working as expected when minimizing and maximizing app

70 views Asked by At

After minimizing my app and coming back to my app again to select item from recycler view then the imageview checkbox and color filter that marks recyclerview item as checked disappear but when I select any next item then that item show imageview checkbox and color filter. I have to reselect the first selected item again to show imageview checkbox and color filter. Note: If there is time delay between app maximization and recyclerview item selection then everything is working fine. I have attached my code.Any help or guidance is highly appreciated.

ImageAdapter Code:


    var file: ArrayList<WhatsAppStatus>,

    var context: Context,

    private val listener: RecyclerViewSelectionListener

) :

    RecyclerView.Adapter<ImageAdapter.ImageViewHolder>() {

    private val selectedItems = ArrayList<WhatsAppStatus>()



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

        val itemView =

            LayoutInflater.from(parent.context).inflate(R.layout.image_item, parent, false)

        return ImageViewHolder(itemView)

    }



    override fun getItemCount(): Int {

        return file.size;

    }



    fun notifySelectAll() {

//        recyclerView.adapter?.notifyDataSetChanged()

        selectedItems.clear()

        file.forEach {

            it.isSelected = true

            selectedItems.add(it)

        }

        notifyDataSetChanged()

    }

    fun clearSelected() {

//        recyclerView.adapter?.notifyDataSetChanged()

        selectedItems.clear()

        // Perform clearing asynchronously

            file.forEach {

                it.isSelected = false

        }

        notifyDataSetChanged()

    }

    fun selectedSize(): Int {

//        recyclerView.adapter?.notifyDataSetChanged()

       return selectedItems.size

    }

    interface RecyclerViewSelectionListener {

        fun onItemSelected(selectedStatus: WhatsAppStatus, size: Int)

    }

    fun isEmpty(): Boolean {

            return selectedItems.isEmpty()

    }

    fun downloadItem(): ArrayList<WhatsAppStatus> {

            return selectedItems

    }

    override fun onBindViewHolder(holder: ImageViewHolder, position: Int) {

        val currentItem = file[position]

        if (currentItem.isSelected) {

            holder.image.setColorFilter(R.color.black)

            holder.checkBox.visibility=View.VISIBLE

        } else {

            holder.image.clearColorFilter()

            holder.checkBox.visibility=View.GONE

        }

        Glide.with(context).load(currentItem.documentFile.uri).into(holder.image)

        holder.image.setOnClickListener({

            currentItem.isSelected = !currentItem.isSelected

            if (currentItem.isSelected) {

                holder.image.setColorFilter(R.color.black)

                holder.checkBox.visibility=View.VISIBLE

                selectedItems.add(currentItem)

            } else {

                holder.image.clearColorFilter()

                holder.checkBox.visibility=View.GONE

                selectedItems.remove(currentItem)

            }

            listener.onItemSelected(currentItem,selectedItems.size)

//            notifyItemChanged(position)

        })



    }



    class ImageViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        val image: ImageView = itemView.findViewById(R.id.imageView)

        val checkBox: ImageView = itemView.findViewById(R.id.checkBox)

    }

}```



**ImageFragment Code:**

class ImageFragment : Fragment(), ImageAdapter.RecyclerViewSelectionListener, ImageAdapterListener {

    // TODO: Rename and change types of parameters

    private var param1: String? = null

    private var param2: String? = null

    private lateinit var recyclerView: RecyclerView

    private lateinit var imageFile: ArrayList<WhatsAppStatus>





    @RequiresApi(Build.VERSION_CODES.Q)

    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

        return inflater.inflate(R.layout.fragment_image, container, false)

    }



    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

        super.onViewCreated(view, savedInstanceState)

        recyclerView = view.findViewById(R.id.imageRecyclerView)

        imageFile = ArrayList()

        recyclerView.layoutManager = GridLayoutManager(context, 2)

        recyclerView.setHasFixedSize(true)

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            accessStatusesFolder()

        }

        recyclerView.adapter = ImageAdapter(imageFile, requireContext(), this)

    }





    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 ImageFragment.

         */

        // TODO: Rename and change types and number of parameters

        @JvmStatic

        fun newInstance(param1: String, param2: String) =

            ImageFragment().apply {

                arguments = Bundle().apply {

                    putString(ARG_PARAM1, param1)

                    putString(ARG_PARAM2, param2)

                }

            }

    }







    @RequiresApi(Build.VERSION_CODES.O)

    fun accessStatusesFolder() {

        AccessStatusesTask().execute()

    }



    inner class AccessStatusesTask : AsyncTask<Void, Void, List<WhatsAppStatus>>() {

        override fun doInBackground(vararg params: Void?): List<WhatsAppStatus> {

            val list = requireActivity().contentResolver.persistedUriPermissions

            val documentFile = DocumentFile.fromTreeUri(requireContext(), list[0].uri)



            val statusFiles = documentFile?.listFiles()

            val newImageFiles = ArrayList<WhatsAppStatus>()



            statusFiles?.forEach { statusFile ->

                // Get the status file name.

                val statusFileName = statusFile.name

                val whatsAppStatus = WhatsAppStatus(statusFile)

                if (statusFileName != null) {

                    if (statusFileName.endsWith(".jpg") || statusFileName.endsWith(".jpeg")

                        || statusFileName.endsWith(".png") || statusFileName.endsWith(".gif") ||

                        statusFileName.endsWith(".webp") || statusFileName.endsWith(".bmp")

                    )

                        newImageFiles.add(whatsAppStatus)

                }

            }

            imageFile.clear()

            return newImageFiles

        }



        override fun onPostExecute(result: List<WhatsAppStatus>?) {

            result?.let {



                imageFile.addAll(it)

                notifyAdapterDataSetChanged(this@ImageFragment)

            }

        }

    }



    fun downloadAll() {

        DownloadAllTask().execute()

    }



    inner class DownloadAllTask : AsyncTask<Void, Void, Unit>() {

        override fun onPreExecute() {

            super.onPreExecute()



        }

        override fun doInBackground(vararg params: Void?) {

            val selectedItem = (recyclerView.adapter as ImageAdapter).downloadItem().toList()  // Create a copy



            selectedItem.forEach {

                val savedStatusFile = File(

                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath +

                            "/statusFileName/" + it.documentFile.name

                )

                copyFile(it.documentFile, savedStatusFile)

            }

        }

        override fun onPostExecute(result: Unit?) {

            result?.let {

                (activity as StickerActivity).updateToolbarNormalMenu()

                notifyAdapterDataSetChanged(this@ImageFragment)

            }

        }

    }







    private fun copyFile(statusFile: DocumentFile, savedStatusFile: File) {

        val inputStream = requireContext().contentResolver.openInputStream(statusFile.uri) ?: return



        try {

            val outputStream = FileOutputStream(savedStatusFile)

            val buffer = ByteArray(1024)

            var bytesRead: Int

            while (inputStream.read(buffer).also { bytesRead = it } > 0) {

                outputStream.write(buffer, 0, bytesRead)

            }

            outputStream.close()

        } catch (e: IOException) {

            Log.e("MainActivity", "Failed to copy file: ${e.message}")

        } finally {

            inputStream.close()

        }

    }



    override fun onStart() {

        super.onStart()

        (activity as StickerActivity).updateToolbarNormalMenu()

        notifyAdapterDataSetChanged(this@ImageFragment)

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            accessStatusesFolder()

        }



//        Toast.makeText(context, "onStart", Toast.LENGTH_SHORT).show()





    }



    override fun onPause() {

        super.onPause()

//        notifyAdapterDataSetChanged(this@ImageFragment)

//        notifyAdapterDataSetChanged(this)

//        (activity as StickerActivity).updateToolbarNormalMenu()

//        recyclerView.adapter?.notifyDataSetChanged()

    }





    override fun onItemSelected(selectedStatus: WhatsAppStatus, size: Int) {

        (activity as StickerActivity).onItemSelected(selectedStatus, size)

    }



    override fun notifyAdapterDataSetChanged(fragment: ImageFragment) {

        (recyclerView.adapter as ImageAdapter).clearSelected()

    }



    fun isEmpty(): Boolean {

        return (recyclerView.adapter as ImageAdapter).isEmpty()

    }



    fun notifySelectAll() {

//        recyclerV

iew.adapter?.notifyDataSetChanged()

        (recyclerView.adapter as ImageAdapter).notifySelectAll()

    }



    fun notifySize(): Int {

//        recyclerView.adapter?.notifyDataSetChanged()

        return (recyclerView.adapter as ImageAdapter).selectedSize()

    }

}
1

There are 1 answers

3
Masum Billah On
private var isDataLoaded = false

override fun onStart() {
    super.onStart()

    if (!isDataLoaded) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            accessStatusesFolder()
        }
        isDataLoaded = true
    }

    // The rest of your onStart code
}