Fixing different bitmap sizes in different orientations
> Using a single bitmap icon size > Picking up appropriate density for satisfy the required icon size > Fixing some icon size assumptions during icon animations Bug: 19514688 Change-Id: Ia7a1d0d2c03a9d39ccc241fa4ae3eb8a0f374585
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="app_icon_size">64dp</dimen>
|
||||
|
||||
<!-- All Apps -->
|
||||
<dimen name="all_apps_container_inset">18dp</dimen>
|
||||
<dimen name="all_apps_grid_view_start_margin">0dp</dimen>
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="app_icon_size">72dp</dimen>
|
||||
|
||||
<!-- All Apps -->
|
||||
<dimen name="all_apps_search_bar_height">54dp</dimen>
|
||||
<dimen name="all_apps_icon_top_bottom_padding">16dp</dimen>
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<dimen name="app_icon_size">48dp</dimen>
|
||||
|
||||
<!-- Dynamic Grid -->
|
||||
<dimen name="dynamic_grid_edge_margin">6dp</dimen>
|
||||
<dimen name="dynamic_grid_search_bar_max_width">500dp</dimen>
|
||||
|
||||
@@ -57,6 +57,7 @@ public class BubbleTextView extends TextView {
|
||||
private static final int DISPLAY_WORKSPACE = 0;
|
||||
private static final int DISPLAY_ALL_APPS = 1;
|
||||
|
||||
private final Launcher mLauncher;
|
||||
private Drawable mIcon;
|
||||
private final Drawable mBackground;
|
||||
private final CheckLongPressHelper mLongPressHelper;
|
||||
@@ -91,8 +92,8 @@ public class BubbleTextView extends TextView {
|
||||
|
||||
public BubbleTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
LauncherAppState app = LauncherAppState.getInstance();
|
||||
DeviceProfile grid = ((Launcher) context).getDeviceProfile();
|
||||
mLauncher = (Launcher) context;
|
||||
DeviceProfile grid = mLauncher.getDeviceProfile();
|
||||
|
||||
TypedArray a = context.obtainStyledAttributes(attrs,
|
||||
R.styleable.BubbleTextView, defStyle, 0);
|
||||
@@ -142,7 +143,7 @@ public class BubbleTextView extends TextView {
|
||||
boolean promiseStateChanged) {
|
||||
Bitmap b = info.getIcon(iconCache);
|
||||
|
||||
FastBitmapDrawable iconDrawable = Utilities.createIconDrawable(b);
|
||||
FastBitmapDrawable iconDrawable = mLauncher.createIconDrawable(b);
|
||||
iconDrawable.setGhostModeEnabled(info.isDisabled != 0);
|
||||
|
||||
setIcon(iconDrawable, mIconSize);
|
||||
@@ -158,7 +159,7 @@ public class BubbleTextView extends TextView {
|
||||
}
|
||||
|
||||
public void applyFromApplicationInfo(AppInfo info) {
|
||||
setIcon(Utilities.createIconDrawable(info.iconBitmap), mIconSize);
|
||||
setIcon(mLauncher.createIconDrawable(info.iconBitmap), mIconSize);
|
||||
setText(info.title);
|
||||
if (info.contentDescription != null) {
|
||||
setContentDescription(info.contentDescription);
|
||||
@@ -171,7 +172,7 @@ public class BubbleTextView extends TextView {
|
||||
}
|
||||
|
||||
public void applyFromPackageItemInfo(PackageItemInfo info) {
|
||||
setIcon(Utilities.createIconDrawable(info.iconBitmap), mIconSize);
|
||||
setIcon(mLauncher.createIconDrawable(info.iconBitmap), mIconSize);
|
||||
setText(info.title);
|
||||
if (info.contentDescription != null) {
|
||||
setContentDescription(info.contentDescription);
|
||||
|
||||
@@ -645,9 +645,10 @@ public class FolderIcon extends FrameLayout implements FolderListener {
|
||||
final Runnable onCompleteRunnable) {
|
||||
final PreviewItemDrawingParams finalParams = computePreviewItemDrawingParams(0, null);
|
||||
|
||||
final float scale0 = 1.0f;
|
||||
final float transX0 = (mAvailableSpaceInPreview - d.getIntrinsicWidth()) / 2;
|
||||
final float transY0 = (mAvailableSpaceInPreview - d.getIntrinsicHeight()) / 2 + getPaddingTop();
|
||||
float iconSize = mLauncher.getDeviceProfile().iconSizePx;
|
||||
final float scale0 = iconSize / d.getIntrinsicWidth() ;
|
||||
final float transX0 = (mAvailableSpaceInPreview - iconSize) / 2;
|
||||
final float transY0 = (mAvailableSpaceInPreview - iconSize) / 2 + getPaddingTop();
|
||||
mAnimParams.drawable = d;
|
||||
|
||||
ValueAnimator va = LauncherAnimUtils.ofFloat(this, 0f, 1.0f);
|
||||
|
||||
@@ -131,7 +131,7 @@ public class Hotseat extends FrameLayout
|
||||
inflater.inflate(R.layout.all_apps_button, mContent, false);
|
||||
Drawable d = context.getResources().getDrawable(R.drawable.all_apps_button_icon);
|
||||
|
||||
Utilities.resizeIconDrawable(d);
|
||||
mLauncher.resizeIconDrawable(d);
|
||||
allAppsButton.setCompoundDrawables(null, d, null, null);
|
||||
|
||||
allAppsButton.setContentDescription(context.getString(R.string.all_apps_button_label));
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.android.launcher3;
|
||||
|
||||
import android.app.ActivityManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
@@ -93,14 +92,11 @@ public class IconCache {
|
||||
@Thunk final Handler mWorkerHandler;
|
||||
|
||||
public IconCache(Context context, InvariantDeviceProfile inv) {
|
||||
ActivityManager activityManager =
|
||||
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
|
||||
mContext = context;
|
||||
mPackageManager = context.getPackageManager();
|
||||
mUserManager = UserManagerCompat.getInstance(mContext);
|
||||
mLauncherApps = LauncherAppsCompat.getInstance(mContext);
|
||||
mIconDpi = activityManager.getLauncherLargeIconDensity();
|
||||
mIconDpi = inv.fillResIconDpi;
|
||||
mIconDb = new IconDB(context);
|
||||
|
||||
mWorkerHandler = new Handler(LauncherModel.getWorkerLooper());
|
||||
@@ -136,10 +132,6 @@ public class IconCache {
|
||||
return getFullResDefaultActivityIcon();
|
||||
}
|
||||
|
||||
public int getFullResIconDpi() {
|
||||
return mIconDpi;
|
||||
}
|
||||
|
||||
public Drawable getFullResIcon(ActivityInfo info) {
|
||||
Resources resources;
|
||||
try {
|
||||
@@ -744,7 +736,7 @@ public class IconCache {
|
||||
}
|
||||
|
||||
private static final class IconDB extends SQLiteOpenHelper {
|
||||
private final static int DB_VERSION = 4;
|
||||
private final static int DB_VERSION = 5;
|
||||
|
||||
private final static String TABLE_NAME = "icons";
|
||||
private final static String COLUMN_ROWID = "rowid";
|
||||
|
||||
@@ -35,6 +35,8 @@ public class InvariantDeviceProfile {
|
||||
// This is a static that we use for the default icon size on a 4/5-inch phone
|
||||
private static float DEFAULT_ICON_SIZE_DP = 60;
|
||||
|
||||
private static final float ICON_SIZE_DEFINED_IN_APP_DP = 48;
|
||||
|
||||
// Constants that affects the interpolation curve between statically defined device profile
|
||||
// buckets.
|
||||
private static float KNEARESTNEIGHBOR = 3;
|
||||
@@ -60,6 +62,8 @@ public class InvariantDeviceProfile {
|
||||
public int numFolderRows;
|
||||
public int numFolderColumns;
|
||||
float iconSize;
|
||||
int iconBitmapSize;
|
||||
int fillResIconDpi;
|
||||
float iconTextSize;
|
||||
|
||||
/**
|
||||
@@ -135,8 +139,10 @@ public class InvariantDeviceProfile {
|
||||
numFolderColumns = closestProfile.numFolderColumns;
|
||||
|
||||
iconSize = interpolatedDeviceProfileOut.iconSize;
|
||||
iconBitmapSize = Utilities.pxFromDp(iconSize, dm);
|
||||
iconTextSize = interpolatedDeviceProfileOut.iconTextSize;
|
||||
hotseatIconSize = interpolatedDeviceProfileOut.hotseatIconSize;
|
||||
fillResIconDpi = getLauncherIconDensity(iconBitmapSize);
|
||||
|
||||
// If the partner customization apk contains any grid overrides, apply them
|
||||
// Supported overrides: numRows, numColumns, iconSize
|
||||
@@ -187,6 +193,29 @@ public class InvariantDeviceProfile {
|
||||
return predefinedDeviceProfiles;
|
||||
}
|
||||
|
||||
private int getLauncherIconDensity(int requiredSize) {
|
||||
// Densities typically defined by an app.
|
||||
int[] densityBuckets = new int[] {
|
||||
DisplayMetrics.DENSITY_LOW,
|
||||
DisplayMetrics.DENSITY_MEDIUM,
|
||||
DisplayMetrics.DENSITY_TV,
|
||||
DisplayMetrics.DENSITY_HIGH,
|
||||
DisplayMetrics.DENSITY_XHIGH,
|
||||
DisplayMetrics.DENSITY_XXHIGH,
|
||||
DisplayMetrics.DENSITY_XXXHIGH
|
||||
};
|
||||
|
||||
int density = DisplayMetrics.DENSITY_XXXHIGH;
|
||||
for (int i = densityBuckets.length - 1; i >= 0; i--) {
|
||||
float expectedSize = ICON_SIZE_DEFINED_IN_APP_DP * densityBuckets[i]
|
||||
/ DisplayMetrics.DENSITY_DEFAULT;
|
||||
if (expectedSize >= requiredSize) {
|
||||
density = densityBuckets[i];
|
||||
}
|
||||
}
|
||||
|
||||
return density;
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply any Partner customization grid overrides.
|
||||
|
||||
@@ -453,9 +453,6 @@ public class Launcher extends Activity
|
||||
app.getInvariantDeviceProfile().landscapeProfile
|
||||
: app.getInvariantDeviceProfile().portraitProfile;
|
||||
|
||||
// TODO: Move this to icon cache.
|
||||
Utilities.setIconSize(mDeviceProfile.iconSizePx);
|
||||
|
||||
// the LauncherApplication should call this, but in case of Instrumentation it might not be present yet
|
||||
mSharedPrefs = getSharedPreferences(LauncherAppState.getSharedPreferencesKey(),
|
||||
Context.MODE_PRIVATE);
|
||||
@@ -4673,6 +4670,23 @@ public class Launcher extends Activity
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a FastBitmapDrawable with the icon, accurately sized.
|
||||
*/
|
||||
public FastBitmapDrawable createIconDrawable(Bitmap icon) {
|
||||
FastBitmapDrawable d = new FastBitmapDrawable(icon);
|
||||
d.setFilterBitmap(true);
|
||||
resizeIconDrawable(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes an icon drawable to the correct icon size.
|
||||
*/
|
||||
public void resizeIconDrawable(Drawable icon) {
|
||||
icon.setBounds(0, 0, mDeviceProfile.iconSizePx, mDeviceProfile.iconSizePx);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out out state for debugging.
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,8 @@ public class LauncherAppWidgetProviderInfo extends AppWidgetProviderInfo {
|
||||
if (isCustomWidget) {
|
||||
return cache.getFullResIcon(provider.getPackageName(), icon);
|
||||
}
|
||||
return super.loadIcon(context, cache.getFullResIconDpi());
|
||||
return super.loadIcon(context,
|
||||
LauncherAppState.getInstance().getInvariantDeviceProfile().fillResIconDpi);
|
||||
}
|
||||
|
||||
public String toString(PackageManager pm) {
|
||||
|
||||
@@ -3114,8 +3114,9 @@ public class LauncherModel extends BroadcastReceiver
|
||||
// Update shortcuts which use iconResource.
|
||||
if ((si.iconResource != null)
|
||||
&& packageSet.contains(si.iconResource.packageName)) {
|
||||
Bitmap icon = Utilities.createIconBitmap(si.iconResource.packageName,
|
||||
si.iconResource.resourceName, mIconCache, context);
|
||||
Bitmap icon = Utilities.createIconBitmap(
|
||||
si.iconResource.packageName,
|
||||
si.iconResource.resourceName, context);
|
||||
if (icon != null) {
|
||||
si.setIcon(icon);
|
||||
si.usingFallbackIcon = false;
|
||||
@@ -3558,7 +3559,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
String resourceName = c.getString(iconResourceIndex);
|
||||
info.customIcon = false;
|
||||
// the resource
|
||||
icon = Utilities.createIconBitmap(packageName, resourceName, mIconCache, context);
|
||||
icon = Utilities.createIconBitmap(packageName, resourceName, context);
|
||||
// the db
|
||||
if (icon == null) {
|
||||
icon = Utilities.createIconBitmap(c, iconIndex, context);
|
||||
@@ -3612,7 +3613,7 @@ public class LauncherModel extends BroadcastReceiver
|
||||
if (extra instanceof ShortcutIconResource) {
|
||||
iconResource = (ShortcutIconResource) extra;
|
||||
icon = Utilities.createIconBitmap(iconResource.packageName,
|
||||
iconResource.resourceName, mIconCache, context);
|
||||
iconResource.resourceName, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
|
||||
// 2) Preload icon in the center
|
||||
// 3) Setup icon in the center and app icon in the top right corner.
|
||||
if (mDisabledForSafeMode) {
|
||||
FastBitmapDrawable disabledIcon = Utilities.createIconDrawable(mIcon);
|
||||
FastBitmapDrawable disabledIcon = mLauncher.createIconDrawable(mIcon);
|
||||
disabledIcon.setGhostModeEnabled(true);
|
||||
mCenterDrawable = disabledIcon;
|
||||
mTopCornerDrawable = null;
|
||||
@@ -134,7 +134,7 @@ public class PendingAppWidgetHostView extends LauncherAppWidgetHostView implemen
|
||||
sPreloaderTheme.applyStyle(R.style.PreloadIcon, true);
|
||||
}
|
||||
|
||||
FastBitmapDrawable drawable = Utilities.createIconDrawable(mIcon);
|
||||
FastBitmapDrawable drawable = mLauncher.createIconDrawable(mIcon);
|
||||
mCenterDrawable = new PreloadIconDrawable(drawable, sPreloaderTheme);
|
||||
mCenterDrawable.setCallback(this);
|
||||
mTopCornerDrawable = null;
|
||||
|
||||
@@ -71,9 +71,6 @@ public final class Utilities {
|
||||
|
||||
private static final String TAG = "Launcher.Utilities";
|
||||
|
||||
private static int sIconWidth = -1;
|
||||
private static int sIconHeight = -1;
|
||||
|
||||
private static final Rect sOldBounds = new Rect();
|
||||
private static final Canvas sCanvas = new Canvas();
|
||||
|
||||
@@ -87,33 +84,16 @@ public final class Utilities {
|
||||
static int sColors[] = { 0xffff0000, 0xff00ff00, 0xff0000ff };
|
||||
static int sColorIndex = 0;
|
||||
|
||||
static int[] sLoc0 = new int[2];
|
||||
static int[] sLoc1 = new int[2];
|
||||
private static final int[] sLoc0 = new int[2];
|
||||
private static final int[] sLoc1 = new int[2];
|
||||
|
||||
// To turn on these properties, type
|
||||
// adb shell setprop log.tag.PROPERTY_NAME [VERBOSE | SUPPRESS]
|
||||
static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
|
||||
public static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
|
||||
private static final String FORCE_ENABLE_ROTATION_PROPERTY = "launcher_force_rotate";
|
||||
private static boolean sForceEnableRotation = isPropertyEnabled(FORCE_ENABLE_ROTATION_PROPERTY);
|
||||
|
||||
public static final String ALLOW_ROTATION_PREFERENCE_KEY = "pref_allowRotation";
|
||||
|
||||
/**
|
||||
* Returns a FastBitmapDrawable with the icon, accurately sized.
|
||||
*/
|
||||
public static FastBitmapDrawable createIconDrawable(Bitmap icon) {
|
||||
FastBitmapDrawable d = new FastBitmapDrawable(icon);
|
||||
d.setFilterBitmap(true);
|
||||
resizeIconDrawable(d);
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resizes an icon drawable to the correct icon size.
|
||||
*/
|
||||
static void resizeIconDrawable(Drawable icon) {
|
||||
icon.setBounds(0, 0, sIconWidth, sIconHeight);
|
||||
}
|
||||
|
||||
public static boolean isPropertyEnabled(String propertyName) {
|
||||
return Log.isLoggable(propertyName, Log.VERBOSE);
|
||||
}
|
||||
@@ -141,7 +121,7 @@ public final class Utilities {
|
||||
return Build.VERSION.SDK_INT >= 22;
|
||||
}
|
||||
|
||||
static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
|
||||
public static Bitmap createIconBitmap(Cursor c, int iconIndex, Context context) {
|
||||
byte[] data = c.getBlob(iconIndex);
|
||||
try {
|
||||
return createIconBitmap(BitmapFactory.decodeByteArray(data, 0, data.length), context);
|
||||
@@ -154,7 +134,7 @@ public final class Utilities {
|
||||
* Returns a bitmap suitable for the all apps view. If the package or the resource do not
|
||||
* exist, it returns null.
|
||||
*/
|
||||
static Bitmap createIconBitmap(String packageName, String resourceName, IconCache cache,
|
||||
public static Bitmap createIconBitmap(String packageName, String resourceName,
|
||||
Context context) {
|
||||
PackageManager packageManager = context.getPackageManager();
|
||||
// the resource
|
||||
@@ -163,7 +143,8 @@ public final class Utilities {
|
||||
if (resources != null) {
|
||||
final int id = resources.getIdentifier(resourceName, null, null);
|
||||
return createIconBitmap(
|
||||
resources.getDrawableForDensity(id, cache.getFullResIconDpi()), context);
|
||||
resources.getDrawableForDensity(id, LauncherAppState.getInstance()
|
||||
.getInvariantDeviceProfile().fillResIconDpi), context);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Icon not found.
|
||||
@@ -171,16 +152,16 @@ public final class Utilities {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getIconBitmapSize() {
|
||||
return LauncherAppState.getInstance().getInvariantDeviceProfile().iconBitmapSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a bitmap which is of the appropriate size to be displayed as an icon
|
||||
*/
|
||||
static Bitmap createIconBitmap(Bitmap icon, Context context) {
|
||||
synchronized (sCanvas) { // we share the statics :-(
|
||||
if (sIconWidth == -1) {
|
||||
initStatics(context);
|
||||
}
|
||||
}
|
||||
if (sIconWidth == icon.getWidth() && sIconHeight == icon.getHeight()) {
|
||||
public static Bitmap createIconBitmap(Bitmap icon, Context context) {
|
||||
final int iconBitmapSize = getIconBitmapSize();
|
||||
if (iconBitmapSize == icon.getWidth() && iconBitmapSize == icon.getHeight()) {
|
||||
return icon;
|
||||
}
|
||||
return createIconBitmap(new BitmapDrawable(context.getResources(), icon), context);
|
||||
@@ -190,13 +171,11 @@ public final class Utilities {
|
||||
* Returns a bitmap suitable for the all apps view.
|
||||
*/
|
||||
public static Bitmap createIconBitmap(Drawable icon, Context context) {
|
||||
synchronized (sCanvas) { // we share the statics :-(
|
||||
if (sIconWidth == -1) {
|
||||
initStatics(context);
|
||||
}
|
||||
synchronized (sCanvas) {
|
||||
final int iconBitmapSize = getIconBitmapSize();
|
||||
|
||||
int width = sIconWidth;
|
||||
int height = sIconHeight;
|
||||
int width = iconBitmapSize;
|
||||
int height = iconBitmapSize;
|
||||
|
||||
if (icon instanceof PaintDrawable) {
|
||||
PaintDrawable painter = (PaintDrawable) icon;
|
||||
@@ -223,8 +202,8 @@ public final class Utilities {
|
||||
}
|
||||
|
||||
// no intrinsic size --> use default size
|
||||
int textureWidth = sIconWidth;
|
||||
int textureHeight = sIconHeight;
|
||||
int textureWidth = iconBitmapSize;
|
||||
int textureHeight = iconBitmapSize;
|
||||
|
||||
final Bitmap bitmap = Bitmap.createBitmap(textureWidth, textureHeight,
|
||||
Bitmap.Config.ARGB_8888);
|
||||
@@ -354,15 +333,6 @@ public final class Utilities {
|
||||
localY < (v.getHeight() + slop);
|
||||
}
|
||||
|
||||
private static void initStatics(Context context) {
|
||||
final Resources resources = context.getResources();
|
||||
sIconWidth = sIconHeight = (int) resources.getDimension(R.dimen.app_icon_size);
|
||||
}
|
||||
|
||||
public static void setIconSize(int widthPx) {
|
||||
sIconWidth = sIconHeight = widthPx;
|
||||
}
|
||||
|
||||
public static void scaleRect(Rect r, float scale) {
|
||||
if (scale != 1.0f) {
|
||||
r.left = (int) (r.left * scale + 0.5f);
|
||||
|
||||
@@ -241,6 +241,7 @@ public class WidgetsContainerView extends BaseContainerView
|
||||
Drawable icon = mIconCache.getFullResIcon(createShortcutInfo.activityInfo);
|
||||
preview = Utilities.createIconBitmap(icon, mLauncher);
|
||||
createItemInfo.spanX = createItemInfo.spanY = 1;
|
||||
scale = ((float) mLauncher.getDeviceProfile().iconSizePx) / preview.getWidth();
|
||||
}
|
||||
|
||||
// Don't clip alpha values for the drag outline if we're using the default widget preview
|
||||
|
||||
Reference in New Issue
Block a user