am 97c88368: am c78d173b: am 68411471: Merge "Fix layout rendering for RTL locales" into jb-mr2-dev

* commit '97c88368e0036665507c8cd84c71d26953784c85':
  Fix layout rendering for RTL locales
This commit is contained in:
Deepanshu Gupta
2013-09-05 12:00:54 -07:00
committed by Android Git Automerger
15 changed files with 81 additions and 19 deletions

View File

@ -7,5 +7,6 @@
<classpathentry kind="var" path="ANDROID_PLAT_SRC/out/host/common/obj/JAVA_LIBRARIES/temp_layoutlib_intermediates/javalib.jar" sourcepath="/ANDROID_PLAT_SRC/frameworks/base"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/ninepatch/ninepatch-prebuilt.jar"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/tools-common/tools-common-prebuilt.jar"/>
<classpathentry kind="var" path="ANDROID_PLAT_SRC/prebuilts/misc/common/icu4j/icu4j.jar"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -22,6 +22,7 @@ LOCAL_JAVA_RESOURCE_DIRS := resources
LOCAL_JAVA_LIBRARIES := \
kxml2-2.3.0 \
icu4j \
layoutlib_api-prebuilt \
tools-common-prebuilt

Binary file not shown.

After

Width:  |  Height:  |  Size: 904 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 B

View File

@ -35,6 +35,7 @@ import com.android.resources.ResourceType;
import com.android.tools.layoutlib.create.MethodAdapter;
import com.android.tools.layoutlib.create.OverrideMethod;
import com.android.util.Pair;
import com.ibm.icu.util.ULocale;
import android.content.res.BridgeAssetManager;
import android.graphics.Bitmap;
@ -64,6 +65,8 @@ import java.util.concurrent.locks.ReentrantLock;
*/
public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
private static final String ICU_LOCALE_DIRECTION_RTL = "right-to-left";
public static class StaticMethodNotImplementedException extends RuntimeException {
private static final long serialVersionUID = 1L;
@ -211,7 +214,8 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
Capability.ANIMATED_VIEW_MANIPULATION,
Capability.ADAPTER_BINDING,
Capability.EXTENDED_VIEWINFO,
Capability.FIXED_SCALABLE_NINE_PATCH);
Capability.FIXED_SCALABLE_NINE_PATCH,
Capability.RTL);
BridgeAssetManager.initSystem();
@ -411,6 +415,20 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
throw new IllegalArgumentException("viewObject is not a View");
}
@Override
public boolean isRtl(String locale) {
return isLocaleRtl(locale);
}
public static boolean isLocaleRtl(String locale) {
if (locale == null) {
locale = "";
}
ULocale uLocale = new ULocale(locale);
return uLocale.getCharacterOrientation().equals(ICU_LOCALE_DIRECTION_RTL) ?
true : false;
}
/**
* Returns the lock for the bridge
*/

View File

@ -132,7 +132,8 @@ public final class BridgeContext extends Context {
RenderResources renderResources,
IProjectCallback projectCallback,
Configuration config,
int targetSdkVersion) {
int targetSdkVersion,
boolean hasRtlSupport) {
mProjectKey = projectKey;
mMetrics = metrics;
mProjectCallback = projectCallback;
@ -142,6 +143,9 @@ public final class BridgeContext extends Context {
mApplicationInfo = new ApplicationInfo();
mApplicationInfo.targetSdkVersion = targetSdkVersion;
if (hasRtlSupport) {
mApplicationInfo.flags = mApplicationInfo.flags | ApplicationInfo.FLAG_SUPPORTS_RTL;
}
mWindowManager = new WindowManagerImpl(mMetrics);
}

View File

@ -25,6 +25,7 @@ import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.impl.ResourceHelper;
import com.android.resources.Density;
import com.android.resources.LayoutDirection;
import com.android.resources.ResourceType;
import org.xmlpull.v1.XmlPullParser;
@ -86,38 +87,53 @@ abstract class CustomBar extends LinearLayout {
}
}
private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut,
boolean tryOtherDensities) {
private InputStream getIcon(String iconName, Density[] densityInOut, LayoutDirection direction,
String[] pathOut, boolean tryOtherDensities) {
// current density
Density density = densityInOut[0];
// bitmap url relative to this class
if (direction != null) {
pathOut[0] = "/bars/" + direction.getResourceValue() + "-" + density.getResourceValue()
+ "/" + iconName;
} else {
pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName;
}
InputStream stream = getClass().getResourceAsStream(pathOut[0]);
if (stream == null && tryOtherDensities) {
for (Density d : Density.values()) {
if (d != density) {
densityInOut[0] = d;
stream = getIcon(iconName, densityInOut, pathOut, false /*tryOtherDensities*/);
stream = getIcon(iconName, densityInOut, direction, pathOut,
false /*tryOtherDensities*/);
if (stream != null) {
return stream;
}
}
}
// couldn't find resource with direction qualifier. try without.
if (direction != null) {
return getIcon(iconName, densityInOut, null, pathOut, true);
}
}
return stream;
}
protected void loadIcon(int index, String iconName, Density density) {
loadIcon(index, iconName, density, false);
}
protected void loadIcon(int index, String iconName, Density density, boolean isRtl) {
View child = getChildAt(index);
if (child instanceof ImageView) {
ImageView imageView = (ImageView) child;
String[] pathOut = new String[1];
Density[] densityInOut = new Density[] { density };
InputStream stream = getIcon(iconName, densityInOut, pathOut,
LayoutDirection dir = isRtl ? LayoutDirection.RTL : LayoutDirection.LTR;
InputStream stream = getIcon(iconName, densityInOut, dir, pathOut,
true /*tryOtherDensities*/);
density = densityInOut[0];

View File

@ -17,6 +17,7 @@
package com.android.layoutlib.bridge.bars;
import com.android.resources.Density;
import com.android.layoutlib.bridge.Bridge;
import org.xmlpull.v1.XmlPullParserException;
@ -26,7 +27,8 @@ import android.widget.TextView;
public class NavigationBar extends CustomBar {
public NavigationBar(Context context, Density density, int orientation) throws XmlPullParserException {
public NavigationBar(Context context, Density density, int orientation, boolean isRtl,
boolean rtlEnabled) throws XmlPullParserException {
super(context, density, orientation, "/bars/navigation_bar.xml", "navigation_bar.xml");
setBackgroundColor(0xFF000000);
@ -37,14 +39,15 @@ public class NavigationBar extends CustomBar {
// 0 is a spacer.
int back = 1;
int recent = 3;
if (orientation == LinearLayout.VERTICAL) {
if (orientation == LinearLayout.VERTICAL || (isRtl && !rtlEnabled)) {
// If RTL is enabled, then layoutlib mirrors the layout for us.
back = 3;
recent = 1;
}
loadIcon(back, "ic_sysbar_back.png", density);
loadIcon(2, "ic_sysbar_home.png", density);
loadIcon(recent, "ic_sysbar_recent.png", density);
loadIcon(back, "ic_sysbar_back.png", density, isRtl);
loadIcon(2, "ic_sysbar_home.png", density, isRtl);
loadIcon(recent, "ic_sysbar_recent.png", density, isRtl);
}
@Override

View File

@ -30,7 +30,10 @@ import android.widget.TextView;
public class StatusBar extends CustomBar {
public StatusBar(Context context, Density density) throws XmlPullParserException {
public StatusBar(Context context, Density density, int direction, boolean RtlEnabled)
throws XmlPullParserException {
// FIXME: if direction is RTL but it's not enabled in application manifest, mirror this bar.
super(context, density, LinearLayout.HORIZONTAL, "/bars/status_bar.xml", "status_bar.xml");
// FIXME: use FILL_H?

View File

@ -121,7 +121,8 @@ public abstract class RenderAction<T extends RenderParams> extends FrameworkReso
// build the context
mContext = new BridgeContext(mParams.getProjectKey(), metrics, resources,
mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion());
mParams.getProjectCallback(), getConfiguration(), mParams.getTargetSdkVersion(),
mParams.isRtlSupported());
setUp();

View File

@ -224,13 +224,15 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
SessionParams params = getParams();
HardwareConfig hardwareConfig = params.getHardwareConfig();
BridgeContext context = getContext();
boolean isRtl = Bridge.isLocaleRtl(params.getLocale());
int direction = isRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR;
// the view group that receives the window background.
ViewGroup backgroundView = null;
if (mWindowIsFloating || params.isForceNoDecor()) {
backgroundView = mViewRoot = mContentRoot = new FrameLayout(context);
mViewRoot.setLayoutDirection(direction);
} else {
if (hasSoftwareButtons() && mNavigationBarOrientation == LinearLayout.VERTICAL) {
/*
@ -252,12 +254,14 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
the bottom
*/
LinearLayout topLayout = new LinearLayout(context);
topLayout.setLayoutDirection(direction);
mViewRoot = topLayout;
topLayout.setOrientation(LinearLayout.HORIZONTAL);
try {
NavigationBar navigationBar = new NavigationBar(context,
hardwareConfig.getDensity(), LinearLayout.VERTICAL);
hardwareConfig.getDensity(), LinearLayout.VERTICAL, isRtl,
params.isRtlSupported());
navigationBar.setLayoutParams(
new LinearLayout.LayoutParams(
mNavigationBarSize,
@ -289,6 +293,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
LinearLayout topLayout = new LinearLayout(context);
topLayout.setOrientation(LinearLayout.VERTICAL);
topLayout.setLayoutDirection(direction);
// if we don't already have a view root this is it
if (mViewRoot == null) {
mViewRoot = topLayout;
@ -300,13 +305,22 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// this is the case of soft buttons + vertical bar.
// this top layout is the first layout in the horizontal layout. see above)
if (isRtl && params.isRtlSupported()) {
// If RTL is enabled, layoutlib will mirror the layouts. So, add the
// topLayout to the right of Navigation Bar and layoutlib will draw it
// to the left.
mViewRoot.addView(topLayout);
} else {
// Add the top layout to the left of the Navigation Bar.
mViewRoot.addView(topLayout, 0);
}
}
if (mStatusBarSize > 0) {
// system bar
try {
StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity());
StatusBar systemBar = new StatusBar(context, hardwareConfig.getDensity(),
direction, params.isRtlSupported());
systemBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mStatusBarSize));
@ -365,7 +379,8 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// system bar
try {
NavigationBar navigationBar = new NavigationBar(context,
hardwareConfig.getDensity(), LinearLayout.HORIZONTAL);
hardwareConfig.getDensity(), LinearLayout.HORIZONTAL, isRtl,
params.isRtlSupported());
navigationBar.setLayoutParams(
new LinearLayout.LayoutParams(
LayoutParams.MATCH_PARENT, mNavigationBarSize));