In my application I can create albums with photos, store them on Firebase and view them.
Well, in order to browse these albums I decided to create something like viewing screenshots of an app/game in the Play Store in full screen.
I created Activity
and added ViewPager2
to this Activity
, then I created Fragment
and Adapter
to show my images and everything seems to work but there are some problems with Glide.
First I tried to use this code to load photos:
Glide.with(MediaViewerFragment.this).load(imageUrl).into(image);
but the pictures were not showing.
On stackoverflow I found a solution - it was to add a listener to the method and instead of into(View)
use submit()
So I wrote such a listener:
RequestListener<Drawable> listener = new RequestListener<>() {
@Override
public boolean onl oadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
errorLinear.setVisibility(View.VISIBLE);
errorReasonText.setText(e.getMessage());
loadingLinear.setVisibility(View.GONE);
Log.d("Test", "Glide: Cannot load image: " e.getMessage());
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
image.setImageDrawable(resource);
image.invalidate();
loadingLinear.setVisibility(View.GONE);
Log.d("Test", "Glide: Image loaded");
return false;
}
};
Glide.with(MediaFragment.this).load(imageUrl).addListener(listener).submit();
but:
When I open the album the photo in the first Fragment does not appear immediately after loading, the image "loads into imageview" only when I touch the ViewPager2 with my finger or scroll to the next Fragment and return to the first one.
ProgressBar does not disappear on first fragment
and I don't know why this is happening. I think that this happens because maybe the first Glide Listener is begin replaced by other listeners in others fragments with images?
As you can see, in OnResourceReady
I have Log.d("Test", "Glide: Image loaded");
but it doesn't appear to me in LogCat (on first fragment, when i swipe to others fragment then everything works fine!). But when I put Log.d("Test", "Glide: Image loaded");
on top so it will look like this:
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
Log.d("Test", "Glide: Image loaded");
image.setImageDrawable(resource);
image.invalidate();
loadingLinear.setVisibility(View.GONE);
return false;
}
then:
When I open the album then immediately in logcat I get my message that the photo has been uploaded but unfortunately, I still can't see it and ProgressBar doesn't disappear.
I still need to swipe to next fragment and go back to previous to see that image.
Video describing the problem - you can see that I have to touch the screen for the photo to load which is weird and shouldn't happen
MediaViewerFragment.java
public class MediaViewerFragment extends Fragment {
View mRootView;
private ImageView image;
private LinearLayout errorLinear, loadingLinear;
private MaterialTextView errorReasonText;
private String imageUrl;
private Context context;
@Override
public void onDestroyView() {
context = null;
super.onDestroyView();
}
public MediaViewerFragment(Context context, String imageUrl) {
this.imageUrl = imageUrl;
this.context = context;
Log.d("Teest", "MediaFragment - Image to load: " imageUrl);
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_media, container, false);
return mRootView;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView();
setup();
}
private void initView() {
image = mRootView.findViewById(R.id.image);
errorLinear = (LinearLayout) mRootView.findViewById(R.id.error_linear);
errorReasonText = (MaterialTextView) mRootView.findViewById(R.id.error_reason_text);
loadingLinear = mRootView.findViewById(R.id.loading_progress_bar);
}
private void setup() {
Log.d("Test", "Preparing to load image: " imageUrl);
RequestListener<Drawable> listener = new RequestListener<>() {
@Override
public boolean onl oadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
errorLinear.setVisibility(View.VISIBLE);
errorReasonText.setText(e.getMessage());
loadingLinear.setVisibility(View.GONE);
Log.d("Test", "Glide: Cannot load image: " e.getMessage());
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
image.setImageDrawable(resource);
image.invalidate();
loadingLinear.setVisibility(View.GONE);
Log.d("Test", "Glide: Image loaded");
return false;
}
};
Glide.with(MediaViewerFragment.this)load(imageUrl).addListener(listener).submit();
}
}
ViewPager Adapter:
public class MediaViewerViewPager extends FragmentStateAdapter {
private List<AlbumImage> imagesUrls;
private Context context;
public MediaViewerViewPager(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle, Context context, List<AlbumImage> imagesUrls) {
super(fragmentManager, lifecycle);
this.imagesUrls = imagesUrls;
this.context = context;
}
@NonNull
@Override
public Fragment createFragment(int position) {
return new MediaFragment(context, imagesUrls.get(position).getImageUrl());
}
@Override
public int getItemCount() {
return imagesUrls.size();
}
}
Activity where my ViewPager2 is:
public class MediaViewerActivity extends AppCompatActivity {
private ViewPager2 imagesViewpager;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_media_viewer);
initView();
setup();
}
private void initView() {
imagesViewpager = (ViewPager2) findViewById(R.id.images_viewpager);
}
private void setup() {
MediaViewerViewPager adapter = new MediaViewerViewPager(getSupportFragmentManager(), getLifecycle(), MediaViewerActivity.this, new Gson().fromJson(getIntent().getStringExtra("albumImages"), new TypeToken<List<AlbumImage>>() {}.getType()));
imagesViewpager.setAdapter(adapter);
}
}
Fixed
After adding the placeholder
and error
methods to the code, everything works.
Correct code looks like this now:
Glide.with(image)
.load(getImageUrl())
.placeholder(R.drawable.transparent_background)
.error(R.drawable.transparent_background)
.addListener(new RequestListener<Drawable>() {
@Override
public boolean onl oadFailed(@Nullable GlideException e, Object model, Target<Drawable> target, boolean isFirstResource) {
loadingLinear.setVisibility(View.GONE);
errorLinear.setVisibility(View.VISIBLE);
errorReasonText.setText(e.getMessage());
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
loadingLinear.setVisibility(View.GONE);
return false;
}
})
.into(image);
CodePudding user response:
Have you tried to loading by using
Glide.with(View)
and set placeholder
image and error
image. it might let you know what is happening!
something like this -
Glide.with(view)
.load(imageUrl)
.error(R.drawable.someErrorImage)
.placeholder(R.drawable.somePlaceHolderImage)
.into(view);