diff options
author | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-09-09 13:19:43 +0200 |
---|---|---|
committer | Dominik Schürmann <dominik@dominikschuermann.de> | 2013-09-09 13:19:43 +0200 |
commit | aae87b894f72a719a850ec32ad6944bd5c743331 (patch) | |
tree | b5a221fcb529c07b309f5bde0563155df28a472c /libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget | |
parent | 5b6880d2e34f4c8a4bfba87b5ce53d3c6727b744 (diff) | |
download | open-keychain-aae87b894f72a719a850ec32ad6944bd5c743331.tar.gz open-keychain-aae87b894f72a719a850ec32ad6944bd5c743331.tar.bz2 open-keychain-aae87b894f72a719a850ec32ad6944bd5c743331.zip |
Update actionbarsherlock from 4.2 to 4.4
Diffstat (limited to 'libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget')
11 files changed, 417 insertions, 306 deletions
diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java index 1d9c68b37..0889825c0 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarContainer.java @@ -18,7 +18,6 @@ package com.actionbarsherlock.internal.widget; import android.content.Context; import android.content.res.TypedArray; -import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -27,7 +26,6 @@ import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; - import com.actionbarsherlock.R; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.internal.nineoldandroids.widget.NineFrameLayout; @@ -65,12 +63,7 @@ public class ActionBarContainer extends NineFrameLayout { //Fix for issue #379 if (mStackedBackground instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { - Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); - Canvas c = new Canvas(bitmap); - mStackedBackground.draw(c); - int color = bitmap.getPixel(0, 0); - bitmap.recycle(); - mStackedBackground = new IcsColorDrawable(color); + mStackedBackground = new IcsColorDrawable((ColorDrawable) mStackedBackground); } if (getId() == R.id.abs__split_action_bar) { diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java index 4636de17f..61e55b0a2 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ActionBarView.java @@ -16,16 +16,14 @@ package com.actionbarsherlock.internal.widget; -import org.xmlpull.v1.XmlPullParser; +import com.actionbarsherlock.internal.ResourcesCompat; import android.app.Activity; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.TypedArray; -import android.content.res.XmlResourceParser; import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Parcel; @@ -49,7 +47,6 @@ import android.widget.TextView; import com.actionbarsherlock.R; import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar.OnNavigationListener; -import com.actionbarsherlock.internal.ActionBarSherlockCompat; import com.actionbarsherlock.internal.view.menu.ActionMenuItem; import com.actionbarsherlock.internal.view.menu.ActionMenuPresenter; import com.actionbarsherlock.internal.view.menu.ActionMenuView; @@ -70,7 +67,6 @@ import static com.actionbarsherlock.internal.ResourcesCompat.getResources_getBoo */ public class ActionBarView extends AbsActionBarView { private static final String TAG = "ActionBarView"; - private static final boolean DEBUG = false; /** * Display options applied by default @@ -190,7 +186,7 @@ public class ActionBarView extends AbsActionBarView { if (context instanceof Activity) { //Even though native methods existed in API 9 and 10 they don't work //so just parse the manifest to look for the logo pre-Honeycomb - final int resId = loadLogoFromManifest((Activity) context); + final int resId = ResourcesCompat.loadLogoFromManifest((Activity) context); if (resId != 0) { mLogo = context.getResources().getDrawable(resId); } @@ -265,85 +261,6 @@ public class ActionBarView extends AbsActionBarView { mHomeLayout.setFocusable(true); } - /** - * Attempt to programmatically load the logo from the manifest file of an - * activity by using an XML pull parser. This should allow us to read the - * logo attribute regardless of the platform it is being run on. - * - * @param activity Activity instance. - * @return Logo resource ID. - */ - private static int loadLogoFromManifest(Activity activity) { - int logo = 0; - try { - final String thisPackage = activity.getClass().getName(); - if (DEBUG) Log.i(TAG, "Parsing AndroidManifest.xml for " + thisPackage); - - final String packageName = activity.getApplicationInfo().packageName; - final AssetManager am = activity.createPackageContext(packageName, 0).getAssets(); - final XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml"); - - int eventType = xml.getEventType(); - while (eventType != XmlPullParser.END_DOCUMENT) { - if (eventType == XmlPullParser.START_TAG) { - String name = xml.getName(); - - if ("application".equals(name)) { - //Check if the <application> has the attribute - if (DEBUG) Log.d(TAG, "Got <application>"); - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - if ("logo".equals(xml.getAttributeName(i))) { - logo = xml.getAttributeResourceValue(i, 0); - break; //out of for loop - } - } - } else if ("activity".equals(name)) { - //Check if the <activity> is us and has the attribute - if (DEBUG) Log.d(TAG, "Got <activity>"); - Integer activityLogo = null; - String activityPackage = null; - boolean isOurActivity = false; - - for (int i = xml.getAttributeCount() - 1; i >= 0; i--) { - if (DEBUG) Log.d(TAG, xml.getAttributeName(i) + ": " + xml.getAttributeValue(i)); - - //We need both uiOptions and name attributes - String attrName = xml.getAttributeName(i); - if ("logo".equals(attrName)) { - activityLogo = xml.getAttributeResourceValue(i, 0); - } else if ("name".equals(attrName)) { - activityPackage = ActionBarSherlockCompat.cleanActivityName(packageName, xml.getAttributeValue(i)); - if (!thisPackage.equals(activityPackage)) { - break; //on to the next - } - isOurActivity = true; - } - - //Make sure we have both attributes before processing - if ((activityLogo != null) && (activityPackage != null)) { - //Our activity, logo specified, override with our value - logo = activityLogo.intValue(); - } - } - if (isOurActivity) { - //If we matched our activity but it had no logo don't - //do any more processing of the manifest - break; - } - } - } - eventType = xml.nextToken(); - } - } catch (Exception e) { - e.printStackTrace(); - } - if (DEBUG) Log.i(TAG, "Returning " + Integer.toHexString(logo)); - return logo; - } - /* * Must be public so we can dispatch pre-2.2 via ActionBarImpl. */ diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java index fa3698f3b..9c658d561 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/CapitalizingButton.java @@ -12,9 +12,14 @@ public class CapitalizingButton extends Button { private static final boolean IS_GINGERBREAD = Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD; private static final int[] R_styleable_Button = new int[] { + android.R.attr.textAppearance + }; + private static final int R_styleable_Button_textAppearance = 0; + + private static final int[] R_styleable_TextAppearance = new int[] { android.R.attr.textAllCaps }; - private static final int R_styleable_Button_textAllCaps = 0; + private static final int R_styleable_TextAppearance_textAllCaps = 0; private boolean mAllCaps; @@ -22,14 +27,26 @@ public class CapitalizingButton extends Button { super(context, attrs); TypedArray a = context.obtainStyledAttributes(attrs, R_styleable_Button); - mAllCaps = a.getBoolean(R_styleable_Button_textAllCaps, true); + int ap = a.getResourceId(R_styleable_Button_textAppearance, -1); a.recycle(); + if (ap != -1) { + TypedArray appearance = context.obtainStyledAttributes(ap, R_styleable_TextAppearance); + if (appearance != null) { + mAllCaps = appearance.getBoolean(R_styleable_TextAppearance_textAllCaps, true); + appearance.recycle(); + } + } } public void setTextCompat(CharSequence text) { if (SANS_ICE_CREAM && mAllCaps && text != null) { if (IS_GINGERBREAD) { - setText(text.toString().toUpperCase(Locale.ROOT)); + try { + setText(text.toString().toUpperCase(Locale.ROOT)); + } catch (NoSuchFieldError e) { + //Some manufacturer broke Locale.ROOT. See #572. + setText(text.toString().toUpperCase()); + } } else { setText(text.toString().toUpperCase()); } diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java deleted file mode 100644 index ad1b4f0a8..000000000 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/FakeDialogPhoneWindow.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.actionbarsherlock.internal.widget; - -import static android.view.View.MeasureSpec.EXACTLY; -import android.content.Context; -import android.content.res.TypedArray; -import android.util.AttributeSet; -import android.util.DisplayMetrics; -import android.util.TypedValue; -import android.widget.LinearLayout; -import com.actionbarsherlock.R; - -public class FakeDialogPhoneWindow extends LinearLayout { - final TypedValue mMinWidthMajor = new TypedValue(); - final TypedValue mMinWidthMinor = new TypedValue(); - - public FakeDialogPhoneWindow(Context context, AttributeSet attrs) { - super(context, attrs); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SherlockTheme); - - a.getValue(R.styleable.SherlockTheme_windowMinWidthMajor, mMinWidthMajor); - a.getValue(R.styleable.SherlockTheme_windowMinWidthMinor, mMinWidthMinor); - - a.recycle(); - } - - /* Stolen from PhoneWindow */ - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - final DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); - final boolean isPortrait = metrics.widthPixels < metrics.heightPixels; - - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - int width = getMeasuredWidth(); - boolean measure = false; - - widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY); - - final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor; - - if (tv.type != TypedValue.TYPE_NULL) { - final int min; - if (tv.type == TypedValue.TYPE_DIMENSION) { - min = (int)tv.getDimension(metrics); - } else if (tv.type == TypedValue.TYPE_FRACTION) { - min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels); - } else { - min = 0; - } - - if (width < min) { - widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY); - measure = true; - } - } - - // TODO: Support height? - - if (measure) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - } - } -} diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java index a78b3f71b..3e022e63a 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsColorDrawable.java @@ -1,8 +1,10 @@ package com.actionbarsherlock.internal.widget; +import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; /** @@ -12,6 +14,14 @@ public class IcsColorDrawable extends Drawable { private int color; private final Paint paint = new Paint(); + public IcsColorDrawable(ColorDrawable drawable) { + Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + Canvas c = new Canvas(bitmap); + drawable.draw(c); + this.color = bitmap.getPixel(0, 0); + bitmap.recycle(); + } + public IcsColorDrawable(int color) { this.color = color; } @@ -26,7 +36,7 @@ public class IcsColorDrawable extends Drawable { @Override public void setAlpha(int alpha) { if (alpha != (color >>> 24)) { - color = (color & 0x00FFFFFF) & (alpha << 24); + color = (color & 0x00FFFFFF) | (alpha << 24); invalidateSelf(); } } diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java index 4947c41df..b7c6ff318 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsLinearLayout.java @@ -3,10 +3,11 @@ package com.actionbarsherlock.internal.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; +import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.util.AttributeSet; import android.view.View; -import android.widget.LinearLayout; import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; @@ -20,14 +21,12 @@ import com.actionbarsherlock.internal.nineoldandroids.widget.NineLinearLayout; public class IcsLinearLayout extends NineLinearLayout { private static final int[] R_styleable_LinearLayout = new int[] { /* 0 */ android.R.attr.divider, - /* 1 */ android.R.attr.measureWithLargestChild, /* 2 */ android.R.attr.showDividers, /* 3 */ android.R.attr.dividerPadding, }; private static final int LinearLayout_divider = 0; - private static final int LinearLayout_measureWithLargestChild = 1; - private static final int LinearLayout_showDividers = 2; - private static final int LinearLayout_dividerPadding = 3; + private static final int LinearLayout_showDividers = 1; + private static final int LinearLayout_dividerPadding = 2; /** * Don't show any dividers. @@ -53,8 +52,6 @@ public class IcsLinearLayout extends NineLinearLayout { private int mShowDividers; private int mDividerPadding; - private boolean mUseLargestChild; - public IcsLinearLayout(Context context, AttributeSet attrs) { super(context, attrs); @@ -63,7 +60,6 @@ public class IcsLinearLayout extends NineLinearLayout { setDividerDrawable(a.getDrawable(/*com.android.internal.R.styleable.*/LinearLayout_divider)); mShowDividers = a.getInt(/*com.android.internal.R.styleable.*/LinearLayout_showDividers, SHOW_DIVIDER_NONE); mDividerPadding = a.getDimensionPixelSize(/*com.android.internal.R.styleable.*/LinearLayout_dividerPadding, 0); - mUseLargestChild = a.getBoolean(/*com.android.internal.R.styleable.*/LinearLayout_measureWithLargestChild, false); a.recycle(); } @@ -100,6 +96,12 @@ public class IcsLinearLayout extends NineLinearLayout { if (divider == mDivider) { return; } + + //Fix for issue #379 + if (divider instanceof ColorDrawable && Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { + divider = new IcsColorDrawable((ColorDrawable) divider); + } + mDivider = divider; if (divider != null) { mDividerWidth = divider.getIntrinsicWidth(); @@ -275,136 +277,4 @@ public class IcsLinearLayout extends NineLinearLayout { } return false; } - - /** - * When true, all children with a weight will be considered having - * the minimum size of the largest child. If false, all children are - * measured normally. - * - * @return True to measure children with a weight using the minimum - * size of the largest child, false otherwise. - * - * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild - */ - public boolean isMeasureWithLargestChildEnabled() { - return mUseLargestChild; - } - - /** - * When set to true, all children with a weight will be considered having - * the minimum size of the largest child. If false, all children are - * measured normally. - * - * Disabled by default. - * - * @param enabled True to measure children with a weight using the - * minimum size of the largest child, false otherwise. - * - * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild - */ - public void setMeasureWithLargestChildEnabled(boolean enabled) { - mUseLargestChild = enabled; - } - - @Override - protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - - if (mUseLargestChild) { - final int orientation = getOrientation(); - switch (orientation) { - case HORIZONTAL: - useLargestChildHorizontal(); - break; - - case VERTICAL: - useLargestChildVertical(); - break; - } - } - } - - private void useLargestChildHorizontal() { - final int childCount = getChildCount(); - - // Find largest child width - int largestChildWidth = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - largestChildWidth = Math.max(child.getMeasuredWidth(), largestChildWidth); - } - - int totalWidth = 0; - // Re-measure childs - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - - if (child == null || child.getVisibility() == View.GONE) { - continue; - } - - final LinearLayout.LayoutParams lp = - (LinearLayout.LayoutParams) child.getLayoutParams(); - - float childExtra = lp.weight; - if (childExtra > 0) { - child.measure( - MeasureSpec.makeMeasureSpec(largestChildWidth, - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), - MeasureSpec.EXACTLY)); - totalWidth += largestChildWidth; - - } else { - totalWidth += child.getMeasuredWidth(); - } - - totalWidth += lp.leftMargin + lp.rightMargin; - } - - totalWidth += getPaddingLeft() + getPaddingRight(); - setMeasuredDimension(totalWidth, getMeasuredHeight()); - } - - private void useLargestChildVertical() { - final int childCount = getChildCount(); - - // Find largest child width - int largestChildHeight = 0; - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - largestChildHeight = Math.max(child.getMeasuredHeight(), largestChildHeight); - } - - int totalHeight = 0; - // Re-measure childs - for (int i = 0; i < childCount; i++) { - final View child = getChildAt(i); - - if (child == null || child.getVisibility() == View.GONE) { - continue; - } - - final LinearLayout.LayoutParams lp = - (LinearLayout.LayoutParams) child.getLayoutParams(); - - float childExtra = lp.weight; - if (childExtra > 0) { - child.measure( - MeasureSpec.makeMeasureSpec(child.getMeasuredWidth(), - MeasureSpec.EXACTLY), - MeasureSpec.makeMeasureSpec(largestChildHeight, - MeasureSpec.EXACTLY)); - totalHeight += largestChildHeight; - - } else { - totalHeight += child.getMeasuredHeight(); - } - - totalHeight += lp.leftMargin + lp.rightMargin; - } - - totalHeight += getPaddingLeft() + getPaddingRight(); - setMeasuredDimension(getMeasuredWidth(), totalHeight); - } } diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java index d13c6cea9..9ed87db2f 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsListPopupWindow.java @@ -36,7 +36,7 @@ public class IcsListPopupWindow { private static final int EXPAND_LIST_TIMEOUT = 250; private Context mContext; - private PopupWindow mPopup; + private final PopupWindowCompat mPopup; private ListAdapter mAdapter; private DropDownListView mDropDownList; @@ -80,7 +80,7 @@ public class IcsListPopupWindow { public IcsListPopupWindow(Context context, AttributeSet attrs, int defStyleAttr) { mContext = context; - mPopup = new PopupWindow(context, attrs, defStyleAttr); + mPopup = new PopupWindowCompat(context, attrs, defStyleAttr); mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); } @@ -88,9 +88,9 @@ public class IcsListPopupWindow { mContext = context; if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) { Context wrapped = new ContextThemeWrapper(context, defStyleRes); - mPopup = new PopupWindow(wrapped, attrs, defStyleAttr); + mPopup = new PopupWindowCompat(wrapped, attrs, defStyleAttr); } else { - mPopup = new PopupWindow(context, attrs, defStyleAttr, defStyleRes); + mPopup = new PopupWindowCompat(context, attrs, defStyleAttr, defStyleRes); } mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); } @@ -258,6 +258,23 @@ public class IcsListPopupWindow { mPopup.setInputMethodMode(mode); } + /** + * Set the selected position of the list. + * Only valid when {@link #isShowing()} == {@code true}. + * + * @param position List position to set as selected. + */ + public void setSelection(int position) { + DropDownListView list = mDropDownList; + if (isShowing() && list != null) { + list.mListSelectionHidden = false; + list.setSelection(position); + if (list.getChoiceMode() != ListView.CHOICE_MODE_NONE) { + list.setItemChecked(position, true); + } + } + } + public void clearListSelection() { final DropDownListView list = mDropDownList; if (list != null) { diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsToast.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsToast.java new file mode 100644 index 000000000..042648b24 --- /dev/null +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/IcsToast.java @@ -0,0 +1,60 @@ + +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.util.Log; +import android.view.Gravity; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.widget.TextView; +import android.widget.Toast; + +import com.actionbarsherlock.R; + +public class IcsToast extends Toast { + public static final int LENGTH_LONG = Toast.LENGTH_LONG; + public static final int LENGTH_SHORT = Toast.LENGTH_SHORT; + private static final String TAG = "Toast"; + + public static Toast makeText(Context context, CharSequence s, int duration) { + if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { + return Toast.makeText(context, s, duration); + } + IcsToast toast = new IcsToast(context); + toast.setDuration(duration); + TextView view = new TextView(context); + view.setText(s); + // Original AOSP using reference on @android:color/bright_foreground_dark + // bright_foreground_dark - reference on @android:color/background_light + // background_light - 0xffffffff + view.setTextColor(0xffffffff); + view.setGravity(Gravity.CENTER); + view.setBackgroundResource(R.drawable.abs__toast_frame); + toast.setView(view); + return toast; + } + + public static Toast makeText(Context context, int resId, int duration) { + return makeText(context, context.getResources().getString(resId), duration); + } + + public IcsToast(Context context) { + super(context); + } + + @Override + public void setText(CharSequence s) { + if (VERSION.SDK_INT >= VERSION_CODES.ICE_CREAM_SANDWICH) { + super.setText(s); + return; + } + if (getView() == null) { + return; + } + try { + ((TextView) getView()).setText(s); + } catch (ClassCastException e) { + Log.e(TAG, "This Toast was not created with IcsToast.makeText", e); + } + } +} diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/PopupWindowCompat.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/PopupWindowCompat.java new file mode 100644 index 000000000..4c6e3720c --- /dev/null +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/PopupWindowCompat.java @@ -0,0 +1,178 @@ + +package com.actionbarsherlock.internal.widget; + +import java.lang.reflect.Field; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.ViewTreeObserver.OnScrollChangedListener; +import android.widget.PopupWindow; + +/** + * Works around bugs in the handling of {@link ViewTreeObserver} by + * {@link PopupWindow}. + * <p> + * <code>PopupWindow</code> registers an {@link OnScrollChangedListener} with + * {@link ViewTreeObserver}, but does not keep a reference to the observer + * instance that it has registers on. This is problematic when the anchor view + * used by <code>PopupWindow</code> to access the observer is detached from the + * window, as it will revert from the shared <code>ViewTreeObserver</code> owned + * by the <code>ViewRoot</code> to a floating one, meaning + * <code>PopupWindow</code> cannot unregister it's listener anymore and has + * leaked it into the global observer. + * <p> + * This class works around this issue by + * <ul> + * <li>replacing <code>PopupWindow.mOnScrollChangedListener</code> with a no-op + * listener so that any registration or unregistration performed by + * <code>PopupWindow</code> itself has no effect and causes no leaks. + * <li>registering the real listener only with the shared + * <code>ViewTreeObserver</code> and keeping a reference to it to facilitate + * correct unregistration. The reason for not registering on a floating observer + * (before a view is attached) is that there is no safe way to get a reference + * to the shared observer that the floating one will be merged into. This would + * again cause the listener to leak. + * </ul> + */ +public class PopupWindowCompat extends PopupWindow { + + private static final Field superListenerField; + static { + Field f = null; + try { + f = PopupWindow.class.getDeclaredField("mOnScrollChangedListener"); + f.setAccessible(true); + } catch (NoSuchFieldException e) { + /* ignored */ + } + superListenerField = f; + } + + private static final OnScrollChangedListener NOP = new OnScrollChangedListener() { + @Override + public void onScrollChanged() { + /* do nothing */ + } + }; + + private OnScrollChangedListener mSuperScrollListener; + private ViewTreeObserver mViewTreeObserver; + + public PopupWindowCompat() { + super(); + init(); + } + + public PopupWindowCompat(Context context) { + super(context); + init(); + } + + public PopupWindowCompat(Context context, AttributeSet attrs) { + super(context, attrs); + init(); + } + + public PopupWindowCompat(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(); + } + + // @TargetApi(Build.VERSION_CODES.HONEYCOMB) + public PopupWindowCompat(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { + super(context, attrs, defStyleAttr, defStyleRes); + init(); + } + + public PopupWindowCompat(int width, int height) { + super(width, height); + init(); + } + + public PopupWindowCompat(View contentView) { + super(contentView); + init(); + } + + public PopupWindowCompat(View contentView, int width, int height, boolean focusable) { + super(contentView, width, height, focusable); + init(); + } + + public PopupWindowCompat(View contentView, int width, int height) { + super(contentView, width, height); + init(); + } + + private void init() { + if (superListenerField != null) { + try { + mSuperScrollListener = (OnScrollChangedListener) superListenerField.get(this); + superListenerField.set(this, NOP); + } catch (Exception e) { + mSuperScrollListener = null; + } + } + } + + private void unregisterListener() { + // Don't do anything if we haven't managed to patch the super listener + if (mSuperScrollListener != null && mViewTreeObserver != null) { + if (mViewTreeObserver.isAlive()) { + mViewTreeObserver.removeOnScrollChangedListener(mSuperScrollListener); + } + mViewTreeObserver = null; + } + } + + private void registerListener(View anchor) { + // Don't do anything if we haven't managed to patch the super listener. + // And don't bother attaching the listener if the anchor view isn't + // attached. This means we'll only have to deal with the real VTO owned + // by the ViewRoot. + if (mSuperScrollListener != null) { + ViewTreeObserver vto = (anchor.getWindowToken() != null) ? anchor.getViewTreeObserver() + : null; + if (vto != mViewTreeObserver) { + if (mViewTreeObserver != null && mViewTreeObserver.isAlive()) { + mViewTreeObserver.removeOnScrollChangedListener(mSuperScrollListener); + } + if ((mViewTreeObserver = vto) != null) { + vto.addOnScrollChangedListener(mSuperScrollListener); + } + } + } + } + + @Override + public void showAsDropDown(View anchor, int xoff, int yoff) { + super.showAsDropDown(anchor, xoff, yoff); + registerListener(anchor); + } + + @Override + public void update(View anchor, int xoff, int yoff, int width, int height) { + super.update(anchor, xoff, yoff, width, height); + registerListener(anchor); + } + + @Override + public void update(View anchor, int width, int height) { + super.update(anchor, width, height); + registerListener(anchor); + } + + @Override + public void showAtLocation(View parent, int gravity, int x, int y) { + super.showAtLocation(parent, gravity, x, y); + unregisterListener(); + } + + @Override + public void dismiss() { + super.dismiss(); + unregisterListener(); + } +} diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java index 48fb5d8b4..eb178e0de 100644 --- a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/ScrollingTabContainerView.java @@ -186,7 +186,7 @@ public class ScrollingTabContainerView extends NineHorizontalScrollView } private IcsLinearLayout createTabLayout() { - final IcsLinearLayout tabLayout = (IcsLinearLayout) LayoutInflater.from(getContext()) + final TabsLinearLayout tabLayout = (TabsLinearLayout) LayoutInflater.from(getContext()) .inflate(R.layout.abs__action_bar_tab_bar_view, null); tabLayout.setMeasureWithLargestChildEnabled(true); tabLayout.setLayoutParams(new LinearLayout.LayoutParams( diff --git a/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/TabsLinearLayout.java b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/TabsLinearLayout.java new file mode 100644 index 000000000..03d09b1f6 --- /dev/null +++ b/libraries/ActionBarSherlock/src/com/actionbarsherlock/internal/widget/TabsLinearLayout.java @@ -0,0 +1,113 @@ +package com.actionbarsherlock.internal.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.view.View; +import android.widget.LinearLayout; + +public class TabsLinearLayout extends IcsLinearLayout { + private static final int[] R_styleable_LinearLayout = new int[] { + /* 0 */ android.R.attr.measureWithLargestChild, + }; + private static final int LinearLayout_measureWithLargestChild = 0; + + private boolean mUseLargestChild; + + public TabsLinearLayout(Context context, AttributeSet attrs) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, /*com.android.internal.R.styleable.*/R_styleable_LinearLayout); + mUseLargestChild = a.getBoolean(/*com.android.internal.R.styleable.*/LinearLayout_measureWithLargestChild, false); + + a.recycle(); + } + + /** + * When true, all children with a weight will be considered having + * the minimum size of the largest child. If false, all children are + * measured normally. + * + * @return True to measure children with a weight using the minimum + * size of the largest child, false otherwise. + * + * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild + */ + public boolean isMeasureWithLargestChildEnabled() { + return mUseLargestChild; + } + + /** + * When set to true, all children with a weight will be considered having + * the minimum size of the largest child. If false, all children are + * measured normally. + * + * Disabled by default. + * + * @param enabled True to measure children with a weight using the + * minimum size of the largest child, false otherwise. + * + * @attr ref android.R.styleable#LinearLayout_measureWithLargestChild + */ + public void setMeasureWithLargestChildEnabled(boolean enabled) { + mUseLargestChild = enabled; + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + final int childCount = getChildCount(); + if (childCount <= 2) return; + + final int mode = MeasureSpec.getMode(widthMeasureSpec); + if (mUseLargestChild && mode == MeasureSpec.UNSPECIFIED) { + final int orientation = getOrientation(); + if (orientation == HORIZONTAL) { + useLargestChildHorizontal(); + } + } + } + + private void useLargestChildHorizontal() { + final int childCount = getChildCount(); + + // Find largest child width + int largestChildWidth = 0; + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + largestChildWidth = Math.max(child.getMeasuredWidth(), largestChildWidth); + } + + int totalWidth = 0; + // Re-measure childs + for (int i = 0; i < childCount; i++) { + final View child = getChildAt(i); + + if (child == null || child.getVisibility() == View.GONE) { + continue; + } + + final LinearLayout.LayoutParams lp = + (LinearLayout.LayoutParams) child.getLayoutParams(); + + float childExtra = lp.weight; + if (childExtra > 0) { + child.measure( + MeasureSpec.makeMeasureSpec(largestChildWidth, + MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(child.getMeasuredHeight(), + MeasureSpec.EXACTLY)); + totalWidth += largestChildWidth; + + } else { + totalWidth += child.getMeasuredWidth(); + } + + totalWidth += lp.leftMargin + lp.rightMargin; + } + + totalWidth += getPaddingLeft() + getPaddingRight(); + setMeasuredDimension(totalWidth, getMeasuredHeight()); + } +} |