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()
}
}