Fixes for optical bounds feature.

1. Make the feature opt-in (ViewGroup::layoutMode defaults to CLIP_BOUNDS) without inheritance.
2. Rename COMPONENT_BOUNDS to CLIP_BOUNDS.
3. Rename LAYOUT_BOUNDS to OPTICAL_BOUNDS.
4. Complete GridLayout implementation.
5. Change the default_gap between components to 8dp, to align with the Style Guide.

Change-Id: I8d40dfc5f4ca469f6424eb3ff60d07bec56e3a9f
This commit is contained in:
Philip Milne
2012-04-24 22:12:36 -07:00
parent c887843b19
commit 7a23b49a8c
13 changed files with 103 additions and 128 deletions

View File

@@ -24493,12 +24493,12 @@ package android.view {
method public void startLayoutAnimation();
method public void startViewTransition(android.view.View);
method public void updateViewLayout(android.view.View, android.view.ViewGroup.LayoutParams);
field public static final int CLIP_BOUNDS = 0; // 0x0
field protected static final int CLIP_TO_PADDING_MASK = 34; // 0x22
field public static final int COMPONENT_BOUNDS = 0; // 0x0
field public static final int FOCUS_AFTER_DESCENDANTS = 262144; // 0x40000
field public static final int FOCUS_BEFORE_DESCENDANTS = 131072; // 0x20000
field public static final int FOCUS_BLOCK_DESCENDANTS = 393216; // 0x60000
field public static final int LAYOUT_BOUNDS = 1; // 0x1
field public static final int OPTICAL_BOUNDS = 1; // 0x1
field public static final int PERSISTENT_ALL_CACHES = 3; // 0x3
field public static final int PERSISTENT_ANIMATION_CACHE = 1; // 0x1
field public static final int PERSISTENT_NO_CACHE = 0; // 0x0

View File

@@ -13853,7 +13853,7 @@ public class View implements Drawable.Callback, Drawable.Callback2, KeyEvent.Cal
/**
* @hide
*/
public Insets getLayoutInsets() {
public Insets getOpticalInsets() {
if (mLayoutInsets == null) {
mLayoutInsets = (mBackground == null) ? Insets.NONE : mBackground.getLayoutInsets();
}

View File

@@ -173,10 +173,9 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
protected int mGroupFlags;
/*
* THe layout mode: either {@link #UNDEFINED_LAYOUT_MODE}, {@link #COMPONENT_BOUNDS} or
* {@link #LAYOUT_BOUNDS}
* The layout mode: either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}
*/
private int mLayoutMode = UNDEFINED_LAYOUT_MODE;
private int mLayoutMode = CLIP_BOUNDS;
/**
* NOTE: If you change the flags below make sure to reflect the changes
@@ -345,19 +344,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
// Layout Modes
private static final int UNDEFINED_LAYOUT_MODE = -1;
/**
* This constant is a {@link #setLayoutMode(int) layoutMode}.
* Component bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
* Clip bounds are the raw values of {@link #getLeft() left}, {@link #getTop() top},
* {@link #getRight() right} and {@link #getBottom() bottom}.
*/
public static final int COMPONENT_BOUNDS = 0;
public static final int CLIP_BOUNDS = 0;
/**
* This constant is a {@link #setLayoutMode(int) layoutMode}.
* Optical bounds describe where a widget appears to be. They sit inside the clip
* bounds which need to cover a larger area to allow other effects,
* such as shadows and glows, to be drawn.
*/
public static final int LAYOUT_BOUNDS = 1;
public static final int OPTICAL_BOUNDS = 1;
/**
* We clip to padding when FLAG_CLIP_TO_PADDING and FLAG_PADDING_NOT_NULL
@@ -2696,10 +2696,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
*/
protected void onDebugDraw(Canvas canvas) {
// Draw optical bounds
if (getLayoutMode() == LAYOUT_BOUNDS) {
if (getLayoutMode() == OPTICAL_BOUNDS) {
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
Insets insets = c.getLayoutInsets();
Insets insets = c.getOpticalInsets();
drawRect(canvas,
c.getLeft() + insets.left,
c.getTop() + insets.top,
@@ -4597,37 +4597,22 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
/**
* Returns the basis of alignment during the layout of this view group:
* either {@link #COMPONENT_BOUNDS} or {@link #LAYOUT_BOUNDS}.
* Returns the basis of alignment during layout operations on this view group:
* either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}.
*
* @return the layout mode to use during layout operations
*
* @see #setLayoutMode(int)
*/
public int getLayoutMode() {
if (mLayoutMode == UNDEFINED_LAYOUT_MODE) {
ViewParent parent = getParent();
if (parent instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) parent;
return viewGroup.getLayoutMode();
} else {
int targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
boolean preJellyBean = targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN;
return preJellyBean ? COMPONENT_BOUNDS : LAYOUT_BOUNDS;
}
}
return mLayoutMode;
}
/**
* Sets the basis of alignment during alignment of this view group.
* Valid values are either {@link #COMPONENT_BOUNDS} or {@link #LAYOUT_BOUNDS}.
* Sets the basis of alignment during the layout of this view group.
* Valid values are either {@link #CLIP_BOUNDS} or {@link #OPTICAL_BOUNDS}.
* <p>
* The default is to query the property of the parent if this view group has a parent.
* If this ViewGroup is the root of the view hierarchy the default
* value is {@link #LAYOUT_BOUNDS} for target SDK's greater than JellyBean,
* {@link #LAYOUT_BOUNDS} otherwise.
* The default is {@link #CLIP_BOUNDS}.
*
* @param layoutMode the layout mode to use during layout operations
*

View File

@@ -581,10 +581,10 @@ public class GridLayout extends ViewGroup {
}
private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) {
return isAtEdge ? DEFAULT_CONTAINER_MARGIN : getDefaultMargin(c, horizontal, leading);
return /*isAtEdge ? DEFAULT_CONTAINER_MARGIN :*/ getDefaultMargin(c, horizontal, leading);
}
private int getDefaultMarginValue(View c, LayoutParams p, boolean horizontal, boolean leading) {
private int getDefaultMargin(View c, LayoutParams p, boolean horizontal, boolean leading) {
if (!useDefaultMargins) {
return 0;
}
@@ -602,7 +602,7 @@ public class GridLayout extends ViewGroup {
int margin = horizontal ?
(leading ? lp.leftMargin : lp.rightMargin) :
(leading ? lp.topMargin : lp.bottomMargin);
return margin == UNDEFINED ? getDefaultMarginValue(view, lp, horizontal, leading) : margin;
return margin == UNDEFINED ? getDefaultMargin(view, lp, horizontal, leading) : margin;
}
private int getMargin(View view, boolean horizontal, boolean leading) {
@@ -777,11 +777,12 @@ public class GridLayout extends ViewGroup {
LayoutParams lp = new LayoutParams();
for (int i = 0; i < getChildCount(); i++) {
View c = getChildAt(i);
Insets insets = getLayoutMode() == OPTICAL_BOUNDS ? c.getOpticalInsets() : Insets.NONE;
lp.setMargins(
getMargin1(c, true, true),
getMargin1(c, false, true),
getMargin1(c, true, false),
getMargin1(c, false, false));
getMargin1(c, true, true) - insets.left,
getMargin1(c, false, true) - insets.top,
getMargin1(c, true, false) - insets.right,
getMargin1(c, false, false) - insets.bottom);
lp.onDebugDraw(c, canvas);
}
}
@@ -946,7 +947,12 @@ public class GridLayout extends ViewGroup {
}
private int getMeasurement(View c, boolean horizontal) {
return horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
int result = horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
if (getLayoutMode() == OPTICAL_BOUNDS) {
Insets insets = c.getOpticalInsets();
return result - (horizontal ? insets.left + insets.right : insets.top + insets.bottom);
}
return result;
}
final int getMeasurementIncludingMargin(View c, boolean horizontal) {
@@ -1052,6 +1058,14 @@ public class GridLayout extends ViewGroup {
targetWidth - width - paddingRight - rightMargin - dx;
int cy = paddingTop + y1 + gravityOffsetY + alignmentOffsetY + topMargin;
boolean useLayoutBounds = getLayoutMode() == OPTICAL_BOUNDS;
if (useLayoutBounds) {
Insets insets = c.getOpticalInsets();
cx -= insets.left;
cy -= insets.top;
width += (insets.left + insets.right);
height += (insets.top + insets.bottom);
}
if (width != c.getMeasuredWidth() || height != c.getMeasuredHeight()) {
c.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
}
@@ -2135,21 +2149,8 @@ public class GridLayout extends ViewGroup {
return before + after;
}
private int getAlignmentValue(GridLayout gl, View c, int size, Alignment a, boolean horiz) {
boolean useLayoutBounds = gl.getLayoutMode() == LAYOUT_BOUNDS;
if (!useLayoutBounds) {
return a.getAlignmentValue(c, size);
} else {
Insets insets = c.getLayoutInsets();
int leadingInset = horiz ? insets.left : insets.top; // RTL?
int trailingInset = horiz ? insets.right : insets.bottom; // RTL?
int totalInset = leadingInset + trailingInset;
return leadingInset + a.getAlignmentValue(c, size - totalInset);
}
}
protected int getOffset(GridLayout gl, View c, Alignment a, int size, boolean horizontal) {
return before - getAlignmentValue(gl, c, size, a, horizontal);
return before - a.getAlignmentValue(c, size, gl.getLayoutMode());
}
protected final void include(GridLayout gl, View c, Spec spec, Axis axis) {
@@ -2158,7 +2159,7 @@ public class GridLayout extends ViewGroup {
int size = gl.getMeasurementIncludingMargin(c, horizontal);
Alignment alignment = gl.getAlignment(spec.alignment, horizontal);
// todo test this works correctly when the returned value is UNDEFINED
int before = getAlignmentValue(gl, c, size, alignment, horizontal);
int before = alignment.getAlignmentValue(c, size, gl.getLayoutMode());
include(before, size - before);
}
@@ -2441,9 +2442,10 @@ public class GridLayout extends ViewGroup {
*
* @param view the view to which this alignment should be applied
* @param viewSize the measured size of the view
* @param mode the basis of alignment: CLIP or OPTICAL
* @return the alignment value
*/
abstract int getAlignmentValue(View view, int viewSize);
abstract int getAlignmentValue(View view, int viewSize, int mode);
/**
* Returns the size of the view specified by this alignment.
@@ -2473,7 +2475,7 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
return UNDEFINED;
}
};
@@ -2489,7 +2491,7 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
return 0;
}
};
@@ -2505,7 +2507,7 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
return viewSize;
}
};
@@ -2542,8 +2544,8 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
return (!view.isLayoutRtl() ? ltr : rtl).getAlignmentValue(view, viewSize);
public int getAlignmentValue(View view, int viewSize, int mode) {
return (!view.isLayoutRtl() ? ltr : rtl).getAlignmentValue(view, viewSize, mode);
}
};
}
@@ -2572,7 +2574,7 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
return viewSize >> 1;
}
};
@@ -2591,9 +2593,16 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
int baseline = view.getBaseline();
return (baseline == -1) ? UNDEFINED : baseline;
if (baseline == -1) {
return UNDEFINED;
} else {
if (mode == OPTICAL_BOUNDS) {
return baseline - view.getOpticalInsets().top;
}
return baseline;
}
}
@Override
@@ -2644,7 +2653,7 @@ public class GridLayout extends ViewGroup {
}
@Override
public int getAlignmentValue(View view, int viewSize) {
public int getAlignmentValue(View view, int viewSize, int mode) {
return UNDEFINED;
}

View File

@@ -194,7 +194,7 @@
<dimen name="activity_chooser_popup_min_width">200dip</dimen>
<!-- The default gap between components in a layout. -->
<dimen name="default_gap">16dip</dimen>
<dimen name="default_gap">8dip</dimen>
<!-- Text padding for dropdown items -->
<dimen name="dropdownitem_text_padding_left">8dip</dimen>

View File

@@ -56,6 +56,7 @@ public class NinePatchDrawable extends Drawable {
private NinePatchState mNinePatchState;
private NinePatch mNinePatch;
private Rect mPadding;
private Insets mLayoutInsets = Insets.NONE;
private Paint mPaint;
private boolean mMutated;
@@ -180,12 +181,21 @@ public class NinePatchDrawable extends Drawable {
}
}
private Insets scaleFromDensity(Insets insets, int sdensity, int tdensity) {
int left = Bitmap.scaleFromDensity(insets.left, sdensity, tdensity);
int top = Bitmap.scaleFromDensity(insets.top, sdensity, tdensity);
int right = Bitmap.scaleFromDensity(insets.right, sdensity, tdensity);
int bottom = Bitmap.scaleFromDensity(insets.bottom, sdensity, tdensity);
return Insets.of(left, top, right, bottom);
}
private void computeBitmapSize() {
final int sdensity = mNinePatch.getDensity();
final int tdensity = mTargetDensity;
if (sdensity == tdensity) {
mBitmapWidth = mNinePatch.getWidth();
mBitmapHeight = mNinePatch.getHeight();
mLayoutInsets = mNinePatchState.mLayoutInsets;
} else {
mBitmapWidth = Bitmap.scaleFromDensity(mNinePatch.getWidth(),
sdensity, tdensity);
@@ -202,6 +212,7 @@ public class NinePatchDrawable extends Drawable {
dest.right = Bitmap.scaleFromDensity(src.right, sdensity, tdensity);
dest.bottom = Bitmap.scaleFromDensity(src.bottom, sdensity, tdensity);
}
mLayoutInsets = scaleFromDensity(mNinePatchState.mLayoutInsets, sdensity, tdensity);
}
}
@@ -226,7 +237,7 @@ public class NinePatchDrawable extends Drawable {
*/
@Override
public Insets getLayoutInsets() {
return mNinePatchState.mLayoutInsets;
return mLayoutInsets;
}
@Override

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2008 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_window_focused="false" android:state_enabled="true"
android:drawable="@drawable/my_btn_default_normal" />
<item android:state_window_focused="false" android:state_enabled="false"
android:drawable="@drawable/my_btn_default_normal" />
<item android:state_pressed="true"
android:drawable="@drawable/my_btn_default_pressed" />
<item android:state_focused="true" android:state_enabled="true"
android:drawable="@drawable/my_btn_default_selected" />
<item android:state_enabled="true"
android:drawable="@drawable/my_btn_default_normal" />
<item android:state_focused="true"
android:drawable="@drawable/my_btn_default_normal_disable_focused" />
<item
android:drawable="@drawable/my_btn_default_normal_disable" />
</selector>

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -4,46 +4,49 @@ import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.GridLayout;
import android.widget.TextView;
import static android.widget.GridLayout.*;
import static android.widget.GridLayout.ALIGN_BOUNDS;
import static android.widget.GridLayout.LayoutParams;
import static android.widget.GridLayout.OPTICAL_BOUNDS;
public class LayoutInsetsTest extends Activity {
static int[] GRAVITIES = {Gravity.LEFT, Gravity.LEFT, Gravity.CENTER_HORIZONTAL, Gravity.RIGHT, Gravity.RIGHT};
public static View create(Context context) {
final int N = GRAVITIES.length;
GridLayout p = new GridLayout(context);
p.setUseDefaultMargins(true);
p.setAlignmentMode(ALIGN_BOUNDS);
p.setOrientation(VERTICAL);
//p.setAlignmentMode(ALIGN_BOUNDS);
p.setLayoutMode(OPTICAL_BOUNDS);
p.setColumnCount(N);
for (int i = 0; i < 2*N; i++) {
View c;
if (i % 2 == 0) {
TextView tv = new TextView(context);
tv.setTextSize(32);
tv.setText("A");
c = tv;
} else {
Button b = new Button(context);
b.setBackgroundResource(R.drawable.btn_default_normal);
b.setText("B");
c = b;
}
LayoutParams lp = new LayoutParams();
lp.setGravity(GRAVITIES[(i % N)]);
p.addView(c, lp);
{
TextView c = new TextView(context);
c.setTextSize(32);
c.setText("Email setup");
p.addView(c);
}
{
Button c = new Button(context);
c.setBackgroundResource(R.drawable.btn_default);
c.setText("Test");
p.addView(c);
}
{
Button c = new Button(context);
c.setBackgroundResource(R.drawable.btn_default);
c.setText("Manual setup");
p.addView(c);
c.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Button b = (Button) v;
b.setEnabled(false);
}
});
}
return p;
}