Browse Source

Trying to generalize avatar setting.

Bartosz Przybylski 8 years ago
parent
commit
54f7e64414

+ 30 - 54
src/com/owncloud/android/datamodel/ThumbnailsCacheManager.java

@@ -29,6 +29,7 @@ import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.drawable.BitmapDrawable;
 import android.graphics.drawable.Drawable;
+import android.media.Image;
 import android.media.ThumbnailUtils;
 import android.net.Uri;
 import android.os.AsyncTask;
@@ -45,6 +46,8 @@ import com.owncloud.android.lib.common.utils.Log_OC;
 import com.owncloud.android.lib.resources.status.OwnCloudVersion;
 import com.owncloud.android.ui.adapter.DiskLruImageCache;
 import com.owncloud.android.utils.BitmapUtils;
+import com.owncloud.android.utils.DisplayUtils;
+import com.owncloud.android.utils.DisplayUtils.AvatarGenerationListener;
 
 import org.apache.commons.httpclient.HttpStatus;
 import org.apache.commons.httpclient.methods.GetMethod;
@@ -361,38 +364,21 @@ public class ThumbnailsCacheManager {
     }
 
     public static class AvatarGenerationTask extends AsyncTask<Object, Void, Bitmap> {
-        private final WeakReference<ImageView> mImageViewReference;
-        private final WeakReference<MenuItem> mMenuItemReference;
+        private final WeakReference<AvatarGenerationListener> mAvatarGenerationListener;
+        private final Object mCallContext;
         private Account mAccount;
         private Object mUsername;
 
 
-        public AvatarGenerationTask(ImageView imageView, FileDataStorageManager storageManager,
-                                       Account account) {
-            // Use a WeakReference to ensure the ImageView can be garbage collected
-            mMenuItemReference = null;
-            mImageViewReference = new WeakReference<ImageView>(imageView);
+        public AvatarGenerationTask(AvatarGenerationListener avatarGenerationListener, Object callContext,
+                                    FileDataStorageManager storageManager, Account account) {
+            mAvatarGenerationListener = new WeakReference<>(avatarGenerationListener);
+            mCallContext = callContext;
             if (storageManager == null)
                 throw new IllegalArgumentException("storageManager must not be NULL");
             mAccount = account;
         }
 
-        public AvatarGenerationTask(MenuItem menuItem, FileDataStorageManager storageManager,
-                                    Account account) {
-            // Use a WeakReference to ensure the ImageView can be garbage collected
-            mImageViewReference = null;
-            mMenuItemReference = new WeakReference<MenuItem>(menuItem);
-            if (storageManager == null)
-                throw new IllegalArgumentException("storageManager must not be NULL");
-            mAccount = account;
-        }
-
-        public AvatarGenerationTask(ImageView imageView) {
-            // Use a WeakReference to ensure the ImageView can be garbage collected
-            mMenuItemReference = null;
-            mImageViewReference = new WeakReference<ImageView>(imageView);
-        }
-
         @Override
         protected Bitmap doInBackground(Object... params) {
             Bitmap thumbnail = null;
@@ -424,28 +410,15 @@ public class ThumbnailsCacheManager {
 
         protected void onPostExecute(Bitmap bitmap) {
             if (bitmap != null) {
-                if (mImageViewReference != null) {
-                    ImageView imageView = mImageViewReference.get();
-                    AvatarGenerationTask avatarWorkerTask = getAvatarWorkerTask(imageView);
-                    if (this == avatarWorkerTask) {
-                        String tagId = "";
-                        if (mUsername instanceof String) {
-                            tagId = (String) mUsername;
-                            if (String.valueOf(imageView.getTag()).equals(tagId)) {
-                                imageView.setImageBitmap(bitmap);
-                            }
-                        }
-                    }
-                } else {
-                    MenuItem menuItem = mMenuItemReference.get();
-                    AvatarGenerationTask avatarWorkerTask = getAvatarWorkerTask(menuItem);
+                if (mAvatarGenerationListener != null) {
+                    AvatarGenerationListener listener = mAvatarGenerationListener.get();
+                    AvatarGenerationTask avatarWorkerTask = getAvatarWorkerTask(mCallContext);
                     if (this == avatarWorkerTask) {
                         String tagId = "";
                         if (mUsername instanceof String) {
                             tagId = (String) mUsername;
-                            if (String.valueOf(menuItem.getTitle()).equals(tagId)) {
-                                menuItem.setIcon(new BitmapDrawable(MainApp.getAppContext().getResources(),
-                                        bitmap));
+                            if (listener.shouldCallGeneratedCallback(tagId, mCallContext)) {
+                                listener.avatarGenerated(new BitmapDrawable(bitmap), mCallContext);
                             }
                         }
                     }
@@ -592,6 +565,15 @@ public class ThumbnailsCacheManager {
         return true;
     }
 
+    public static boolean cancelPotentialAvatarWork(Object file, Object callContext) {
+        if (callContext instanceof ImageView)
+            return cancelPotentialAvatarWork(file, (ImageView)callContext);
+        else if (callContext instanceof MenuItem)
+            return cancelPotentialAvatarWork(file, (MenuItem)callContext);
+
+        return false;
+    }
+
     public static boolean cancelPotentialAvatarWork(Object file, ImageView imageView) {
         final AvatarGenerationTask avatarWorkerTask = getAvatarWorkerTask(imageView);
 
@@ -641,21 +623,16 @@ public class ThumbnailsCacheManager {
         return null;
     }
 
-    public static AvatarGenerationTask getAvatarWorkerTask(ImageView imageView) {
-        if (imageView != null) {
-            return getAvatarWorkerTask(imageView.getDrawable());
-        }
-        return null;
-    }
+    public static AvatarGenerationTask getAvatarWorkerTask(Object callContext) {
+        if (callContext instanceof ImageView)
+            return getAvatarWorkerTask(((ImageView)callContext).getDrawable());
+        else if (callContext instanceof MenuItem)
+            return getAvatarWorkerTask(((MenuItem)callContext).getIcon());
 
-    public static AvatarGenerationTask getAvatarWorkerTask(MenuItem menuItem) {
-        if (menuItem != null) {
-            return getAvatarWorkerTask(menuItem.getIcon());
-        }
         return null;
     }
 
-    public static AvatarGenerationTask getAvatarWorkerTask(Drawable drawable) {
+    private static AvatarGenerationTask getAvatarWorkerTask(Drawable drawable) {
         if (drawable instanceof AsyncAvatarDrawable) {
             final AsyncAvatarDrawable asyncDrawable = (AsyncAvatarDrawable) drawable;
             return asyncDrawable.getAvatarWorkerTask();
@@ -671,8 +648,7 @@ public class ThumbnailsCacheManager {
         ) {
 
             super(res, bitmap);
-            bitmapWorkerTaskReference =
-                    new WeakReference<ThumbnailGenerationTask>(bitmapWorkerTask);
+            bitmapWorkerTaskReference = new WeakReference<>(bitmapWorkerTask);
         }
 
         public ThumbnailGenerationTask getBitmapWorkerTask() {

+ 36 - 63
src/com/owncloud/android/ui/activity/DrawerActivity.java

@@ -25,6 +25,8 @@ import android.accounts.AccountManagerFuture;
 import android.content.Intent;
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.drawable.Drawable;
+import android.media.Image;
 import android.os.Build;
 import android.os.Bundle;
 import android.support.design.widget.NavigationView;
@@ -51,7 +53,7 @@ import com.owncloud.android.utils.DisplayUtils;
  * Base class to handle setup of the drawer implementation including user switching and avatar fetching and fallback
  * generation.
  */
-public abstract class DrawerActivity extends ToolbarActivity {
+public abstract class DrawerActivity extends ToolbarActivity implements DisplayUtils.AvatarGenerationListener {
     private static final String TAG = DrawerActivity.class.getSimpleName();
     private static final String KEY_IS_ACCOUNT_CHOOSER_ACTIVE = "IS_ACCOUNT_CHOOSER_ACTIVE";
     private static final String KEY_CHECKED_MENU_ITEM = "CHECKED_MENU_ITEM";
@@ -341,9 +343,9 @@ public abstract class DrawerActivity extends ToolbarActivity {
 
                 // activate second/end account avatar
                 if (mAvatars[1] != null) {
-                    DisplayUtils.setAvatar(mAvatars[1],
-                            (ImageView) findNavigationViewChildById(R.id.drawer_account_end),
-                            mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager());
+                    DisplayUtils.setAvatar(mAvatars[1], this,
+                            mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager(),
+                            findNavigationViewChildById(R.id.drawer_account_end));
                     mAccountEndAccountAvatar.setVisibility(View.VISIBLE);
                 } else {
                     mAccountEndAccountAvatar.setVisibility(View.GONE);
@@ -351,9 +353,9 @@ public abstract class DrawerActivity extends ToolbarActivity {
 
                 // activate third/middle account avatar
                 if (mAvatars[2] != null) {
-                    DisplayUtils.setAvatar(mAvatars[2],
-                            (ImageView) findNavigationViewChildById(R.id.drawer_account_middle),
-                            mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager());
+                    DisplayUtils.setAvatar(mAvatars[2], this,
+                            mOtherAccountAvatarRadiusDimension, getResources(), getStorageManager(),
+                            findNavigationViewChildById(R.id.drawer_account_middle));
                     mAccountMiddleAccountAvatar.setVisibility(View.VISIBLE);
                 } else {
                     mAccountMiddleAccountAvatar.setVisibility(View.GONE);
@@ -386,7 +388,7 @@ public abstract class DrawerActivity extends ToolbarActivity {
                                 accounts[i].name,
                                 mMenuAccountAvatarRadiusDimension)
                         );
-                setAvatar(accounts[i], accountMenuItem);
+                DisplayUtils.setAvatar(accounts[i], this, mMenuAccountAvatarRadiusDimension, getResources(), getStorageManager(), accountMenuItem);
             } catch (Exception e) {
                 Log_OC.e(TAG, "Error calculating RGB value for account menu item.", e);
                 mNavigationView.getMenu().add(
@@ -442,61 +444,9 @@ public abstract class DrawerActivity extends ToolbarActivity {
             usernameFull.setText(account.name);
             username.setText(AccountUtils.getAccountUsername(account.name));
 
-            DisplayUtils.setAvatar(account, (ImageView) findNavigationViewChildById(R.id.drawer_current_account),
-                    mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager());
-        }
-    }
-
-    /**
-     * fetches and sets the avatar of the current account in the drawer in case the drawer is available.
-     *
-     * @param account        the account to be set in the drawer
-     * @param menuItem       the menuItem to set the avatar on
-     */
-    private void setAvatar(Account account, MenuItem menuItem) {
-        if (mDrawerLayout != null && account != null) {
-
-            // Thumbnail in Cache?
-            Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache("a_" + account.name);
-
-            if (thumbnail != null) {
-                menuItem.setIcon(
-                        BitmapUtils.bitmapToCircularBitmapDrawable(MainApp.getAppContext().getResources(), thumbnail)
-                );
-            } else {
-                // generate new avatar
-                if (ThumbnailsCacheManager.cancelPotentialAvatarWork(account.name, menuItem)) {
-                    final ThumbnailsCacheManager.AvatarGenerationTask task =
-                            new ThumbnailsCacheManager.AvatarGenerationTask(
-                                    menuItem, getStorageManager(), account
-                            );
-                    if (thumbnail == null) {
-                        try {
-                                menuItem.setIcon(
-                                        TextDrawable.createAvatar(
-                                                account.name,
-                                                mMenuAccountAvatarRadiusDimension
-                                        )
-                                );
-                        } catch (Exception e) {
-                            Log_OC.e(TAG, "Error calculating RGB value for active account icon.", e);
-                            menuItem.setIcon(R.drawable.ic_account_circle);
-                        }
-                    } else {
-                        final ThumbnailsCacheManager.AsyncAvatarDrawable asyncDrawable =
-                                new ThumbnailsCacheManager.AsyncAvatarDrawable(
-                                        getResources(),
-                                        thumbnail,
-                                        task
-                                );
-                        menuItem.setIcon(
-                                BitmapUtils.bitmapToCircularBitmapDrawable(
-                                        MainApp.getAppContext().getResources(), asyncDrawable.getBitmap())
-                        );
-                    }
-                    task.execute(account.name);
-                }
-            }
+            DisplayUtils.setAvatar(account, this,
+                    mCurrentAccountAvatarRadiusDimension, getResources(), getStorageManager(),
+                    findNavigationViewChildById(R.id.drawer_current_account));
         }
     }
 
@@ -679,4 +629,27 @@ public abstract class DrawerActivity extends ToolbarActivity {
             }
         }
     }
+
+    @Override
+    public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
+        if (callContext instanceof MenuItem) {
+            MenuItem mi = (MenuItem)callContext;
+            mi.setIcon(avatarDrawable);
+        } else if (callContext instanceof ImageView) {
+            ImageView iv = (ImageView)callContext;
+            iv.setImageDrawable(avatarDrawable);
+        }
+    }
+
+    @Override
+    public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
+        if (callContext instanceof MenuItem) {
+            MenuItem mi = (MenuItem)callContext;
+            return String.valueOf(mi.getTitle()).equals(tag);
+        } else if (callContext instanceof ImageView) {
+            ImageView iv = (ImageView)callContext;
+            return String.valueOf(iv.getTag()).equals(tag);
+        }
+        return false;
+    }
 }

+ 14 - 3
src/com/owncloud/android/ui/adapter/AccountListAdapter.java

@@ -21,6 +21,7 @@ package com.owncloud.android.ui.adapter;
 
 import android.accounts.Account;
 import android.content.Context;
+import android.graphics.drawable.Drawable;
 import android.view.Display;
 import android.view.LayoutInflater;
 import android.view.View;
@@ -41,7 +42,7 @@ import java.util.List;
 /**
  * This Adapter populates a ListView with all accounts within the app.
  */
-public class AccountListAdapter extends ArrayAdapter<AccountListItem> {
+public class AccountListAdapter extends ArrayAdapter<AccountListItem> implements DisplayUtils.AvatarGenerationListener {
     private static final String TAG = AccountListAdapter.class.getSimpleName();
     private float mAccountAvatarRadiusDimension;
     private final BaseActivity mContext;
@@ -90,8 +91,8 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> {
                 viewHolder.textViewItem.setTag(account.name);
 
                 try {
-                    DisplayUtils.setAvatar(account, viewHolder.imageViewItem, mAccountAvatarRadiusDimension,
-                            mContext.getResources(), mContext.getStorageManager());
+                    DisplayUtils.setAvatar(account, this, mAccountAvatarRadiusDimension,
+                            mContext.getResources(), mContext.getStorageManager(), viewHolder.imageViewItem);
                 } catch (Exception e) {
                     Log_OC.e(TAG, "Error calculating RGB value for account list item.", e);
                     // use user icon as a fallback
@@ -137,6 +138,16 @@ public class AccountListAdapter extends ArrayAdapter<AccountListItem> {
         return convertView;
     }
 
+    @Override
+    public void avatarGenerated(Drawable avatarDrawable, Object callContext) {
+        ((ImageView)callContext).setImageDrawable(avatarDrawable);
+    }
+
+    @Override
+    public boolean shouldCallGeneratedCallback(String tag, Object callContext) {
+        return String.valueOf(((ImageView)callContext).getTag()).equals(tag);
+    }
+
     /**
      * Listener interface for Activities using the {@link AccountListAdapter}
      */

+ 19 - 16
src/com/owncloud/android/utils/DisplayUtils.java

@@ -30,6 +30,7 @@ import android.content.res.Resources;
 import android.graphics.Bitmap;
 import android.graphics.Point;
 import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
 import android.os.Build;
 import android.support.design.widget.Snackbar;
 import android.support.v4.content.ContextCompat;
@@ -288,47 +289,49 @@ public class DisplayUtils {
         snackbar.setActionTextColor(ContextCompat.getColor(context, R.color.white));
     }
 
+    public interface AvatarGenerationListener {
+        void avatarGenerated(Drawable avatarDrawable, Object callContext);
+        boolean shouldCallGeneratedCallback(String tag, Object callContext);
+    }
+
     /**
      * fetches and sets the avatar of the current account in the drawer in case the drawer is available.
      *
      * @param account        the account to be set in the drawer
-     * @param userIcon       the image view to set the avatar on
      * @param avatarRadius   the avatar radius
      * @param resources      reference for density information
      * @param storageManager reference for caching purposes
      */
-    public static void setAvatar(Account account, ImageView userIcon, float avatarRadius, Resources resources,
-                           FileDataStorageManager storageManager) {
+    public static void setAvatar(Account account, AvatarGenerationListener listener, float avatarRadius, Resources resources,
+                           FileDataStorageManager storageManager, Object callContext) {
         if (account != null) {
-
-            userIcon.setContentDescription(account.name);
+            if (callContext instanceof View)
+                ((View)callContext).setContentDescription(account.name);
 
             // Thumbnail in Cache?
             Bitmap thumbnail = ThumbnailsCacheManager.getBitmapFromDiskCache("a_" + account.name);
 
             if (thumbnail != null) {
-                userIcon.setImageDrawable(
-                        BitmapUtils.bitmapToCircularBitmapDrawable(MainApp.getAppContext().getResources(), thumbnail)
-                );
+                listener.avatarGenerated(
+                        BitmapUtils.bitmapToCircularBitmapDrawable(MainApp.getAppContext().getResources(), thumbnail),
+                        callContext);
             } else {
                 // generate new avatar
-                if (ThumbnailsCacheManager.cancelPotentialAvatarWork(account.name, userIcon)) {
+                if (ThumbnailsCacheManager.cancelPotentialAvatarWork(account.name, callContext)) {
                     final ThumbnailsCacheManager.AvatarGenerationTask task =
-                            new ThumbnailsCacheManager.AvatarGenerationTask(userIcon, storageManager, account);
+                            new ThumbnailsCacheManager.AvatarGenerationTask(listener, callContext, storageManager, account);
                     if (thumbnail == null) {
                         try {
-                            userIcon.setImageDrawable(TextDrawable.createAvatar(account.name, avatarRadius));
+                            listener.avatarGenerated(TextDrawable.createAvatar(account.name, avatarRadius), callContext);
                         } catch (Exception e) {
                             Log_OC.e(TAG, "Error calculating RGB value for active account icon.", e);
-                            userIcon.setImageResource(R.drawable.ic_account_circle);
+                            listener.avatarGenerated(resources.getDrawable(R.drawable.ic_account_circle), callContext);
                         }
                     } else {
                         final ThumbnailsCacheManager.AsyncAvatarDrawable asyncDrawable =
                                 new ThumbnailsCacheManager.AsyncAvatarDrawable(resources, thumbnail, task);
-                        userIcon.setImageDrawable(
-                                BitmapUtils.bitmapToCircularBitmapDrawable(
-                                        MainApp.getAppContext().getResources(), asyncDrawable.getBitmap())
-                        );
+                        listener.avatarGenerated(BitmapUtils.bitmapToCircularBitmapDrawable(
+                                        resources, asyncDrawable.getBitmap()), callContext);
                     }
                     task.execute(account.name);
                 }