*
* @param newOptions The bundle of options, in addition to the size information,
* can be null.
- * @param minWidth The minimum width that the widget will be displayed at.
- * @param minHeight The maximum height that the widget will be displayed at.
- * @param maxWidth The maximum width that the widget will be displayed at.
- * @param maxHeight The maximum height that the widget will be displayed at.
+ * @param minWidth The minimum width in dips that the widget will be displayed at.
+ * @param minHeight The maximum height in dips that the widget will be displayed at.
+ * @param maxWidth The maximum width in dips that the widget will be displayed at.
+ * @param maxHeight The maximum height in dips that the widget will be displayed at.
*
*/
public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth,
int maxHeight) {
+ updateAppWidgetSize(newOptions, minWidth, minHeight, maxWidth, maxHeight, false);
+ }
+
+ /**
+ * @hide
+ */
+ public void updateAppWidgetSize(Bundle newOptions, int minWidth, int minHeight, int maxWidth,
+ int maxHeight, boolean ignorePadding) {
if (newOptions == null) {
newOptions = new Bundle();
}
int xPaddingDips = (int) ((padding.left + padding.right) / density);
int yPaddingDips = (int) ((padding.top + padding.bottom) / density);
- int newMinWidth = minWidth - xPaddingDips;
- int newMinHeight = minHeight - yPaddingDips;
- int newMaxWidth = maxWidth - xPaddingDips;
- int newMaxHeight = maxHeight - yPaddingDips;
+ int newMinWidth = minWidth - (ignorePadding ? 0 : xPaddingDips);
+ int newMinHeight = minHeight - (ignorePadding ? 0 : yPaddingDips);
+ int newMaxWidth = maxWidth - (ignorePadding ? 0 : xPaddingDips);
+ int newMaxHeight = maxHeight - (ignorePadding ? 0 : yPaddingDips);
AppWidgetManager widgetManager = AppWidgetManager.getInstance(mContext);
private float mBackgroundAlphaMultiplier = 1.0f;
private Drawable mBackgroundDrawable;
private Rect mBackgroundRect = new Rect();
+ private int mLastMeasuredWidth = -1;
+ private int mLastMeasuredHeight = 1;
+
+ // These variables are all needed in order to size things properly before we're actually
+ // measured.
private int mSmallWidgetHeight;
+ private int mSmallFrameHeight;
+ private boolean mWidgetLockedSmall = false;
+ private int mMaxChallengeTop = -1;
+
+ // This will hold the width value before we've actually been measured
+ private int mFrameHeight;
// Multiple callers may try and adjust the alpha of the frame. When a caller shows
// the outlines, we give that caller control, and nobody else can fade them out.
cancelLongPress();
}
- public void setMaxChallengeTop(int top) {
- mSmallWidgetHeight = top - getPaddingTop();
- }
-
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// Watch for longpress events at this level to make sure
}
/**
- * Set the top location of the challenge.
- *
- * @param top The top of the challenge, in _local_ coordinates, or -1 to indicate the challenge
- * is down.
- */
- private void setChallengeTop(int top, boolean updateWidgetSize) {
- // The widget starts below the padding, and extends to the top of the challengs.
- int widgetHeight = top - getPaddingTop();
- int frameHeight = top + getPaddingBottom();
- setFrameHeight(frameHeight);
- if (updateWidgetSize) {
- setWidgetHeight(widgetHeight);
- }
- }
-
- /**
* Depending on whether the security is up, the widget size needs to change
*
* @param height The height of the widget, -1 for full height
}
}
+ public void setMaxChallengeTop(int top) {
+ boolean dirty = mMaxChallengeTop != top;
+ mSmallWidgetHeight = top - getPaddingTop();
+ mSmallFrameHeight = top + getPaddingBottom();
+ if (dirty && mIsSmall) {
+ setWidgetHeight(mSmallWidgetHeight);
+ setFrameHeight(mSmallFrameHeight);
+ } else if (dirty && mWidgetLockedSmall) {
+ setWidgetHeight(mSmallWidgetHeight);
+ }
+ }
+
public boolean isSmall() {
return mIsSmall;
}
public void adjustFrame(int challengeTop) {
- setChallengeTop(challengeTop, false);
+ int frameHeight = challengeTop + getPaddingBottom();
+ setFrameHeight(frameHeight);
}
public void shrinkWidget() {
mIsSmall = true;
- setChallengeTop(mSmallWidgetHeight, true);
+ setWidgetHeight(mSmallWidgetHeight);
+ setFrameHeight(mSmallFrameHeight);
+ }
+
+ public void setWidgetLockedSmall(boolean locked) {
+ setWidgetHeight(mSmallWidgetHeight);
+ mWidgetLockedSmall = locked;
}
public void resetSize() {
mIsSmall = false;
+ if (!mWidgetLockedSmall) {
+ setWidgetHeight(LayoutParams.MATCH_PARENT);
+ }
setFrameHeight(getMeasuredHeight());
- setWidgetHeight(LayoutParams.MATCH_PARENT);
}
public void setFrameHeight(int height) {
- height = Math.min(height, getMeasuredHeight());
- mBackgroundRect.set(0, 0, getMeasuredWidth(), height);
+ mFrameHeight = height;
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(mFrameHeight, getMeasuredHeight()));
invalidate();
}
mGradientColor, 0, Shader.TileMode.CLAMP);
mRightToLeftGradient = new LinearGradient(x1, 0f, x0, 0f,
mGradientColor, 0, Shader.TileMode.CLAMP);
- mBackgroundRect.set(0, 0, w, h);
+
+ if (!mIsSmall) {
+ mFrameHeight = h;
+ }
+
+ mBackgroundRect.set(0, 0, getMeasuredWidth(), Math.min(h, mFrameHeight));
invalidate();
}
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ performAppWidgetSizeCallbacksIfNecessary();
+ }
+
+ private void performAppWidgetSizeCallbacksIfNecessary() {
+ View content = getContent();
+ if (!(content instanceof AppWidgetHostView)) return;
+
+ boolean sizeDirty = content.getMeasuredWidth() != mLastMeasuredWidth ||
+ content.getMeasuredHeight() != mLastMeasuredHeight;
+ if (sizeDirty) {
+
+ }
+
+ AppWidgetHostView awhv = (AppWidgetHostView) content;
+ float density = getResources().getDisplayMetrics().density;
+
+ int width = (int) (content.getMeasuredWidth() / density);
+ int height = (int) (content.getMeasuredHeight() / density);
+ awhv.updateAppWidgetSize(null, width, height, width, height, true);
+ }
+
void setOverScrollAmount(float r, boolean left) {
if (Float.compare(mOverScrollAmount, r) != 0) {
mOverScrollAmount = r;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.TimeInterpolator;
+import android.appwidget.AppWidgetHostView;
+import android.appwidget.AppWidgetProviderInfo;
import android.content.Context;
import android.content.res.Resources;
import android.os.Handler;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnLongClickListener;
+import android.view.ViewGroup;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
-import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.android.internal.R;
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT);
lp.gravity = Gravity.TOP;
+
// The framework adds a default padding to AppWidgetHostView. We don't need this padding
// for the Keyguard, so we override it to be 0.
widget.setPadding(0, 0, 0, 0);
frame.addView(widget, lp);
+
+ // We set whether or not this widget supports vertical resizing.
+ if (widget instanceof AppWidgetHostView) {
+ AppWidgetHostView awhv = (AppWidgetHostView) widget;
+ AppWidgetProviderInfo info = awhv.getAppWidgetInfo();
+ if ((info.resizeMode & AppWidgetProviderInfo.RESIZE_VERTICAL) != 0) {
+ frame.setWidgetLockedSmall(false);
+ } else {
+ // Lock the widget to be small.
+ frame.setWidgetLockedSmall(true);
+ }
+ }
} else {
frame = (KeyguardWidgetFrame) widget;
}
// coordinate relative to our children, hence we subtract the top padding.s
maxChallengeTop = top - getPaddingTop();
challengeShowing = scl.isChallengeShowing();
- }
-
- int count = getChildCount();
- for (int i = 0; i < count; i++) {
- KeyguardWidgetFrame frame = getWidgetPageAt(i);
- frame.setMaxChallengeTop(maxChallengeTop);
- // On the very first measure pass, if the challenge is showing, we need to make sure
- // that the widget on the current page is small.
- if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
- frame.shrinkWidget();
+ int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ KeyguardWidgetFrame frame = getWidgetPageAt(i);
+ frame.setMaxChallengeTop(maxChallengeTop);
+ // On the very first measure pass, if the challenge is showing, we need to make sure
+ // that the widget on the current page is small.
+ if (challengeShowing && i == mCurrentPage && !mHasMeasure) {
+ frame.shrinkWidget();
+ }
}
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ mHasMeasure = true;
}
void animateOutlinesAndSidePages(final boolean show) {