Add ProgressBar to MediaDetailPagerFragment for Image Loading Indicator (#5736)

* Add progress bar to fragment_media_detail_pager.xml

* Add progress bar to MediaDetailPagerFragment.java

* Add javadoc & comments

* Fix tests

---------

Co-authored-by: Giannis Karyotakis <110292528+karyotakisg@users.noreply.github.com>
This commit is contained in:
Evangelos Talos 2024-06-10 07:06:06 -04:00 committed by GitHub
parent 3dc7180784
commit 48bd3c07b8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 46 additions and 23 deletions

View file

@ -2,6 +2,9 @@ package fr.free.nrw.commons.media;
import static fr.free.nrw.commons.Utils.handleWebUrl; import static fr.free.nrw.commons.Utils.handleWebUrl;
import android.os.Handler;
import android.os.Looper;
import android.widget.ProgressBar;
import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.graphics.Bitmap; import android.graphics.Bitmap;
@ -76,6 +79,11 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
private boolean isFromFeaturedRootFragment; private boolean isFromFeaturedRootFragment;
private int position; private int position;
/**
* ProgressBar used to indicate the loading status of media items.
*/
private ProgressBar imageProgressBar;
private ArrayList<Integer> removedItems=new ArrayList<Integer>(); private ArrayList<Integer> removedItems=new ArrayList<Integer>();
public void clearRemoved(){ public void clearRemoved(){
@ -89,7 +97,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
/** /**
* Use this factory method to create a new instance of this fragment using the provided * Use this factory method to create a new instance of this fragment using the provided
* parameters. * parameters.
* *
* This method will create a new instance of MediaDetailPagerFragment and the arguments will be * This method will create a new instance of MediaDetailPagerFragment and the arguments will be
* saved to a bundle which will be later available in the {@link #onCreate(Bundle)} * saved to a bundle which will be later available in the {@link #onCreate(Bundle)}
* @param editable * @param editable
@ -108,7 +116,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
public MediaDetailPagerFragment() { public MediaDetailPagerFragment() {
// Required empty public constructor // Required empty public constructor
}; };
@Override @Override
public View onCreateView(LayoutInflater inflater, public View onCreateView(LayoutInflater inflater,
@ -116,7 +124,8 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
Bundle savedInstanceState) { Bundle savedInstanceState) {
binding = FragmentMediaDetailPagerBinding.inflate(inflater, container, false); binding = FragmentMediaDetailPagerBinding.inflate(inflater, container, false);
binding.mediaDetailsPager.addOnPageChangeListener(this); binding.mediaDetailsPager.addOnPageChangeListener(this);
// Initialize the ProgressBar by finding it in the layout
imageProgressBar = binding.getRoot().findViewById(R.id.itemProgressBar);
adapter = new MediaDetailAdapter(getChildFragmentManager()); adapter = new MediaDetailAdapter(getChildFragmentManager());
// ActionBar is now supported in both activities - if this crashes something is quite wrong // ActionBar is now supported in both activities - if this crashes something is quite wrong
@ -397,7 +406,7 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
} catch (Exception e) { } catch (Exception e) {
Timber.e("Cant detect media transparency"); Timber.e("Cant detect media transparency");
} }
// Initialize bookmark object // Initialize bookmark object
bookmark = new Bookmark( bookmark = new Bookmark(
m.getFilename(), m.getFilename(),
@ -497,19 +506,27 @@ public class MediaDetailPagerFragment extends CommonsDaggerSupportFragment imple
* @param position current item that to be shown * @param position current item that to be shown
*/ */
private void setViewPagerCurrentItem(int position) { private void setViewPagerCurrentItem(int position) {
final Boolean[] currentItemNotShown = {true};
Runnable runnable = new Runnable() { final Handler handler = new Handler(Looper.getMainLooper());
final Runnable runnable = new Runnable() {
@Override @Override
public void run() { public void run() {
while(currentItemNotShown[0]){ // Show the ProgressBar while waiting for the item to load
if(adapter.getCount() > position){ imageProgressBar.setVisibility(View.VISIBLE);
binding.mediaDetailsPager.setCurrentItem(position, false); // Check if the adapter has enough items loaded
currentItemNotShown[0] = false; if(adapter.getCount() > position){
} // Set the current item in the ViewPager
binding.mediaDetailsPager.setCurrentItem(position, false);
// Hide the ProgressBar once the item is loaded
imageProgressBar.setVisibility(View.GONE);
} else {
// If the item is not ready yet, post the Runnable again
handler.post(this);
} }
} }
}; };
new Thread(runnable).start(); // Start the Runnable
handler.post(runnable);
} }
/** /**

View file

@ -1,14 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:orientation="vertical"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
> xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.viewpager.widget.ViewPager <ProgressBar
android:id="@+id/mediaDetailsPager" android:id="@+id/itemProgressBar"
android:layout_width="match_parent" style="?android:attr/progressBarStyle"
android:layout_height="match_parent" android:layout_width="wrap_content"
android:fadingEdge="none" android:layout_height="wrap_content"
/> android:layout_gravity="center"
android:progressBackgroundTint="@android:color/white"/>
</LinearLayout> <androidx.viewpager.widget.ViewPager
android:id="@+id/mediaDetailsPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fadingEdge="none" />
</LinearLayout>