79339813

Date: 2025-01-08 15:49:01
Score: 0.5
Natty:
Report link

I was having trouble updating my RecyclerView after scanning or importing a new PDF document. The logs were showing that the new document was being loaded, but the UI wasn't reflecting these changes. Here's a breakdown of the problems I faced and how I addressed them:

Problem:

  1. UI Not Updating After Scan/Import: The RecyclerView was not reflecting new documents after scanning or importing despite logs showing successful loading.
  2. Delayed Updates: The UI was not updating instantly, it was lagging.
  3. DiffUtil Not Called: The DiffUtil was not being called when a new document was added to the RecyclerView.

Solutions:

Code Snippet:

HomeFragment.kt

@RequiresApi(Build.VERSION_CODES.R)
    override fun onResume() {
        super.onResume()
        //Use a coroutine to import the PDFs asynchronously
        loadDocumentsWithAnimation() // Load documents with animation
        requireActivity().onBackPressedDispatcher.addCallback(
            this, true // Handle even if other fragments have higher priority
        ) {
            onBackPressed()
        }
    }

    @Deprecated("Deprecated in Java")
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        //Use a coroutine to import the PDFs asynchronously
        if (requestCode == PdfImportUtils.REQUEST_CODE_IMPORT_PDF && resultCode == Activity.RESULT_OK) {
            val urisToImport = if (data?.clipData != null) {
                (0 until data.clipData!!.itemCount).map {
                    data.clipData!!.getItemAt(it).uri
                }
            } else {
                listOfNotNull(data?.data)
            }
            //Use a coroutine to import the PDFs asynchronously
            uiScope.launch {
                progressIndicator.visibility = View.VISIBLE
                withContext(Dispatchers.IO){
                    val importJobs =    urisToImport.map { uri ->
                        async { PdfImportUtils.importPdfFromUri(requireContext(), uri, documentViewModel) }
                    }
                    importJobs.awaitAll()
                }
                withContext(Dispatchers.Main){
                     loadDocumentsWithAnimation() // Load documents with animation
                }
                  progressIndicator.visibility = View.GONE
            }
            try {
                analyticsManager.logEvent(eventName = "pdf_imported", params = Bundle().apply {
                    putString("file_uri", data?.data?.toString() ?: "Multiple Files")
                })
            }catch(e:Exception){
                Timber.e(e, "Exception in pdf_imported:")
            }
        } else {
            try {
                analyticsManager.logEvent(eventName = "pdf_import_failed", params = Bundle().apply {
                    putInt("request_code",requestCode)
                    putInt("result_code", resultCode)
                })
            }catch(e: Exception){
                Timber.e(e,"Exception in pdf_import_failed:")
            }
        }
    }

MainActivity.kt

   private fun Context.savePdfToAppStorage(pdfUri: Uri) {
        try {
            // Get the directory for app's files
            val appFilesDir = filesDir

            // Find the next available filename with auto-increment
            val newFileName = createUniqueFileInDirectory(appFilesDir)
            // Create the output file path
            val outputFile = File(appFilesDir, newFileName)

            val inputStream = contentResolver.openInputStream(pdfUri) ?: return
            val outputStream = FileOutputStream(outputFile)
            inputStream.copyTo(outputStream)
            Timber.d("PDF saved successfully to: $outputFile")
            Toast.makeText(this, "PDF saved as: $newFileName", Toast.LENGTH_SHORT).show()
            uiScope.launch{
                documentViewModel.refreshDocuments(this@savePdfToAppStorage)
            }
        } catch (e: Exception) {
            Timber.e(e, "Error saving PDF to App Storage:")
        }
    }

By using this, the list is correctly updated and the DiffUtil is called which animates the list correctly.

Addressing the Lagging UI:

Code Snippet: (from HomeFragment's loadDocumentsWithAnimation()):

    private fun loadDocumentsWithAnimation() {
        documentViewModel.viewModelScope.launch {
            progressIndicator.visibility = View.VISIBLE
            val documentData = documentViewModel.loadAllDocumentsFromStorage(requireContext())
            withContext(Dispatchers.Main) {
                recentDocumentsAdapter.updateRecentDocuments(documentData.second)
                recentDocumentsVisible = documentData.second.isNotEmpty()
                updateViewVisibility()
            }
            progressIndicator.visibility = View.GONE
        }
    }

Thanks to everyone how commented on the question!

Reasons:
  • Blacklisted phrase (0.5): Thanks
  • Long answer (-1):
  • Has code block (-0.5):
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Puranjay Savar Mattas