I am using Glide for resizing an image and saving it to the file system in an Android app, and I've created a custom FileTarget
class that extends Glide's native Target
to do it.
It works. Yay! But I'm sort of appalled by all the empty methods I had to 'define' to get it to satisfy the Target
implementation. All I really care about is onResourceReady
...
Is there any way to implement this without declaring all these empty methods? Should I be worried that they're all like this?
I'm a little new to Android so I appreciate your patience.
public static class FileTarget<T extends Bitmap> implements Target<Bitmap> {
private final int width;
private final int height;
String fileName;
Bitmap.CompressFormat format;
int quality;
public FileTarget(int width, int height, String fileName, Bitmap.CompressFormat format, int quality) {
this.width = width;
this.height = height;
this.fileName = fileName;
this.format = format;
this.quality = quality;
}
@Override
public void onLoadStarted(Drawable drawable) {}
@Override
public void onLoadFailed(Drawable drawable) {}
@Override
public void onLoadCleared(Drawable drawable) {}
@Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(width, height);
}
@Override
public void removeCallback(@NonNull SizeReadyCallback cb) {}
@Override
public void setRequest(@Nullable Request request) {}
@Nullable
@Override
public Request getRequest() {
return null;
}
@Override
public void onStart() {}
@Override
public void onStop() {}
@Override
public void onDestroy() {}
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
try {
FileOutputStream out = new FileOutputStream(fileName);
resource.compress(format, quality, out);
out.flush();
out.close();
onFileSaved();
} catch (IOException e) {
e.printStackTrace();
onSaveException(e);
}
}
public void onFileSaved() {
// do nothing, should be overriden
}
public void onSaveException(Exception e) {
// do nothing, should be overriden
}
}
Within the Android framework, there is a common pattern of creating an abstract FooAdapter
class that implements all of the methods in a Foo
interface with no-ops.
For example, consider this class:
public abstract class AnimatorListenerAdapter implements Animator.AnimatorListener,
Animator.AnimatorPauseListener {
@Override
public void onAnimationCancel(Animator animation) { }
@Override
public void onAnimationEnd(Animator animation) { }
@Override
public void onAnimationRepeat(Animator animation) { }
@Override
public void onAnimationStart(Animator animation) { }
@Override
public void onAnimationPause(Animator animation) { }
@Override
public void onAnimationResume(Animator animation) { }
}
You could create the same thing for Glide:
public abstract class TargetAdapter<T> implements Target<T> {
@Override
public void onLoadStarted(Drawable drawable) {}
@Override
public void onLoadFailed(Drawable drawable) {}
@Override
public void onLoadCleared(Drawable drawable) {}
@Override
public void getSize(SizeReadyCallback cb) {}
@Override
public void removeCallback(@NonNull SizeReadyCallback cb) {}
@Override
public void setRequest(@Nullable Request request) {}
@Override
public Request getRequest() {}
@Override
public void onResourceReady(@NonNull T resource, @Nullable Transition<? super T> transition) {}
}
Now, when you create your FileTarget
class, you can declare that it extends TargetAdapter
rather than implements Target
, and only override the methods that you care about:
public static class FileTarget<T extends Bitmap> extends TargetAdapter<Bitmap> {
// ...
@Override
public void getSize(SizeReadyCallback cb) {
cb.onSizeReady(width, height);
}
@Nullable
@Override
public Request getRequest() {
return null;
}
@Override
public void onResourceReady(@NonNull Bitmap resource, @Nullable Transition<? super Bitmap> transition) {
try {
FileOutputStream out = new FileOutputStream(fileName);
resource.compress(format, quality, out);
out.flush();
out.close();
onFileSaved();
} catch (IOException e) {
e.printStackTrace();
onSaveException(e);
}
}
// ...
}