Convert ContactPictureLoader to Kotlin
This commit is contained in:
parent
2dd7d00f8d
commit
9ada669e0b
2 changed files with 126 additions and 166 deletions
|
@ -12,6 +12,6 @@ public class ContactPicture {
|
|||
|
||||
public static ContactPictureLoader getContactPictureLoader(Context context) {
|
||||
ContactLetterBitmapCreator contactLetterBitmapCreator = DI.get(ContactLetterBitmapCreator.class);
|
||||
return new ContactPictureLoader(context, contactLetterBitmapCreator);
|
||||
return new ContactPictureLoader(context.getApplicationContext(), contactLetterBitmapCreator);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,229 +1,189 @@
|
|||
package com.fsck.k9.contacts;
|
||||
package com.fsck.k9.contacts
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Bitmap.CompressFormat;
|
||||
import android.net.Uri;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.WorkerThread;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.Priority;
|
||||
import com.bumptech.glide.load.ResourceDecoder;
|
||||
import com.bumptech.glide.load.data.DataFetcher;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.engine.Resource;
|
||||
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
|
||||
import com.bumptech.glide.load.model.ModelLoader;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapEncoder;
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapResource;
|
||||
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder;
|
||||
import com.bumptech.glide.load.resource.transcode.BitmapToGlideDrawableTranscoder;
|
||||
import com.bumptech.glide.request.FutureTarget;
|
||||
import com.bumptech.glide.request.RequestListener;
|
||||
import com.bumptech.glide.request.target.Target;
|
||||
import com.fsck.k9.helper.Contacts;
|
||||
import com.fsck.k9.mail.Address;
|
||||
import com.fsck.k9.view.RecipientSelectView.Recipient;
|
||||
import android.content.Context
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Bitmap.CompressFormat
|
||||
import android.net.Uri
|
||||
import android.support.annotation.WorkerThread
|
||||
import android.widget.ImageView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.bumptech.glide.Priority
|
||||
import com.bumptech.glide.load.ResourceDecoder
|
||||
import com.bumptech.glide.load.data.DataFetcher
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||
import com.bumptech.glide.load.engine.Resource
|
||||
import com.bumptech.glide.load.model.ModelLoader
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapEncoder
|
||||
import com.bumptech.glide.load.resource.bitmap.BitmapResource
|
||||
import com.bumptech.glide.load.resource.bitmap.StreamBitmapDecoder
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable
|
||||
import com.bumptech.glide.load.resource.file.FileToStreamDecoder
|
||||
import com.bumptech.glide.load.resource.transcode.BitmapToGlideDrawableTranscoder
|
||||
import com.bumptech.glide.request.FutureTarget
|
||||
import com.bumptech.glide.request.RequestListener
|
||||
import com.bumptech.glide.request.target.Target
|
||||
import com.fsck.k9.helper.Contacts
|
||||
import com.fsck.k9.mail.Address
|
||||
import com.fsck.k9.view.RecipientSelectView.Recipient
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
public class ContactPictureLoader {
|
||||
/**
|
||||
* Resize the pictures to the following value (device-independent pixels).
|
||||
*/
|
||||
private static final int PICTURE_SIZE = 40;
|
||||
class ContactPictureLoader(
|
||||
private val context: Context,
|
||||
private val contactLetterBitmapCreator: ContactLetterBitmapCreator
|
||||
) {
|
||||
private val contactsHelper: Contacts = Contacts.getInstance(context)
|
||||
private val pictureSizeInPx: Int = PICTURE_SIZE.toDip(context)
|
||||
|
||||
|
||||
private final Context context;
|
||||
private final ContactLetterBitmapCreator contactLetterBitmapCreator;
|
||||
private Contacts mContactsHelper;
|
||||
private int mPictureSizeInPx;
|
||||
|
||||
|
||||
public ContactPictureLoader(Context context, ContactLetterBitmapCreator contactLetterBitmapCreator) {
|
||||
this.context = context.getApplicationContext();
|
||||
this.contactLetterBitmapCreator = contactLetterBitmapCreator;
|
||||
mContactsHelper = Contacts.getInstance(this.context);
|
||||
|
||||
Resources resources = context.getResources();
|
||||
float scale = resources.getDisplayMetrics().density;
|
||||
mPictureSizeInPx = (int) (PICTURE_SIZE * scale);
|
||||
fun loadContactPicture(address: Address, imageView: ImageView) {
|
||||
val photoUri = contactsHelper.getPhotoUri(address.address)
|
||||
loadContactPicture(photoUri, address, imageView)
|
||||
}
|
||||
|
||||
public void loadContactPicture(final Address address, final ImageView imageView) {
|
||||
Uri photoUri = mContactsHelper.getPhotoUri(address.getAddress());
|
||||
loadContactPicture(photoUri, address, imageView);
|
||||
fun loadContactPicture(recipient: Recipient, imageView: ImageView) {
|
||||
loadContactPicture(recipient.photoThumbnailUri, recipient.address, imageView)
|
||||
}
|
||||
|
||||
public void loadContactPicture(Recipient recipient, ImageView imageView) {
|
||||
loadContactPicture(recipient.photoThumbnailUri, recipient.address, imageView);
|
||||
}
|
||||
|
||||
private void loadFallbackPicture(Address address, ImageView imageView) {
|
||||
Context context = imageView.getContext();
|
||||
private fun loadFallbackPicture(address: Address, imageView: ImageView) {
|
||||
val context = imageView.context
|
||||
|
||||
Glide.with(context)
|
||||
.using(new FallbackGlideModelLoader(), FallbackGlideParams.class)
|
||||
.from(FallbackGlideParams.class)
|
||||
.as(Bitmap.class)
|
||||
.transcode(new BitmapToGlideDrawableTranscoder(context), GlideDrawable.class)
|
||||
.decoder(new FallbackGlideBitmapDecoder(context))
|
||||
.encoder(new BitmapEncoder(Bitmap.CompressFormat.PNG, 0))
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new StreamBitmapDecoder(context)))
|
||||
.using(FallbackGlideModelLoader(), FallbackGlideParams::class.java)
|
||||
.from(FallbackGlideParams::class.java)
|
||||
.`as`(Bitmap::class.java)
|
||||
.transcode(BitmapToGlideDrawableTranscoder(context), GlideDrawable::class.java)
|
||||
.decoder(FallbackGlideBitmapDecoder())
|
||||
.encoder(BitmapEncoder(Bitmap.CompressFormat.PNG, 0))
|
||||
.cacheDecoder(FileToStreamDecoder(StreamBitmapDecoder(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(new FallbackGlideParams(address))
|
||||
.load(FallbackGlideParams(address))
|
||||
// for some reason, following 2 lines fix loading issues.
|
||||
.dontAnimate()
|
||||
.override(mPictureSizeInPx, mPictureSizeInPx)
|
||||
.into(imageView);
|
||||
.override(pictureSizeInPx, pictureSizeInPx)
|
||||
.into(imageView)
|
||||
}
|
||||
|
||||
private void loadContactPicture(Uri photoUri, final Address address, final ImageView imageView) {
|
||||
private fun loadContactPicture(photoUri: Uri?, address: Address, imageView: ImageView) {
|
||||
if (photoUri != null) {
|
||||
RequestListener<Uri, GlideDrawable> noPhotoListener = new RequestListener<Uri, GlideDrawable>() {
|
||||
@Override
|
||||
public boolean onException(Exception e, Uri model, Target<GlideDrawable> target,
|
||||
boolean isFirstResource) {
|
||||
loadFallbackPicture(address, imageView);
|
||||
return true;
|
||||
val noPhotoListener = object : RequestListener<Uri, GlideDrawable> {
|
||||
override fun onException(
|
||||
e: Exception,
|
||||
model: Uri,
|
||||
target: Target<GlideDrawable>,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
loadFallbackPicture(address, imageView)
|
||||
return true
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onResourceReady(GlideDrawable resource, Uri model,
|
||||
Target<GlideDrawable> target,
|
||||
boolean isFromMemoryCache, boolean isFirstResource) {
|
||||
return false;
|
||||
override fun onResourceReady(
|
||||
resource: GlideDrawable,
|
||||
model: Uri,
|
||||
target: Target<GlideDrawable>,
|
||||
isFromMemoryCache: Boolean,
|
||||
isFirstResource: Boolean
|
||||
): Boolean {
|
||||
return false
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Glide.with(imageView.getContext())
|
||||
Glide.with(imageView.context)
|
||||
.load(photoUri)
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.listener(noPhotoListener)
|
||||
// for some reason, following 2 lines fix loading issues.
|
||||
.dontAnimate()
|
||||
.override(mPictureSizeInPx, mPictureSizeInPx)
|
||||
.into(imageView);
|
||||
.override(pictureSizeInPx, pictureSizeInPx)
|
||||
.into(imageView)
|
||||
} else {
|
||||
loadFallbackPicture(address, imageView);
|
||||
loadFallbackPicture(address, imageView)
|
||||
}
|
||||
}
|
||||
|
||||
public Bitmap loadContactPictureIcon(Recipient recipient) {
|
||||
return loadContactPicture(recipient.photoThumbnailUri, recipient.address);
|
||||
fun loadContactPictureIcon(recipient: Recipient): Bitmap? {
|
||||
return loadContactPicture(recipient.photoThumbnailUri, recipient.address)
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
private Bitmap loadContactPicture(Uri photoUri, Address address) {
|
||||
FutureTarget<Bitmap> bitmapTarget;
|
||||
private fun loadContactPicture(photoUri: Uri?, address: Address): Bitmap? {
|
||||
val bitmapTarget: FutureTarget<Bitmap>
|
||||
if (photoUri != null) {
|
||||
bitmapTarget = Glide.with(context)
|
||||
.load(photoUri)
|
||||
.asBitmap()
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.dontAnimate()
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx);
|
||||
.into(pictureSizeInPx, pictureSizeInPx)
|
||||
} else {
|
||||
bitmapTarget = Glide.with(context)
|
||||
.using(new FallbackGlideModelLoader(), FallbackGlideParams.class)
|
||||
.from(FallbackGlideParams.class)
|
||||
.as(Bitmap.class)
|
||||
.decoder(new FallbackGlideBitmapDecoder(context))
|
||||
.encoder(new BitmapEncoder(CompressFormat.PNG, 0))
|
||||
.cacheDecoder(new FileToStreamDecoder<>(new StreamBitmapDecoder(context)))
|
||||
.using(FallbackGlideModelLoader(), FallbackGlideParams::class.java)
|
||||
.from(FallbackGlideParams::class.java)
|
||||
.`as`(Bitmap::class.java)
|
||||
.decoder(FallbackGlideBitmapDecoder())
|
||||
.encoder(BitmapEncoder(CompressFormat.PNG, 0))
|
||||
.cacheDecoder(FileToStreamDecoder(StreamBitmapDecoder(context)))
|
||||
.diskCacheStrategy(DiskCacheStrategy.NONE)
|
||||
.load(new FallbackGlideParams(address))
|
||||
.load(FallbackGlideParams(address))
|
||||
.dontAnimate()
|
||||
.into(mPictureSizeInPx, mPictureSizeInPx);
|
||||
.into(pictureSizeInPx, pictureSizeInPx)
|
||||
}
|
||||
|
||||
return loadIgnoringErors(bitmapTarget);
|
||||
return loadIgnoringErrors(bitmapTarget)
|
||||
}
|
||||
|
||||
private class FallbackGlideBitmapDecoder implements ResourceDecoder<FallbackGlideParams, Bitmap> {
|
||||
private final Context context;
|
||||
private inner class FallbackGlideBitmapDecoder : ResourceDecoder<FallbackGlideParams, Bitmap> {
|
||||
override fun decode(source: FallbackGlideParams, width: Int, height: Int): Resource<Bitmap> {
|
||||
val pool = Glide.get(context).bitmapPool
|
||||
val bitmap: Bitmap =
|
||||
pool.getDirty(pictureSizeInPx, pictureSizeInPx, Bitmap.Config.ARGB_8888) ?:
|
||||
Bitmap.createBitmap(pictureSizeInPx, pictureSizeInPx, Bitmap.Config.ARGB_8888)
|
||||
|
||||
FallbackGlideBitmapDecoder(Context context) {
|
||||
this.context = context;
|
||||
contactLetterBitmapCreator.drawBitmap(bitmap, pictureSizeInPx, source.address)
|
||||
|
||||
return BitmapResource.obtain(bitmap, pool)
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource<Bitmap> decode(FallbackGlideParams source, int width, int height) throws IOException {
|
||||
BitmapPool pool = Glide.get(context).getBitmapPool();
|
||||
Bitmap bitmap = pool.getDirty(mPictureSizeInPx, mPictureSizeInPx, Bitmap.Config.ARGB_8888);
|
||||
if (bitmap == null) {
|
||||
bitmap = Bitmap.createBitmap(mPictureSizeInPx, mPictureSizeInPx, Bitmap.Config.ARGB_8888);
|
||||
}
|
||||
|
||||
Address address = source.address;
|
||||
contactLetterBitmapCreator.drawBitmap(bitmap, mPictureSizeInPx, address);
|
||||
return BitmapResource.obtain(bitmap, pool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return "fallback-photo";
|
||||
override fun getId(): String {
|
||||
return "fallback-photo"
|
||||
}
|
||||
}
|
||||
|
||||
private class FallbackGlideParams {
|
||||
final Address address;
|
||||
|
||||
FallbackGlideParams(Address address) {
|
||||
this.address = address;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return String.format(Locale.ROOT, "%s-%s", address.getAddress(), address.getPersonal());
|
||||
}
|
||||
private inner class FallbackGlideParams(val address: Address) {
|
||||
val id: String
|
||||
get() = String.format(Locale.ROOT, "%s-%s", address.address, address.personal)
|
||||
}
|
||||
|
||||
private class FallbackGlideModelLoader implements ModelLoader<FallbackGlideParams, FallbackGlideParams> {
|
||||
@Override
|
||||
public DataFetcher<FallbackGlideParams> getResourceFetcher(final FallbackGlideParams model, int width,
|
||||
int height) {
|
||||
|
||||
return new DataFetcher<FallbackGlideParams>() {
|
||||
|
||||
@Override
|
||||
public FallbackGlideParams loadData(Priority priority) throws Exception {
|
||||
return model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanup() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return model.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
|
||||
}
|
||||
};
|
||||
private inner class FallbackGlideModelLoader : ModelLoader<FallbackGlideParams, FallbackGlideParams> {
|
||||
override fun getResourceFetcher(
|
||||
model: FallbackGlideParams,
|
||||
width: Int,
|
||||
height: Int
|
||||
): DataFetcher<FallbackGlideParams> = object : DataFetcher<FallbackGlideParams> {
|
||||
override fun loadData(priority: Priority): FallbackGlideParams = model
|
||||
override fun getId(): String = model.id
|
||||
override fun cleanup() = Unit
|
||||
override fun cancel() = Unit
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@Nullable
|
||||
private <T> T loadIgnoringErors(FutureTarget<T> target) {
|
||||
try {
|
||||
return target.get();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
private fun <T> loadIgnoringErrors(target: FutureTarget<T>): T? {
|
||||
return try {
|
||||
target.get()
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun Int.toDip(context: Context): Int = (this * context.resources.displayMetrics.density).toInt()
|
||||
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Resize the pictures to the following value (device-independent pixels).
|
||||
*/
|
||||
private const val PICTURE_SIZE = 40
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue