Want to show progress bar while moving to the previous page from the current page

Viewed 342

I want to show progress bar when I'm moving from the current page to previous page. so my scenario is like in the current page I'm downloading 20-25 images and while downloading the images want to move from the current page to the previous screen and show the progress bar in a RecyclerView and in the upper area of the page(till downloading completed).

So how Can I achieve it? I'm not getting like how we can show the progress from current page to previous page? Please help me out. Any help will be appreciated.

ImageDownload()

private fun downloadImage() {
    GlobalScope.launch(dispatcherProvider.io()) {
        for (angle in 0..340 step 20) {
            dataHandler.MyRequestHandler.getImage(url.replace("340", "%03d".format(angle)), "%03d".format(angle)) { response: Response ->

                if (response.body() != null && response.isSuccessful && response.networkResponse()!!.code() == 200) {
                    if (isDownload) {
                        activity.lifecycleScope.launch {
                            try {
                                isDownload = true
                                val imageByteArray = response.body()?.source()?.readByteArray()
                                imageEntity = viewModel.imageEntityConverter(ImageModels("xyz", number, "%03d".format(angle), "ownImage", imageByteArray))
                                viewModel.insertNumber(imageEntity)
                                activity.popSubPage()
                                activity.showSubPage(CarSelectionSite(activity), false)
                            } catch (e: Exception) {
                                Timber.e(e, "Failed to download image")
                                showErrorMessageDialog(R.string.failed, R.string.general_request_error)
                            }
                        }
                    }
                } else if (response.networkResponse() != null && response.networkResponse()!!.code() == 404) {
                    showErrorMessageDialog(R.string.error_fin_not_found_title, R.string.error_fin_not_found_message)
                    return@getBBDCarImage
                } else {
                    showErrorMessageDialog(R.string.failed, R.string.general_request_error)
                    return@getBBDCarImage
                }
            }
        }
    }
}
1 Answers

For your UseCase , you just need to implement a Shared ViewModel between your fragments . I have not implemented your UseCase(Since I don't have your code ) . I have created my UseCase . It is a basic application using Navigation Component to navigate between fragments and fragment-ktx for easily creating a shared ViewModel .

First add the fragment - ktx dependency in your gradle file :

implementation "androidx.fragment:fragment-ktx:1.3.6"

Then first create a Shared View Model . Here I have just created a ViewModel with a function wherein it counts from 20 to 1 with a tiny delay and then updates the textView of the countDown it is current on . I have used MutableLiveData to communicate with fragments . You should have your download function here and you have to update your textView using MutableLiveData / KotlinFlow

class SharedViewModel : ViewModel() {

    private val _progress: MutableLiveData<Int> = MutableLiveData()
    val progress: LiveData<Int>
        get() = _progress

    suspend fun printFrom0to20() {
        viewModelScope.launch {

            for (i in 20 downTo 0) {
                _progress.postValue(i)
                delay(100)
            }
        }
    }

}

I have two fragments . In the first there is a button which navigates to the second Fragment and a textView wherein it shows the progress where it is current at though the function is called in the second fragment . In your scenario , your progress of how many images have been downloaded will be shown though not being on the fragment where it was started . Here is how the fragment look like . Here remember to use activitViewModel which create SharedViewModel

class FirstFragment : Fragment() {

    private val viewModel: SharedViewModel by activityViewModels()
    private lateinit var moveToSecondFragment: Button
    private lateinit var progressValue: TextView


    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view = inflater.inflate(R.layout.fragment_first, container, false)
        moveToSecondFragment = view.findViewById(R.id.moveToSecondFragment)
        progressValue = view.findViewById(R.id.currentProgress)
        return view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        viewModel.progress.observe(viewLifecycleOwner, {
            progressValue.text = it.toString()
        })

        moveToSecondFragment.setOnClickListener {
            findNavController().navigate(R.id.action_firstFragment_to_secondFragment)
        }
    }

}

Now in the second Fragment , I have added a button which starts the countDown also a button to navigate to last fragment and also a textView which shows current progress .


class SecondFragment : Fragment() {

    private val viewModel: SharedViewModel by activityViewModels()

    private lateinit var startDownload : Button
    private lateinit var moveToFirstFragment : Button
    private lateinit var currentProgress : TextView

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        val view =  inflater.inflate(R.layout.fragment_second, container, false)
        moveToFirstFragment = view.findViewById(R.id.moveToFirstFragment)
        startDownload = view.findViewById(R.id.startDownload)
        currentProgress = view.findViewById(R.id.currentProgress2)
        return  view
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        startDownload.setOnClickListener {
            lifecycleScope.launch {
                viewModel.printFrom0to20()
            }
        }

        moveToFirstFragment.setOnClickListener {
            findNavController().navigate(R.id.action_secondFragment_to_firstFragment)
        }

        viewModel.progress.observe(viewLifecycleOwner,{
            currentProgress.text = it.toString()
        })

    }


}

If you adopt to this code , you will see that the countdown can be seen at both the fragment . Using SharedViewModel concept you can create your own version as per your UseCase .

This is the demo of the application enter image description here

Related