Update UIProgressView progress via delegate
I figured it out. So for anyone in the future with similar issue just make sure all the tasks are running in the background then call the progressView on the main thread. In my case I had to specify in my viewDidLoad:
DispatchQueue.global(qos: .background).async {[self] in
fetchInfo()
}
Then call the UI change on the main thread:
DispatchQueue.main.async { [self] in
progressView.setProgress(Float(progress), animated: true)
}
How do I update the upload progress percentage in the recyclerview items?
@Override
public void onProgressChanged(int id, long bytesCurrent, long bytesTotal) {
long _bytesCurrent = bytesCurrent;
long _bytesTotal = bytesTotal;
float percentage = (int) ((float)_bytesCurrent /(float)_bytesTotal * 100);
Log.d("percentage","" + percentage);
adapter.updateProgress(percentage, position);// pass adapter list item position here
}
Adapter change
Instead of ArrayList<String> filePaths
use ArrayList<FilesClass> filePaths
and update your adapter accordingly
FilesClass.java
public class FilesClass {
String FileName;
Float Percentage;
public FilesClass(String fileName, Float percentage) {
FileName = fileName;
Percentage = percentage;
}
public FilesClass() {
}
public String getFileName() {
return FileName;
}
public void setFileName(String fileName) {
FileName = fileName;
}
public Float getPercentage() {
return Percentage;
}
public void setPercentage(Float percentage) {
Percentage = percentage;
}
}
and Add your file path and default progress 0. after using this custom model all your files and progress managed to same index
Then,
public void updateProgress(float percentage, int position){
ProgPos = String.valueOf(position);
Progress = (int) percentage;
filePaths.get(position).setPercentage(percentage);
notifyItemChanged(position);
}
Update the Progress Bar in the ListView when downloading
You need to call publishProgress from the doInBackground method to update the ProgressBar: publishProgress docs
This will call onProgressUpdate(Integer... values);
You don't need the myProgress instance variable;
progressBar in ListView changes parent on scroll
ListView
, like all Adapter views, uses views recycling.
The problem is that when i click the element ProgressBars became visible not only in the row i clicked but in other random rows too.
I bet it happens when you scroll the view. It works like this: you show the progress bar, then scroll the list. The item with the progress bar scrolls outside of the visible area of the screen. This is the moment the view gets recycled. The system detaches it from listview and attaches again to show another row of your list. This is why you see the progress bar again.
What to do?
You should turn the visibility of the progress bar inside the getView() method of your custom adapter (which can be based on BaseAdapter
). Whether it's turned on or not should depend on some flag.
Read this to find out more about views recycling in adapter views.
i need to change visibility of progressbar and it's progress when i
click on the element, not when i create listview.
Just define a method in your adapter which will change the value of the flag. Then you can call notifyDataSetChanged.
The important thing to remember when dealing with adapter views is that you change the underlying data, not the view, because you may have several thousand items in your lists, but there are only a few views to deal with the visible rows.
Progress Bar during the loading of a ListView
The reason for that behavior is that you are starting multiple threads.
FillLocations preExecute --> SHOW ProgressBar
BitmapWorkerTask_1 --> new thread
BitmapWorkerTask_2 --> new thread
...
BitmapWorkerTask_N --> new thread
FillLocations postExecute --> HIDE ProgressBar
BitmapWorkerTask_K --> continue execution
BitmapWorkerTask_K+1 --> continue execution
etc.
If you want the list to be displayed until it's all loaded, Simply make BitmapWorker's processing synchronous. If you still want to display the list right away but keep the spinner until it's all finished, then keep a counter in your activity and increase it in preexecute and decrease it in postExecute of BitmapWorker via a setter. Once the counter hits 0, remove hide the progressBar.
In activity:
private int asynchCounter = 0;
private void updateCounter(int delta){
asynchCounter+=delta;
if(asynchCounter<=0){
progress.setVisibility(View.GONE);
}else{
progress.setVisibility(View.VISIBLE);
}
}
And instead of BitmapWorkerTask use
class CountedBitmapWorkerTask extends BitmapWorkerTask {
protected void onPreExecute() {
super.onPreExecute();
updateCounter(1);
}
protected void onPostExecute(String msg) {
super.onPostExecute();
updateCounter(-1);
}
}
Updating Progress bar in listview while downloading a file
Children of a list view are built by an adapter. This adapter has some underneath data that is 'transformed' to views in getView() method. This means you have to change that data in update progress method of async task and call adapter.notifyDataSetChanged(). And your getView method should just 'transform' data to the list view child.
AsyncTask:
protected void onProgressUpdate(final int... values) {
data[i].progress = values[0];
adapter.notifyDataSetChanged();
}
Adapter:
public View getView(final int position, final View convertView, final ViewGroup parent) {
...
progress.setProgress(getItem(position).progress);
...
}
Saved State progressbar status and button click event in android listview
use Activity.runOnUiThread for updating ProgressBar from Thread as :
TestHopeDownload.this.runOnUiThread(new Runnable() {
public void run() {
updateStatus(position, Status); //<<<< call updateStatus method here
}
});
Showing progress bar while loading a List
Use AsyncTask
to load data in background while showing loading indicator. In AsyncTask's
doInBackground
method , process the JSON or anything which is taking time.
public class HeavyWorker extends AsyncTask < String , Context , Void > {
private ProgressDialog progressDialog ;
private Context targetCtx ;
public HeavyWorker ( Context context ) {
this.targetCtx = context ;
this.needToShow = true;
progressDialog = new ProgressDialog ( targetCtx ) ;
progressDialog.setCancelable ( false ) ;
progressDialog.setMessage ( "Retrieving data..." ) ;
progressDialog.setTitle ( "Please wait" ) ;
progressDialog.setIndeterminate ( true ) ;
}
@ Override
protected void onPreExecute ( ) {
progressDialog.show ( ) ;
}
@ Override
protected Void doInBackground ( String ... params ) {
// Do Your WORK here
return null ;
}
@ Override
protected void onPostExecute ( Void result ) {
if(progressDialog != null && progressDialog.isShowing()){
progressDialog.dismiss ( ) ;
}
}
}
In your Activity's onCreate()
execute AsyncTask
new HeavyWorker().execute();
Related Topics
How to Make Exponents in the Swiftui
How to Retrieve Audio File from Parse Swift
Swiftui Mysterious Spacing Between Large Text and Textfield in VStack
Cannot Stop Background Music from Within Game Scenes, Swift 3/Spritekit
Let User Save PDF Outside App in iOS Swift
Declaring Conformance to @Objc Protocol in Empty Extension Breaks with Exc_Bad_Instruction
Swift Decodable, Endpoint Returns Completely Different Types
Moving an Object Across the Screen at a Certain Speed.(Sprite Kit)
Tabview, Tabitem: Running Code on Selection or Adding an Ontapgesture
Value of Type 'Authdataresult' Has No Member 'Uid'
Don't Delete Some Rows from Uitableview
How to Get Exactly the Same Point on Different Screen Sizes
Get Element from Array of Dictionaries According to Key