Merge "LayoutLib: render system/title/action bars." into honeycomb
This commit is contained in:
committed by
Android (Google) Code Review
commit
331e93e5a2
@@ -17,6 +17,8 @@ LOCAL_PATH := $(call my-dir)
|
|||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
LOCAL_SRC_FILES := $(call all-java-files-under,src)
|
LOCAL_SRC_FILES := $(call all-java-files-under,src)
|
||||||
|
LOCAL_JAVA_RESOURCE_DIRS := resources
|
||||||
|
|
||||||
|
|
||||||
LOCAL_JAVA_LIBRARIES := \
|
LOCAL_JAVA_LIBRARIES := \
|
||||||
kxml2-2.3.0 \
|
kxml2-2.3.0 \
|
||||||
|
|||||||
11
tools/layoutlib/bridge/resources/bars/action_bar.xml
Normal file
11
tools/layoutlib/bridge/resources/bars/action_bar.xml
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
</merge>
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 885 B |
12
tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
Normal file
12
tools/layoutlib/bridge/resources/bars/phone_system_bar.xml
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text=" "/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
</merge>
|
||||||
20
tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
Normal file
20
tools/layoutlib/bridge/resources/bars/tablet_system_bar.xml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"/>
|
||||||
|
<ImageView
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
</merge>
|
||||||
7
tools/layoutlib/bridge/resources/bars/title_bar.xml
Normal file
7
tools/layoutlib/bridge/resources/bars/title_bar.xml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_gravity="center"/>
|
||||||
|
</merge>
|
||||||
@@ -18,6 +18,9 @@ package android.graphics;
|
|||||||
|
|
||||||
import com.android.ide.common.rendering.api.LayoutLog;
|
import com.android.ide.common.rendering.api.LayoutLog;
|
||||||
import com.android.layoutlib.bridge.Bridge;
|
import com.android.layoutlib.bridge.Bridge;
|
||||||
|
import com.android.layoutlib.bridge.android.BridgeResources.NinePatchInputStream;
|
||||||
|
import com.android.ninepatch.NinePatch;
|
||||||
|
import com.android.ninepatch.NinePatchChunk;
|
||||||
import com.android.resources.Density;
|
import com.android.resources.Density;
|
||||||
|
|
||||||
import android.content.res.AssetManager;
|
import android.content.res.AssetManager;
|
||||||
@@ -438,6 +441,8 @@ public class BitmapFactory {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean isNinePatch = is instanceof NinePatchInputStream;
|
||||||
|
|
||||||
// we need mark/reset to work properly
|
// we need mark/reset to work properly
|
||||||
|
|
||||||
if (!is.markSupported()) {
|
if (!is.markSupported()) {
|
||||||
@@ -466,7 +471,29 @@ public class BitmapFactory {
|
|||||||
if (opts != null) {
|
if (opts != null) {
|
||||||
density = Density.getEnum(opts.inDensity);
|
density = Density.getEnum(opts.inDensity);
|
||||||
}
|
}
|
||||||
bm = Bitmap_Delegate.createBitmap(is, true, density);
|
|
||||||
|
if (isNinePatch) {
|
||||||
|
// load the bitmap as a nine patch
|
||||||
|
NinePatch ninePatch = NinePatch.load(is, true /*is9Patch*/, false /*convert*/);
|
||||||
|
|
||||||
|
// get the bitmap and chunk objects.
|
||||||
|
bm = Bitmap_Delegate.createBitmap(ninePatch.getImage(), true /*isMutable*/,
|
||||||
|
density);
|
||||||
|
NinePatchChunk chunk = ninePatch.getChunk();
|
||||||
|
|
||||||
|
// put the chunk in the bitmap
|
||||||
|
bm.setNinePatchChunk(NinePatch_Delegate.serialize(chunk));
|
||||||
|
|
||||||
|
// read the padding
|
||||||
|
int[] padding = chunk.getPadding();
|
||||||
|
outPadding.left = padding[0];
|
||||||
|
outPadding.top = padding[1];
|
||||||
|
outPadding.right = padding[2];
|
||||||
|
outPadding.bottom = padding[3];
|
||||||
|
} else {
|
||||||
|
// load the bitmap directly.
|
||||||
|
bm = Bitmap_Delegate.createBitmap(is, true, density);
|
||||||
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
|
|||||||
|
|
||||||
import com.android.ide.common.rendering.api.Capability;
|
import com.android.ide.common.rendering.api.Capability;
|
||||||
import com.android.ide.common.rendering.api.LayoutLog;
|
import com.android.ide.common.rendering.api.LayoutLog;
|
||||||
import com.android.ide.common.rendering.api.Params;
|
import com.android.ide.common.rendering.api.RenderParams;
|
||||||
import com.android.ide.common.rendering.api.RenderSession;
|
import com.android.ide.common.rendering.api.RenderSession;
|
||||||
import com.android.ide.common.rendering.api.Result;
|
import com.android.ide.common.rendering.api.Result;
|
||||||
import com.android.layoutlib.bridge.android.BridgeAssetManager;
|
import com.android.layoutlib.bridge.android.BridgeAssetManager;
|
||||||
@@ -293,15 +293,15 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a layout session by inflating and rendering it. The method returns a
|
* Starts a layout session by inflating and rendering it. The method returns a
|
||||||
* {@link ILayoutScene} on which further actions can be taken.
|
* {@link RenderSession} on which further actions can be taken.
|
||||||
*
|
*
|
||||||
* @param params the {@link SceneParams} object with all the information necessary to create
|
* @param params the {@link RenderParams} object with all the information necessary to create
|
||||||
* the scene.
|
* the scene.
|
||||||
* @return a new {@link ILayoutScene} object that contains the result of the layout.
|
* @return a new {@link RenderSession} object that contains the result of the layout.
|
||||||
* @since 5
|
* @since 5
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public RenderSession createSession(Params params) {
|
public RenderSession createSession(RenderParams params) {
|
||||||
try {
|
try {
|
||||||
Result lastResult = SUCCESS.createResult();
|
Result lastResult = SUCCESS.createResult();
|
||||||
RenderSessionImpl scene = new RenderSessionImpl(params);
|
RenderSessionImpl scene = new RenderSessionImpl(params);
|
||||||
@@ -331,10 +331,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
* @see com.android.layoutlib.api.ILayoutLibBridge#clearCaches(java.lang.Object)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void clearCaches(Object projectKey) {
|
public void clearCaches(Object projectKey) {
|
||||||
if (projectKey != null) {
|
if (projectKey != null) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package com.android.layoutlib.bridge;
|
|||||||
|
|
||||||
import com.android.ide.common.rendering.api.IAnimationListener;
|
import com.android.ide.common.rendering.api.IAnimationListener;
|
||||||
import com.android.ide.common.rendering.api.ILayoutPullParser;
|
import com.android.ide.common.rendering.api.ILayoutPullParser;
|
||||||
import com.android.ide.common.rendering.api.Params;
|
import com.android.ide.common.rendering.api.RenderParams;
|
||||||
import com.android.ide.common.rendering.api.RenderSession;
|
import com.android.ide.common.rendering.api.RenderSession;
|
||||||
import com.android.ide.common.rendering.api.Result;
|
import com.android.ide.common.rendering.api.Result;
|
||||||
import com.android.ide.common.rendering.api.ViewInfo;
|
import com.android.ide.common.rendering.api.ViewInfo;
|
||||||
@@ -128,7 +128,7 @@ public class BridgeRenderSession extends RenderSession {
|
|||||||
boolean isFrameworkAnimation, IAnimationListener listener) {
|
boolean isFrameworkAnimation, IAnimationListener listener) {
|
||||||
try {
|
try {
|
||||||
Bridge.prepareThread();
|
Bridge.prepareThread();
|
||||||
mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
|
mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
|
||||||
if (mLastResult.isSuccess()) {
|
if (mLastResult.isSuccess()) {
|
||||||
mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
|
mLastResult = mSession.animate(targetObject, animationName, isFrameworkAnimation,
|
||||||
listener);
|
listener);
|
||||||
@@ -150,7 +150,7 @@ public class BridgeRenderSession extends RenderSession {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Bridge.prepareThread();
|
Bridge.prepareThread();
|
||||||
mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
|
mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
|
||||||
if (mLastResult.isSuccess()) {
|
if (mLastResult.isSuccess()) {
|
||||||
mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
|
mLastResult = mSession.insertChild((ViewGroup) parentView, childXml, index,
|
||||||
listener);
|
listener);
|
||||||
@@ -176,7 +176,7 @@ public class BridgeRenderSession extends RenderSession {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Bridge.prepareThread();
|
Bridge.prepareThread();
|
||||||
mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
|
mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
|
||||||
if (mLastResult.isSuccess()) {
|
if (mLastResult.isSuccess()) {
|
||||||
mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
|
mLastResult = mSession.moveChild((ViewGroup) parentView, (View) childView, index,
|
||||||
layoutParams, listener);
|
layoutParams, listener);
|
||||||
@@ -197,7 +197,7 @@ public class BridgeRenderSession extends RenderSession {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
Bridge.prepareThread();
|
Bridge.prepareThread();
|
||||||
mLastResult = mSession.acquire(Params.DEFAULT_TIMEOUT);
|
mLastResult = mSession.acquire(RenderParams.DEFAULT_TIMEOUT);
|
||||||
if (mLastResult.isSuccess()) {
|
if (mLastResult.isSuccess()) {
|
||||||
mLastResult = mSession.removeChild((View) childView, listener);
|
mLastResult = mSession.removeChild((View) childView, listener);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import com.android.ide.common.rendering.api.ResourceValue;
|
|||||||
import com.android.layoutlib.bridge.Bridge;
|
import com.android.layoutlib.bridge.Bridge;
|
||||||
import com.android.layoutlib.bridge.BridgeConstants;
|
import com.android.layoutlib.bridge.BridgeConstants;
|
||||||
import com.android.layoutlib.bridge.impl.ResourceHelper;
|
import com.android.layoutlib.bridge.impl.ResourceHelper;
|
||||||
|
import com.android.ninepatch.NinePatch;
|
||||||
import com.android.resources.ResourceType;
|
import com.android.resources.ResourceType;
|
||||||
import com.android.util.Pair;
|
import com.android.util.Pair;
|
||||||
|
|
||||||
@@ -57,6 +58,18 @@ public final class BridgeResources extends Resources {
|
|||||||
private IProjectCallback mProjectCallback;
|
private IProjectCallback mProjectCallback;
|
||||||
private boolean[] mPlatformResourceFlag = new boolean[1];
|
private boolean[] mPlatformResourceFlag = new boolean[1];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simpler wrapper around FileInputStream. This is used when the input stream represent
|
||||||
|
* not a normal bitmap but a nine patch.
|
||||||
|
* This is useful when the InputStream is created in a method but used in another that needs
|
||||||
|
* to know whether this is 9-patch or not, such as BitmapFactory.
|
||||||
|
*/
|
||||||
|
public class NinePatchInputStream extends FileInputStream {
|
||||||
|
public NinePatchInputStream(File file) throws FileNotFoundException {
|
||||||
|
super(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This initializes the static field {@link Resources#mSystem} which is used
|
* This initializes the static field {@link Resources#mSystem} which is used
|
||||||
* by methods who get global resources using {@link Resources#getSystem()}.
|
* by methods who get global resources using {@link Resources#getSystem()}.
|
||||||
@@ -129,7 +142,7 @@ public final class BridgeResources extends Resources {
|
|||||||
ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
|
ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
return ResourceHelper.getDrawable(value, mContext, value.isFramework());
|
return ResourceHelper.getDrawable(value, mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
// id was not found or not resolved. Throw a NotFoundException.
|
// id was not found or not resolved. Throw a NotFoundException.
|
||||||
@@ -165,44 +178,9 @@ public final class BridgeResources extends Resources {
|
|||||||
ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag);
|
ResourceValue resValue = getResourceValue(id, mPlatformResourceFlag);
|
||||||
|
|
||||||
if (resValue != null) {
|
if (resValue != null) {
|
||||||
String value = resValue.getValue();
|
ColorStateList stateList = ResourceHelper.getColorStateList(resValue, mContext);
|
||||||
if (value != null) {
|
if (stateList != null) {
|
||||||
// first check if the value is a file (xml most likely)
|
return stateList;
|
||||||
File f = new File(value);
|
|
||||||
if (f.isFile()) {
|
|
||||||
try {
|
|
||||||
// let the framework inflate the ColorStateList from the XML file, by
|
|
||||||
// providing an XmlPullParser
|
|
||||||
KXmlParser parser = new KXmlParser();
|
|
||||||
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
|
||||||
parser.setInput(new FileReader(f));
|
|
||||||
|
|
||||||
return ColorStateList.createFromXml(this,
|
|
||||||
new BridgeXmlBlockParser(parser, mContext, resValue.isFramework()));
|
|
||||||
} catch (XmlPullParserException e) {
|
|
||||||
Bridge.getLog().error(LayoutLog.TAG_BROKEN,
|
|
||||||
"Failed to configure parser for " + value, e, null /*data*/);
|
|
||||||
// we'll return null below.
|
|
||||||
} catch (Exception e) {
|
|
||||||
// this is an error and not warning since the file existence is
|
|
||||||
// checked before attempting to parse it.
|
|
||||||
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
|
|
||||||
"Failed to parse file " + value, e, null /*data*/);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// try to load the color state list from an int
|
|
||||||
try {
|
|
||||||
int color = ResourceHelper.getColor(value);
|
|
||||||
return ColorStateList.valueOf(color);
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
|
|
||||||
"Failed to convert " + value + " into a ColorStateList", e,
|
|
||||||
null /*data*/);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -562,13 +540,19 @@ public final class BridgeResources extends Resources {
|
|||||||
ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
|
ResourceValue value = getResourceValue(id, mPlatformResourceFlag);
|
||||||
|
|
||||||
if (value != null) {
|
if (value != null) {
|
||||||
String v = value.getValue();
|
String path = value.getValue();
|
||||||
|
|
||||||
if (v != null) {
|
if (path != null) {
|
||||||
// check this is a file
|
// check this is a file
|
||||||
File f = new File(value.getValue());
|
File f = new File(path);
|
||||||
if (f.isFile()) {
|
if (f.isFile()) {
|
||||||
try {
|
try {
|
||||||
|
// if it's a nine-patch return a custom input stream so that
|
||||||
|
// other methods (mainly bitmap factory) can detect it's a 9-patch
|
||||||
|
// and actually load it as a 9-patch instead of a normal bitmap
|
||||||
|
if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
|
||||||
|
return new NinePatchInputStream(f);
|
||||||
|
}
|
||||||
return new FileInputStream(f);
|
return new FileInputStream(f);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
NotFoundException newE = new NotFoundException();
|
NotFoundException newE = new NotFoundException();
|
||||||
@@ -590,9 +574,17 @@ public final class BridgeResources extends Resources {
|
|||||||
public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
|
public InputStream openRawResource(int id, TypedValue value) throws NotFoundException {
|
||||||
getValue(id, value, true);
|
getValue(id, value, true);
|
||||||
|
|
||||||
File f = new File(value.string.toString());
|
String path = value.string.toString();
|
||||||
|
|
||||||
|
File f = new File(path);
|
||||||
if (f.isFile()) {
|
if (f.isFile()) {
|
||||||
try {
|
try {
|
||||||
|
// if it's a nine-patch return a custom input stream so that
|
||||||
|
// other methods (mainly bitmap factory) can detect it's a 9-patch
|
||||||
|
// and actually load it as a 9-patch instead of a normal bitmap
|
||||||
|
if (path.toLowerCase().endsWith(NinePatch.EXTENSION_9PATCH)) {
|
||||||
|
return new NinePatchInputStream(f);
|
||||||
|
}
|
||||||
return new FileInputStream(f);
|
return new FileInputStream(f);
|
||||||
} catch (FileNotFoundException e) {
|
} catch (FileNotFoundException e) {
|
||||||
NotFoundException exception = new NotFoundException();
|
NotFoundException exception = new NotFoundException();
|
||||||
|
|||||||
@@ -690,7 +690,7 @@ public final class BridgeTypedArray extends TypedArray {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResourceHelper.getDrawable(value, mContext, mResourceData[index].isFramework());
|
return ResourceHelper.getDrawable(value, mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.layoutlib.bridge.bars;
|
||||||
|
|
||||||
|
import com.android.ide.common.rendering.api.RenderResources;
|
||||||
|
import com.android.ide.common.rendering.api.ResourceValue;
|
||||||
|
import com.android.ide.common.rendering.api.StyleResourceValue;
|
||||||
|
import com.android.layoutlib.bridge.Bridge;
|
||||||
|
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||||
|
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
|
||||||
|
import com.android.layoutlib.bridge.impl.ResourceHelper;
|
||||||
|
import com.android.resources.Density;
|
||||||
|
|
||||||
|
import org.kxml2.io.KXmlParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.Bitmap_Delegate;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base "bar" class for the window decor around the the edited layout.
|
||||||
|
* This is basically an horizontal layout that loads a given layout on creation (it is read
|
||||||
|
* through {@link Class#getResourceAsStream(String)}).
|
||||||
|
*
|
||||||
|
* The given layout should be a merge layout so that all the children belong to this class directly.
|
||||||
|
*
|
||||||
|
* It also provides a few utility methods to configure the content of the layout.
|
||||||
|
*/
|
||||||
|
abstract class CustomBar extends LinearLayout {
|
||||||
|
|
||||||
|
protected abstract TextView getStyleableTextView();
|
||||||
|
|
||||||
|
protected CustomBar(Context context, Density density, String layoutPath)
|
||||||
|
throws XmlPullParserException {
|
||||||
|
super(context);
|
||||||
|
setOrientation(LinearLayout.HORIZONTAL);
|
||||||
|
setBackgroundColor(0xFF000000);
|
||||||
|
|
||||||
|
LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(
|
||||||
|
Context.LAYOUT_INFLATER_SERVICE);
|
||||||
|
|
||||||
|
KXmlParser parser = new KXmlParser();
|
||||||
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
|
parser.setInput(
|
||||||
|
getClass().getResourceAsStream(layoutPath),
|
||||||
|
"UTF8");
|
||||||
|
|
||||||
|
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
|
||||||
|
parser, (BridgeContext) context, false);
|
||||||
|
|
||||||
|
inflater.inflate(bridgeParser, this, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadIcon(int index, String iconName, Density density) {
|
||||||
|
View child = getChildAt(index);
|
||||||
|
if (child instanceof ImageView) {
|
||||||
|
ImageView imageView = (ImageView) child;
|
||||||
|
|
||||||
|
// bitmap url relative to this class
|
||||||
|
String path = "/bars/" + density.getResourceValue() + "/" + iconName;
|
||||||
|
|
||||||
|
// create a bitmap
|
||||||
|
Bitmap bitmap = Bridge.getCachedBitmap(path, true /*isFramework*/);
|
||||||
|
|
||||||
|
if (bitmap == null) {
|
||||||
|
InputStream stream = getClass().getResourceAsStream(path);
|
||||||
|
|
||||||
|
if (stream != null) {
|
||||||
|
try {
|
||||||
|
bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density);
|
||||||
|
Bridge.setCachedBitmap(path, bitmap, true /*isFramework*/);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bitmap != null) {
|
||||||
|
BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), bitmap);
|
||||||
|
imageView.setBackgroundDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void loadIcon(int index, String iconReference) {
|
||||||
|
ResourceValue value = getResourceValue(iconReference);
|
||||||
|
if (value != null) {
|
||||||
|
View child = getChildAt(index);
|
||||||
|
if (child instanceof ImageView) {
|
||||||
|
ImageView imageView = (ImageView) child;
|
||||||
|
|
||||||
|
Drawable drawable = ResourceHelper.getDrawable(
|
||||||
|
value, (BridgeContext) mContext);
|
||||||
|
if (drawable != null) {
|
||||||
|
imageView.setBackgroundDrawable(drawable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected TextView setText(int index, String stringReference) {
|
||||||
|
View child = getChildAt(index);
|
||||||
|
if (child instanceof TextView) {
|
||||||
|
TextView textView = (TextView) child;
|
||||||
|
ResourceValue value = getResourceValue(stringReference);
|
||||||
|
if (value != null) {
|
||||||
|
textView.setText(value.getValue());
|
||||||
|
} else {
|
||||||
|
textView.setText(stringReference);
|
||||||
|
}
|
||||||
|
return textView;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setStyle(String themeEntryName) {
|
||||||
|
|
||||||
|
BridgeContext bridgeContext = (BridgeContext) mContext;
|
||||||
|
RenderResources res = bridgeContext.getRenderResources();
|
||||||
|
|
||||||
|
ResourceValue value = res.findItemInTheme(themeEntryName);
|
||||||
|
value = res.resolveResValue(value);
|
||||||
|
|
||||||
|
if (value instanceof StyleResourceValue == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StyleResourceValue style = (StyleResourceValue) value;
|
||||||
|
|
||||||
|
// get the background
|
||||||
|
ResourceValue backgroundValue = res.findItemInStyle(style, "background");
|
||||||
|
backgroundValue = res.resolveResValue(backgroundValue);
|
||||||
|
if (backgroundValue != null) {
|
||||||
|
Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext);
|
||||||
|
if (d != null) {
|
||||||
|
setBackgroundDrawable(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TextView textView = getStyleableTextView();
|
||||||
|
if (textView != null) {
|
||||||
|
// get the text style
|
||||||
|
ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle");
|
||||||
|
textStyleValue = res.resolveResValue(textStyleValue);
|
||||||
|
if (textStyleValue instanceof StyleResourceValue) {
|
||||||
|
StyleResourceValue textStyle = (StyleResourceValue) textStyleValue;
|
||||||
|
|
||||||
|
ResourceValue textSize = res.findItemInStyle(textStyle, "textSize");
|
||||||
|
textSize = res.resolveResValue(textSize);
|
||||||
|
|
||||||
|
if (textSize != null) {
|
||||||
|
TypedValue out = new TypedValue();
|
||||||
|
if (ResourceHelper.stringToFloat(textSize.getValue(), out)) {
|
||||||
|
textView.setTextSize(
|
||||||
|
out.getDimension(bridgeContext.getResources().mMetrics));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ResourceValue textColor = res.findItemInStyle(textStyle, "textColor");
|
||||||
|
textColor = res.resolveResValue(textColor);
|
||||||
|
if (textColor != null) {
|
||||||
|
ColorStateList stateList = ResourceHelper.getColorStateList(
|
||||||
|
textColor, bridgeContext);
|
||||||
|
if (stateList != null) {
|
||||||
|
textView.setTextColor(stateList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceValue getResourceValue(String reference) {
|
||||||
|
BridgeContext bridgeContext = (BridgeContext) mContext;
|
||||||
|
RenderResources res = bridgeContext.getRenderResources();
|
||||||
|
|
||||||
|
// find the resource
|
||||||
|
ResourceValue value = res.findResValue(reference, false /*isFramework*/);
|
||||||
|
|
||||||
|
// resolve it if needed
|
||||||
|
return res.resolveResValue(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.layoutlib.bridge.bars;
|
||||||
|
|
||||||
|
import com.android.resources.Density;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class FakeActionBar extends CustomBar {
|
||||||
|
|
||||||
|
private TextView mTextView;
|
||||||
|
|
||||||
|
public FakeActionBar(Context context, Density density, String label, String icon)
|
||||||
|
throws XmlPullParserException {
|
||||||
|
super(context, density, "/bars/action_bar.xml");
|
||||||
|
|
||||||
|
// Cannot access the inside items through id because no R.id values have been
|
||||||
|
// created for them.
|
||||||
|
// We do know the order though.
|
||||||
|
loadIcon(0, icon);
|
||||||
|
mTextView = setText(1, label);
|
||||||
|
|
||||||
|
setStyle("actionBarStyle");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TextView getStyleableTextView() {
|
||||||
|
return mTextView;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.layoutlib.bridge.bars;
|
||||||
|
|
||||||
|
import com.android.resources.Density;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class PhoneSystemBar extends CustomBar {
|
||||||
|
|
||||||
|
public PhoneSystemBar(Context context, Density density) throws XmlPullParserException {
|
||||||
|
super(context, density, "/bars/tablet_system_bar.xml");
|
||||||
|
|
||||||
|
// Cannot access the inside items through id because no R.id values have been
|
||||||
|
// created for them.
|
||||||
|
// We do know the order though.
|
||||||
|
// 0 is the spacer
|
||||||
|
loadIcon(1, "stat_sys_wifi_signal_4_fully.png", density);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TextView getStyleableTextView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.layoutlib.bridge.bars;
|
||||||
|
|
||||||
|
import com.android.resources.Density;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class TabletSystemBar extends CustomBar {
|
||||||
|
|
||||||
|
public TabletSystemBar(Context context, Density density) throws XmlPullParserException {
|
||||||
|
super(context, density, "/bars/tablet_system_bar.xml");
|
||||||
|
|
||||||
|
// Cannot access the inside items through id because no R.id values have been
|
||||||
|
// created for them.
|
||||||
|
// We do know the order though.
|
||||||
|
loadIcon(0, "ic_sysbar_back_default.png", density);
|
||||||
|
loadIcon(1, "ic_sysbar_home_default.png", density);
|
||||||
|
loadIcon(2, "ic_sysbar_recent_default.png", density);
|
||||||
|
// 3 is the spacer
|
||||||
|
loadIcon(4, "stat_sys_wifi_signal_4_fully.png", density);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TextView getStyleableTextView() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2011 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.layoutlib.bridge.bars;
|
||||||
|
|
||||||
|
import com.android.resources.Density;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
public class TitleBar extends CustomBar {
|
||||||
|
|
||||||
|
private TextView mTextView;
|
||||||
|
|
||||||
|
public TitleBar(Context context, Density density, String label)
|
||||||
|
throws XmlPullParserException {
|
||||||
|
super(context, density, "/bars/title_bar.xml");
|
||||||
|
|
||||||
|
// Cannot access the inside items through id because no R.id values have been
|
||||||
|
// created for them.
|
||||||
|
// We do know the order though.
|
||||||
|
mTextView = setText(0, label);
|
||||||
|
|
||||||
|
setStyle("windowTitleBackgroundStyle");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TextView getStyleableTextView() {
|
||||||
|
return mTextView;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,14 +29,13 @@ import com.android.ide.common.rendering.api.IAnimationListener;
|
|||||||
import com.android.ide.common.rendering.api.ILayoutPullParser;
|
import com.android.ide.common.rendering.api.ILayoutPullParser;
|
||||||
import com.android.ide.common.rendering.api.IProjectCallback;
|
import com.android.ide.common.rendering.api.IProjectCallback;
|
||||||
import com.android.ide.common.rendering.api.LayoutLog;
|
import com.android.ide.common.rendering.api.LayoutLog;
|
||||||
import com.android.ide.common.rendering.api.Params;
|
import com.android.ide.common.rendering.api.RenderParams;
|
||||||
import com.android.ide.common.rendering.api.RenderResources;
|
import com.android.ide.common.rendering.api.RenderResources;
|
||||||
import com.android.ide.common.rendering.api.RenderSession;
|
import com.android.ide.common.rendering.api.RenderSession;
|
||||||
import com.android.ide.common.rendering.api.ResourceValue;
|
import com.android.ide.common.rendering.api.ResourceValue;
|
||||||
import com.android.ide.common.rendering.api.Result;
|
import com.android.ide.common.rendering.api.Result;
|
||||||
import com.android.ide.common.rendering.api.StyleResourceValue;
|
|
||||||
import com.android.ide.common.rendering.api.ViewInfo;
|
import com.android.ide.common.rendering.api.ViewInfo;
|
||||||
import com.android.ide.common.rendering.api.Params.RenderingMode;
|
import com.android.ide.common.rendering.api.RenderParams.RenderingMode;
|
||||||
import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
|
import com.android.ide.common.rendering.api.RenderResources.FrameworkResourceIdProvider;
|
||||||
import com.android.ide.common.rendering.api.Result.Status;
|
import com.android.ide.common.rendering.api.Result.Status;
|
||||||
import com.android.internal.util.XmlUtils;
|
import com.android.internal.util.XmlUtils;
|
||||||
@@ -47,11 +46,16 @@ import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
|
|||||||
import com.android.layoutlib.bridge.android.BridgeWindow;
|
import com.android.layoutlib.bridge.android.BridgeWindow;
|
||||||
import com.android.layoutlib.bridge.android.BridgeWindowSession;
|
import com.android.layoutlib.bridge.android.BridgeWindowSession;
|
||||||
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
|
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
|
||||||
import com.android.resources.Density;
|
import com.android.layoutlib.bridge.bars.FakeActionBar;
|
||||||
|
import com.android.layoutlib.bridge.bars.PhoneSystemBar;
|
||||||
|
import com.android.layoutlib.bridge.bars.TabletSystemBar;
|
||||||
|
import com.android.layoutlib.bridge.bars.TitleBar;
|
||||||
import com.android.resources.ResourceType;
|
import com.android.resources.ResourceType;
|
||||||
import com.android.resources.ScreenSize;
|
import com.android.resources.ScreenSize;
|
||||||
import com.android.util.Pair;
|
import com.android.util.Pair;
|
||||||
|
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import android.animation.Animator;
|
import android.animation.Animator;
|
||||||
import android.animation.AnimatorInflater;
|
import android.animation.AnimatorInflater;
|
||||||
import android.animation.LayoutTransition;
|
import android.animation.LayoutTransition;
|
||||||
@@ -105,7 +109,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
*/
|
*/
|
||||||
private static BridgeContext sCurrentContext = null;
|
private static BridgeContext sCurrentContext = null;
|
||||||
|
|
||||||
private final Params mParams;
|
private final RenderParams mParams;
|
||||||
|
|
||||||
// scene state
|
// scene state
|
||||||
private RenderSession mScene;
|
private RenderSession mScene;
|
||||||
@@ -113,17 +117,18 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
private BridgeXmlBlockParser mBlockParser;
|
private BridgeXmlBlockParser mBlockParser;
|
||||||
private BridgeInflater mInflater;
|
private BridgeInflater mInflater;
|
||||||
private ResourceValue mWindowBackground;
|
private ResourceValue mWindowBackground;
|
||||||
private FrameLayout mViewRoot;
|
private ViewGroup mViewRoot;
|
||||||
|
private FrameLayout mContentRoot;
|
||||||
private Canvas mCanvas;
|
private Canvas mCanvas;
|
||||||
private int mMeasuredScreenWidth = -1;
|
private int mMeasuredScreenWidth = -1;
|
||||||
private int mMeasuredScreenHeight = -1;
|
private int mMeasuredScreenHeight = -1;
|
||||||
private boolean mIsAlphaChannelImage = true;
|
private boolean mIsAlphaChannelImage;
|
||||||
|
private boolean mWindowIsFloating;
|
||||||
|
|
||||||
private int mStatusBarSize;
|
private int mStatusBarSize;
|
||||||
private int mTopBarSize;
|
|
||||||
private int mSystemBarSize;
|
private int mSystemBarSize;
|
||||||
private int mTopOffset;
|
private int mTitleBarSize;
|
||||||
private int mTotalBarSize;
|
private int mActionBarSize;
|
||||||
|
|
||||||
|
|
||||||
// information being returned through the API
|
// information being returned through the API
|
||||||
@@ -146,9 +151,9 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
*
|
*
|
||||||
* @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
|
* @see LayoutBridge#createScene(com.android.layoutlib.api.SceneParams)
|
||||||
*/
|
*/
|
||||||
public RenderSessionImpl(Params params) {
|
public RenderSessionImpl(RenderParams params) {
|
||||||
// copy the params.
|
// copy the params.
|
||||||
mParams = new Params(params);
|
mParams = new RenderParams(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -172,8 +177,8 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
|
|
||||||
// setup the display Metrics.
|
// setup the display Metrics.
|
||||||
DisplayMetrics metrics = new DisplayMetrics();
|
DisplayMetrics metrics = new DisplayMetrics();
|
||||||
metrics.densityDpi = mParams.getDensity();
|
metrics.densityDpi = mParams.getDensity().getDpiValue();
|
||||||
metrics.density = mParams.getDensity() / (float) DisplayMetrics.DENSITY_DEFAULT;
|
metrics.density = metrics.densityDpi / (float) DisplayMetrics.DENSITY_DEFAULT;
|
||||||
metrics.scaledDensity = metrics.density;
|
metrics.scaledDensity = metrics.density;
|
||||||
metrics.widthPixels = mParams.getScreenWidth();
|
metrics.widthPixels = mParams.getScreenWidth();
|
||||||
metrics.heightPixels = mParams.getScreenHeight();
|
metrics.heightPixels = mParams.getScreenHeight();
|
||||||
@@ -190,17 +195,16 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
mIsAlphaChannelImage = getBooleanThemeValue(resources,
|
mIsAlphaChannelImage = getBooleanThemeValue(resources,
|
||||||
"windowIsFloating", true /*defaultValue*/);
|
"windowIsFloating", true /*defaultValue*/);
|
||||||
|
|
||||||
|
mWindowIsFloating = getBooleanThemeValue(resources, "windowIsFloating",
|
||||||
|
true /*defaultValue*/);
|
||||||
|
|
||||||
setUp();
|
setUp();
|
||||||
|
|
||||||
findBackground(resources);
|
findBackground(resources);
|
||||||
findStatusBar(resources, metrics);
|
findStatusBar(resources, metrics);
|
||||||
findTopBar(resources, metrics);
|
findActionBar(resources, metrics);
|
||||||
findSystemBar(resources, metrics);
|
findSystemBar(resources, metrics);
|
||||||
|
|
||||||
mTopOffset = mStatusBarSize + mTopBarSize;
|
|
||||||
mTotalBarSize = mTopOffset + mSystemBarSize;
|
|
||||||
|
|
||||||
// build the inflater and parser.
|
// build the inflater and parser.
|
||||||
mInflater = new BridgeInflater(mContext, mParams.getProjectCallback());
|
mInflater = new BridgeInflater(mContext, mParams.getProjectCallback());
|
||||||
mContext.setBridgeInflater(mInflater);
|
mContext.setBridgeInflater(mInflater);
|
||||||
@@ -353,13 +357,100 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
mViewRoot = new FrameLayout(mContext);
|
if (mWindowIsFloating || mParams.isForceNoDecor()) {
|
||||||
|
mViewRoot = mContentRoot = new FrameLayout(mContext);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* we're creating the following layout
|
||||||
|
*
|
||||||
|
+-------------------------------------------------+
|
||||||
|
| System bar (only in phone UI) |
|
||||||
|
+-------------------------------------------------+
|
||||||
|
| Title/Action bar (optional) |
|
||||||
|
+-------------------------------------------------+
|
||||||
|
| Content, vertical extending |
|
||||||
|
| |
|
||||||
|
+-------------------------------------------------+
|
||||||
|
| System bar (only in tablet UI) |
|
||||||
|
+-------------------------------------------------+
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
LinearLayout topLayout = new LinearLayout(mContext);
|
||||||
|
mViewRoot = topLayout;
|
||||||
|
topLayout.setOrientation(LinearLayout.VERTICAL);
|
||||||
|
|
||||||
|
if (mStatusBarSize > 0) {
|
||||||
|
// system bar
|
||||||
|
try {
|
||||||
|
PhoneSystemBar systemBar = new PhoneSystemBar(mContext,
|
||||||
|
mParams.getDensity());
|
||||||
|
systemBar.setLayoutParams(
|
||||||
|
new LinearLayout.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT, mStatusBarSize));
|
||||||
|
topLayout.addView(systemBar);
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the theme says no title/action bar, then the size will be 0
|
||||||
|
if (mActionBarSize > 0) {
|
||||||
|
try {
|
||||||
|
FakeActionBar actionBar = new FakeActionBar(mContext,
|
||||||
|
mParams.getDensity(),
|
||||||
|
mParams.getAppLabel(), mParams.getAppIcon());
|
||||||
|
actionBar.setLayoutParams(
|
||||||
|
new LinearLayout.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT, mActionBarSize));
|
||||||
|
topLayout.addView(actionBar);
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
} else if (mTitleBarSize > 0) {
|
||||||
|
try {
|
||||||
|
TitleBar titleBar = new TitleBar(mContext,
|
||||||
|
mParams.getDensity(), mParams.getAppLabel());
|
||||||
|
titleBar.setLayoutParams(
|
||||||
|
new LinearLayout.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT, mTitleBarSize));
|
||||||
|
topLayout.addView(titleBar);
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// content frame
|
||||||
|
mContentRoot = new FrameLayout(mContext);
|
||||||
|
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
||||||
|
params.weight = 1;
|
||||||
|
mContentRoot.setLayoutParams(params);
|
||||||
|
topLayout.addView(mContentRoot);
|
||||||
|
|
||||||
|
if (mSystemBarSize > 0) {
|
||||||
|
// system bar
|
||||||
|
try {
|
||||||
|
TabletSystemBar systemBar = new TabletSystemBar(mContext,
|
||||||
|
mParams.getDensity());
|
||||||
|
systemBar.setLayoutParams(
|
||||||
|
new LinearLayout.LayoutParams(
|
||||||
|
LayoutParams.MATCH_PARENT, mSystemBarSize));
|
||||||
|
topLayout.addView(systemBar);
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// Sets the project callback (custom view loader) to the fragment delegate so that
|
// Sets the project callback (custom view loader) to the fragment delegate so that
|
||||||
// it can instantiate the custom Fragment.
|
// it can instantiate the custom Fragment.
|
||||||
Fragment_Delegate.setProjectCallback(mParams.getProjectCallback());
|
Fragment_Delegate.setProjectCallback(mParams.getProjectCallback());
|
||||||
|
|
||||||
View view = mInflater.inflate(mBlockParser, mViewRoot);
|
View view = mInflater.inflate(mBlockParser, mContentRoot);
|
||||||
|
|
||||||
Fragment_Delegate.setProjectCallback(null);
|
Fragment_Delegate.setProjectCallback(null);
|
||||||
|
|
||||||
@@ -377,9 +468,8 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
|
|
||||||
// get the background drawable
|
// get the background drawable
|
||||||
if (mWindowBackground != null) {
|
if (mWindowBackground != null) {
|
||||||
Drawable d = ResourceHelper.getDrawable(mWindowBackground,
|
Drawable d = ResourceHelper.getDrawable(mWindowBackground, mContext);
|
||||||
mContext, true /* isFramework */);
|
mContentRoot.setBackgroundDrawable(d);
|
||||||
mViewRoot.setBackgroundDrawable(d);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return SUCCESS.createResult();
|
return SUCCESS.createResult();
|
||||||
@@ -408,8 +498,8 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
* @throws IllegalStateException if the current context is different than the one owned by
|
* @throws IllegalStateException if the current context is different than the one owned by
|
||||||
* the scene, or if {@link #acquire(long)} was not called.
|
* the scene, or if {@link #acquire(long)} was not called.
|
||||||
*
|
*
|
||||||
* @see SceneParams#getRenderingMode()
|
* @see RenderParams#getRenderingMode()
|
||||||
* @see LayoutScene#render(long)
|
* @see RenderSession#render(long)
|
||||||
*/
|
*/
|
||||||
public Result render(boolean freshRender) {
|
public Result render(boolean freshRender) {
|
||||||
checkLock();
|
checkLock();
|
||||||
@@ -428,7 +518,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
if (mMeasuredScreenWidth == -1) {
|
if (mMeasuredScreenWidth == -1) {
|
||||||
newRenderSize = true;
|
newRenderSize = true;
|
||||||
mMeasuredScreenWidth = mParams.getScreenWidth();
|
mMeasuredScreenWidth = mParams.getScreenWidth();
|
||||||
mMeasuredScreenHeight = mParams.getScreenHeight() - mTotalBarSize;
|
mMeasuredScreenHeight = mParams.getScreenHeight();
|
||||||
|
|
||||||
if (renderingMode != RenderingMode.NORMAL) {
|
if (renderingMode != RenderingMode.NORMAL) {
|
||||||
// measure the full size needed by the layout.
|
// measure the full size needed by the layout.
|
||||||
@@ -476,11 +566,11 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
if (mParams.getImageFactory() != null) {
|
if (mParams.getImageFactory() != null) {
|
||||||
mImage = mParams.getImageFactory().getImage(
|
mImage = mParams.getImageFactory().getImage(
|
||||||
mMeasuredScreenWidth,
|
mMeasuredScreenWidth,
|
||||||
mMeasuredScreenHeight + mTotalBarSize);
|
mMeasuredScreenHeight);
|
||||||
} else {
|
} else {
|
||||||
mImage = new BufferedImage(
|
mImage = new BufferedImage(
|
||||||
mMeasuredScreenWidth,
|
mMeasuredScreenWidth,
|
||||||
mMeasuredScreenHeight + mTotalBarSize,
|
mMeasuredScreenHeight,
|
||||||
BufferedImage.TYPE_INT_ARGB);
|
BufferedImage.TYPE_INT_ARGB);
|
||||||
newImage = true;
|
newImage = true;
|
||||||
}
|
}
|
||||||
@@ -491,46 +581,26 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
Graphics2D gc = mImage.createGraphics();
|
Graphics2D gc = mImage.createGraphics();
|
||||||
gc.setColor(new Color(mParams.getOverrideBgColor(), true));
|
gc.setColor(new Color(mParams.getOverrideBgColor(), true));
|
||||||
gc.setComposite(AlphaComposite.Src);
|
gc.setComposite(AlphaComposite.Src);
|
||||||
gc.fillRect(0, 0, mMeasuredScreenWidth,
|
gc.fillRect(0, 0, mMeasuredScreenWidth, mMeasuredScreenHeight);
|
||||||
mMeasuredScreenHeight + mTotalBarSize);
|
|
||||||
gc.dispose();
|
gc.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an Android bitmap around the BufferedImage
|
// create an Android bitmap around the BufferedImage
|
||||||
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
|
Bitmap bitmap = Bitmap_Delegate.createBitmap(mImage,
|
||||||
true /*isMutable*/,
|
true /*isMutable*/, mParams.getDensity());
|
||||||
Density.getEnum(mParams.getDensity()));
|
|
||||||
|
|
||||||
// create a Canvas around the Android bitmap
|
// create a Canvas around the Android bitmap
|
||||||
mCanvas = new Canvas(bitmap);
|
mCanvas = new Canvas(bitmap);
|
||||||
mCanvas.setDensity(mParams.getDensity());
|
mCanvas.setDensity(mParams.getDensity().getDpiValue());
|
||||||
mCanvas.translate(0, mTopOffset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (freshRender && newImage == false) {
|
if (freshRender && newImage == false) {
|
||||||
Graphics2D gc = mImage.createGraphics();
|
Graphics2D gc = mImage.createGraphics();
|
||||||
gc.setComposite(AlphaComposite.Src);
|
gc.setComposite(AlphaComposite.Src);
|
||||||
|
|
||||||
if (mStatusBarSize > 0) {
|
|
||||||
gc.setColor(new Color(0xFF3C3C3C, true));
|
|
||||||
gc.fillRect(0, 0, mMeasuredScreenWidth, mStatusBarSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTopBarSize > 0) {
|
|
||||||
gc.setColor(new Color(0xFF7F7F7F, true));
|
|
||||||
gc.fillRect(0, mStatusBarSize, mMeasuredScreenWidth, mTopOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// erase the rest
|
|
||||||
gc.setColor(new Color(0x00000000, true));
|
gc.setColor(new Color(0x00000000, true));
|
||||||
gc.fillRect(0, mTopOffset,
|
gc.fillRect(0, 0,
|
||||||
mMeasuredScreenWidth, mMeasuredScreenHeight + mTopOffset);
|
mMeasuredScreenWidth, mMeasuredScreenHeight);
|
||||||
|
|
||||||
if (mSystemBarSize > 0) {
|
|
||||||
gc.setColor(new Color(0xFF3C3C3C, true));
|
|
||||||
gc.fillRect(0, mMeasuredScreenHeight + mTopOffset,
|
|
||||||
mMeasuredScreenWidth, mMeasuredScreenHeight + mTotalBarSize);
|
|
||||||
}
|
|
||||||
|
|
||||||
// done
|
// done
|
||||||
gc.dispose();
|
gc.dispose();
|
||||||
@@ -538,7 +608,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
|
|
||||||
mViewRoot.draw(mCanvas);
|
mViewRoot.draw(mCanvas);
|
||||||
|
|
||||||
mViewInfoList = visitAllChildren((ViewGroup)mViewRoot, mContext, mTopOffset);
|
mViewInfoList = startVisitingViews(mViewRoot, 0);
|
||||||
|
|
||||||
// success!
|
// success!
|
||||||
return SUCCESS.createResult();
|
return SUCCESS.createResult();
|
||||||
@@ -561,7 +631,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
* @throws IllegalStateException if the current context is different than the one owned by
|
* @throws IllegalStateException if the current context is different than the one owned by
|
||||||
* the scene, or if {@link #acquire(long)} was not called.
|
* the scene, or if {@link #acquire(long)} was not called.
|
||||||
*
|
*
|
||||||
* @see LayoutScene#animate(Object, String, boolean, IAnimationListener)
|
* @see RenderSession#animate(Object, String, boolean, IAnimationListener)
|
||||||
*/
|
*/
|
||||||
public Result animate(Object targetObject, String animationName,
|
public Result animate(Object targetObject, String animationName,
|
||||||
boolean isFrameworkAnimation, IAnimationListener listener) {
|
boolean isFrameworkAnimation, IAnimationListener listener) {
|
||||||
@@ -617,7 +687,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
* @throws IllegalStateException if the current context is different than the one owned by
|
* @throws IllegalStateException if the current context is different than the one owned by
|
||||||
* the scene, or if {@link #acquire(long)} was not called.
|
* the scene, or if {@link #acquire(long)} was not called.
|
||||||
*
|
*
|
||||||
* @see LayoutScene#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
|
* @see RenderSession#insertChild(Object, ILayoutPullParser, int, IAnimationListener)
|
||||||
*/
|
*/
|
||||||
public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
|
public Result insertChild(final ViewGroup parentView, ILayoutPullParser childXml,
|
||||||
final int index, IAnimationListener listener) {
|
final int index, IAnimationListener listener) {
|
||||||
@@ -696,7 +766,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
* @throws IllegalStateException if the current context is different than the one owned by
|
* @throws IllegalStateException if the current context is different than the one owned by
|
||||||
* the scene, or if {@link #acquire(long)} was not called.
|
* the scene, or if {@link #acquire(long)} was not called.
|
||||||
*
|
*
|
||||||
* @see LayoutScene#moveChild(Object, Object, int, Map, IAnimationListener)
|
* @see RenderSession#moveChild(Object, Object, int, Map, IAnimationListener)
|
||||||
*/
|
*/
|
||||||
public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
|
public Result moveChild(final ViewGroup newParentView, final View childView, final int index,
|
||||||
Map<String, String> layoutParamsMap, final IAnimationListener listener) {
|
Map<String, String> layoutParamsMap, final IAnimationListener listener) {
|
||||||
@@ -892,7 +962,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
* @throws IllegalStateException if the current context is different than the one owned by
|
* @throws IllegalStateException if the current context is different than the one owned by
|
||||||
* the scene, or if {@link #acquire(long)} was not called.
|
* the scene, or if {@link #acquire(long)} was not called.
|
||||||
*
|
*
|
||||||
* @see LayoutScene#removeChild(Object, IAnimationListener)
|
* @see RenderSession#removeChild(Object, IAnimationListener)
|
||||||
*/
|
*/
|
||||||
public Result removeChild(final View childView, IAnimationListener listener) {
|
public Result removeChild(final View childView, IAnimationListener listener) {
|
||||||
checkLock();
|
checkLock();
|
||||||
@@ -989,40 +1059,12 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
return mParams.getConfigScreenSize() == ScreenSize.XLARGE;
|
return mParams.getConfigScreenSize() == ScreenSize.XLARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isHCApp() {
|
|
||||||
RenderResources resources = mContext.getRenderResources();
|
|
||||||
|
|
||||||
// the app must say it targets 11+ and the theme name must extend Theme.Holo or
|
|
||||||
// Theme.Holo.Light (which does not extend Theme.Holo, but Theme.Light)
|
|
||||||
if (mParams.getTargetSdkVersion() < 11) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleResourceValue currentTheme = resources.getCurrentTheme();
|
|
||||||
StyleResourceValue holoTheme = resources.getTheme("Theme.Holo", true /*frameworkTheme*/);
|
|
||||||
|
|
||||||
if (currentTheme == holoTheme ||
|
|
||||||
resources.themeIsParentOf(holoTheme, currentTheme)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
StyleResourceValue holoLightTheme = resources.getTheme("Theme.Holo.Light",
|
|
||||||
true /*frameworkTheme*/);
|
|
||||||
|
|
||||||
if (currentTheme == holoLightTheme ||
|
|
||||||
resources.themeIsParentOf(holoLightTheme, currentTheme)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
|
private void findStatusBar(RenderResources resources, DisplayMetrics metrics) {
|
||||||
if (isTabletUi() == false) {
|
if (isTabletUi() == false) {
|
||||||
boolean windowFullscreen = getBooleanThemeValue(resources,
|
boolean windowFullscreen = getBooleanThemeValue(resources,
|
||||||
"windowFullscreen", false /*defaultValue*/);
|
"windowFullscreen", false /*defaultValue*/);
|
||||||
|
|
||||||
if (windowFullscreen == false) {
|
if (windowFullscreen == false && mWindowIsFloating == false) {
|
||||||
// default value
|
// default value
|
||||||
mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
|
mStatusBarSize = DEFAULT_STATUS_BAR_HEIGHT;
|
||||||
|
|
||||||
@@ -1041,20 +1083,11 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findTopBar(RenderResources resources, DisplayMetrics metrics) {
|
|
||||||
boolean windowIsFloating = getBooleanThemeValue(resources,
|
|
||||||
"windowIsFloating", true /*defaultValue*/);
|
|
||||||
|
|
||||||
if (windowIsFloating == false) {
|
|
||||||
if (isHCApp()) {
|
|
||||||
findActionBar(resources, metrics);
|
|
||||||
} else {
|
|
||||||
findTitleBar(resources, metrics);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findActionBar(RenderResources resources, DisplayMetrics metrics) {
|
private void findActionBar(RenderResources resources, DisplayMetrics metrics) {
|
||||||
|
if (mWindowIsFloating) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
boolean windowActionBar = getBooleanThemeValue(resources,
|
boolean windowActionBar = getBooleanThemeValue(resources,
|
||||||
"windowActionBar", true /*defaultValue*/);
|
"windowActionBar", true /*defaultValue*/);
|
||||||
|
|
||||||
@@ -1062,7 +1095,7 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
if (windowActionBar) {
|
if (windowActionBar) {
|
||||||
|
|
||||||
// default size of the window title bar
|
// default size of the window title bar
|
||||||
mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT;
|
mActionBarSize = DEFAULT_TITLE_BAR_HEIGHT;
|
||||||
|
|
||||||
// get value from the theme.
|
// get value from the theme.
|
||||||
ResourceValue value = resources.findItemInTheme("actionBarSize");
|
ResourceValue value = resources.findItemInTheme("actionBarSize");
|
||||||
@@ -1075,44 +1108,43 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
TypedValue typedValue = ResourceHelper.getValue(value.getValue());
|
TypedValue typedValue = ResourceHelper.getValue(value.getValue());
|
||||||
if (typedValue != null) {
|
if (typedValue != null) {
|
||||||
// compute the pixel value based on the display metrics
|
// compute the pixel value based on the display metrics
|
||||||
mTopBarSize = (int)typedValue.getDimension(metrics);
|
mActionBarSize = (int)typedValue.getDimension(metrics);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
}
|
// action bar overrides title bar so only look for this one if action bar is hidden
|
||||||
|
boolean windowNoTitle = getBooleanThemeValue(resources,
|
||||||
|
"windowNoTitle", false /*defaultValue*/);
|
||||||
|
|
||||||
private void findTitleBar(RenderResources resources, DisplayMetrics metrics) {
|
if (windowNoTitle == false) {
|
||||||
boolean windowNoTitle = getBooleanThemeValue(resources,
|
|
||||||
"windowNoTitle", false /*defaultValue*/);
|
|
||||||
|
|
||||||
if (windowNoTitle == false) {
|
// default size of the window title bar
|
||||||
|
mTitleBarSize = DEFAULT_TITLE_BAR_HEIGHT;
|
||||||
|
|
||||||
// default size of the window title bar
|
// get value from the theme.
|
||||||
mTopBarSize = DEFAULT_TITLE_BAR_HEIGHT;
|
ResourceValue value = resources.findItemInTheme("windowTitleSize");
|
||||||
|
|
||||||
// get value from the theme.
|
// resolve it
|
||||||
ResourceValue value = resources.findItemInTheme("windowTitleSize");
|
value = resources.resolveResValue(value);
|
||||||
|
|
||||||
// resolve it
|
if (value != null) {
|
||||||
value = resources.resolveResValue(value);
|
// get the numerical value, if available
|
||||||
|
TypedValue typedValue = ResourceHelper.getValue(value.getValue());
|
||||||
if (value != null) {
|
if (typedValue != null) {
|
||||||
// get the numerical value, if available
|
// compute the pixel value based on the display metrics
|
||||||
TypedValue typedValue = ResourceHelper.getValue(value.getValue());
|
mTitleBarSize = (int)typedValue.getDimension(metrics);
|
||||||
if (typedValue != null) {
|
}
|
||||||
// compute the pixel value based on the display metrics
|
|
||||||
mTopBarSize = (int)typedValue.getDimension(metrics);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void findSystemBar(RenderResources resources, DisplayMetrics metrics) {
|
private void findSystemBar(RenderResources resources, DisplayMetrics metrics) {
|
||||||
if (isTabletUi() && getBooleanThemeValue(
|
if (isTabletUi() && mWindowIsFloating == false) {
|
||||||
resources, "windowIsFloating", true /*defaultValue*/) == false) {
|
|
||||||
|
|
||||||
// default value
|
// default value
|
||||||
mSystemBarSize = 56; // ??
|
mSystemBarSize = 48; // ??
|
||||||
|
|
||||||
// get the real value
|
// get the real value
|
||||||
ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
|
ResourceValue value = resources.getFrameworkResource(ResourceType.DIMEN,
|
||||||
@@ -1244,40 +1276,71 @@ public class RenderSessionImpl extends FrameworkResourceIdProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ViewInfo> startVisitingViews(View view, int offset) {
|
||||||
|
if (view == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// adjust the offset to this view.
|
||||||
|
offset += view.getTop();
|
||||||
|
|
||||||
|
if (view == mContentRoot) {
|
||||||
|
return visitAllChildren(mContentRoot, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise, look for mContentRoot in the children
|
||||||
|
if (view instanceof ViewGroup) {
|
||||||
|
ViewGroup group = ((ViewGroup) view);
|
||||||
|
|
||||||
|
for (int i = 0; i < group.getChildCount(); i++) {
|
||||||
|
List<ViewInfo> list = startVisitingViews(group.getChildAt(i), offset);
|
||||||
|
if (list != null) {
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Visits a View and its children and generate a {@link ViewInfo} containing the
|
* Visits a View and its children and generate a {@link ViewInfo} containing the
|
||||||
* bounds of all the views.
|
* bounds of all the views.
|
||||||
* @param view the root View
|
* @param view the root View
|
||||||
* @param context the context.
|
* @param offset an offset for the view bounds.
|
||||||
*/
|
*/
|
||||||
private ViewInfo visit(View view, BridgeContext context, int offset) {
|
private ViewInfo visit(View view, int offset) {
|
||||||
if (view == null) {
|
if (view == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewInfo result = new ViewInfo(view.getClass().getName(),
|
ViewInfo result = new ViewInfo(view.getClass().getName(),
|
||||||
context.getViewKey(view),
|
mContext.getViewKey(view),
|
||||||
view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset,
|
view.getLeft(), view.getTop() + offset, view.getRight(), view.getBottom() + offset,
|
||||||
view, view.getLayoutParams());
|
view, view.getLayoutParams());
|
||||||
|
|
||||||
if (view instanceof ViewGroup) {
|
if (view instanceof ViewGroup) {
|
||||||
ViewGroup group = ((ViewGroup) view);
|
ViewGroup group = ((ViewGroup) view);
|
||||||
result.setChildren(visitAllChildren(group, context, 0 /*offset*/));
|
result.setChildren(visitAllChildren(group, 0 /*offset*/));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, BridgeContext context,
|
/**
|
||||||
int offset) {
|
* Visits all the children of a given ViewGroup generate a list of {@link ViewInfo}
|
||||||
|
* containing the bounds of all the views.
|
||||||
|
* @param view the root View
|
||||||
|
* @param offset an offset for the view bounds.
|
||||||
|
*/
|
||||||
|
private List<ViewInfo> visitAllChildren(ViewGroup viewGroup, int offset) {
|
||||||
if (viewGroup == null) {
|
if (viewGroup == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ViewInfo> children = new ArrayList<ViewInfo>();
|
List<ViewInfo> children = new ArrayList<ViewInfo>();
|
||||||
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
for (int i = 0; i < viewGroup.getChildCount(); i++) {
|
||||||
children.add(visit(viewGroup.getChildAt(i), context, offset));
|
children.add(visit(viewGroup.getChildAt(i), offset));
|
||||||
}
|
}
|
||||||
return children;
|
return children;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.impl;
|
|||||||
|
|
||||||
import com.android.ide.common.rendering.api.DensityBasedResourceValue;
|
import com.android.ide.common.rendering.api.DensityBasedResourceValue;
|
||||||
import com.android.ide.common.rendering.api.LayoutLog;
|
import com.android.ide.common.rendering.api.LayoutLog;
|
||||||
|
import com.android.ide.common.rendering.api.RenderResources;
|
||||||
import com.android.ide.common.rendering.api.ResourceValue;
|
import com.android.ide.common.rendering.api.ResourceValue;
|
||||||
import com.android.layoutlib.bridge.Bridge;
|
import com.android.layoutlib.bridge.Bridge;
|
||||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||||
@@ -28,7 +29,9 @@ import com.android.resources.Density;
|
|||||||
|
|
||||||
import org.kxml2.io.KXmlParser;
|
import org.kxml2.io.KXmlParser;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
|
import android.content.res.ColorStateList;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.graphics.Bitmap_Delegate;
|
import android.graphics.Bitmap_Delegate;
|
||||||
import android.graphics.NinePatch_Delegate;
|
import android.graphics.NinePatch_Delegate;
|
||||||
@@ -108,19 +111,63 @@ public final class ResourceHelper {
|
|||||||
throw new NumberFormatException();
|
throw new NumberFormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ColorStateList getColorStateList(ResourceValue resValue, BridgeContext context) {
|
||||||
|
String value = resValue.getValue();
|
||||||
|
if (value != null) {
|
||||||
|
// first check if the value is a file (xml most likely)
|
||||||
|
File f = new File(value);
|
||||||
|
if (f.isFile()) {
|
||||||
|
try {
|
||||||
|
// let the framework inflate the ColorStateList from the XML file, by
|
||||||
|
// providing an XmlPullParser
|
||||||
|
KXmlParser parser = new KXmlParser();
|
||||||
|
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
|
||||||
|
parser.setInput(new FileReader(f));
|
||||||
|
|
||||||
|
return ColorStateList.createFromXml(context.getResources(),
|
||||||
|
new BridgeXmlBlockParser(parser, context, resValue.isFramework()));
|
||||||
|
} catch (XmlPullParserException e) {
|
||||||
|
Bridge.getLog().error(LayoutLog.TAG_BROKEN,
|
||||||
|
"Failed to configure parser for " + value, e, null /*data*/);
|
||||||
|
// we'll return null below.
|
||||||
|
} catch (Exception e) {
|
||||||
|
// this is an error and not warning since the file existence is
|
||||||
|
// checked before attempting to parse it.
|
||||||
|
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_READ,
|
||||||
|
"Failed to parse file " + value, e, null /*data*/);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// try to load the color state list from an int
|
||||||
|
try {
|
||||||
|
int color = ResourceHelper.getColor(value);
|
||||||
|
return ColorStateList.valueOf(color);
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
Bridge.getLog().error(LayoutLog.TAG_RESOURCES_FORMAT,
|
||||||
|
"Failed to convert " + value + " into a ColorStateList", e,
|
||||||
|
null /*data*/);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a drawable from the given value.
|
* Returns a drawable from the given value.
|
||||||
* @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
|
* @param value The value that contains a path to a 9 patch, a bitmap or a xml based drawable,
|
||||||
* or an hexadecimal color
|
* or an hexadecimal color
|
||||||
* @param context
|
* @param context the current context
|
||||||
* @param isFramework indicates whether the resource is a framework resources.
|
|
||||||
* Framework resources are cached, and loaded only once.
|
|
||||||
*/
|
*/
|
||||||
public static Drawable getDrawable(ResourceValue value, BridgeContext context,
|
public static Drawable getDrawable(ResourceValue value, BridgeContext context) {
|
||||||
boolean isFramework) {
|
|
||||||
Drawable d = null;
|
Drawable d = null;
|
||||||
|
|
||||||
String stringValue = value.getValue();
|
String stringValue = value.getValue();
|
||||||
|
if (RenderResources.REFERENCE_NULL.equals(stringValue)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
String lowerCaseValue = stringValue.toLowerCase();
|
String lowerCaseValue = stringValue.toLowerCase();
|
||||||
|
|
||||||
@@ -129,9 +176,9 @@ public final class ResourceHelper {
|
|||||||
if (file.isFile()) {
|
if (file.isFile()) {
|
||||||
// see if we still have both the chunk and the bitmap in the caches
|
// see if we still have both the chunk and the bitmap in the caches
|
||||||
NinePatchChunk chunk = Bridge.getCached9Patch(stringValue,
|
NinePatchChunk chunk = Bridge.getCached9Patch(stringValue,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
|
Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
|
|
||||||
// if either chunk or bitmap is null, then we reload the 9-patch file.
|
// if either chunk or bitmap is null, then we reload the 9-patch file.
|
||||||
if (chunk == null || bitmap == null) {
|
if (chunk == null || bitmap == null) {
|
||||||
@@ -143,7 +190,7 @@ public final class ResourceHelper {
|
|||||||
chunk = ninePatch.getChunk();
|
chunk = ninePatch.getChunk();
|
||||||
|
|
||||||
Bridge.setCached9Patch(stringValue, chunk,
|
Bridge.setCached9Patch(stringValue, chunk,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
@@ -158,7 +205,7 @@ public final class ResourceHelper {
|
|||||||
density);
|
density);
|
||||||
|
|
||||||
Bridge.setCachedBitmap(stringValue, bitmap,
|
Bridge.setCachedBitmap(stringValue, bitmap,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (MalformedURLException e) {
|
} catch (MalformedURLException e) {
|
||||||
@@ -192,7 +239,7 @@ public final class ResourceHelper {
|
|||||||
parser.setInput(new FileReader(f));
|
parser.setInput(new FileReader(f));
|
||||||
|
|
||||||
d = Drawable.createFromXml(context.getResources(),
|
d = Drawable.createFromXml(context.getResources(),
|
||||||
new BridgeXmlBlockParser(parser, context, isFramework));
|
new BridgeXmlBlockParser(parser, context, value.isFramework()));
|
||||||
return d;
|
return d;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// this is an error and not warning since the file existence is checked before
|
// this is an error and not warning since the file existence is checked before
|
||||||
@@ -212,7 +259,7 @@ public final class ResourceHelper {
|
|||||||
if (bmpFile.isFile()) {
|
if (bmpFile.isFile()) {
|
||||||
try {
|
try {
|
||||||
Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
|
Bitmap bitmap = Bridge.getCachedBitmap(stringValue,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
|
|
||||||
if (bitmap == null) {
|
if (bitmap == null) {
|
||||||
Density density = Density.MEDIUM;
|
Density density = Density.MEDIUM;
|
||||||
@@ -223,7 +270,7 @@ public final class ResourceHelper {
|
|||||||
bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
|
bitmap = Bitmap_Delegate.createBitmap(bmpFile, false /*isMutable*/,
|
||||||
density);
|
density);
|
||||||
Bridge.setCachedBitmap(stringValue, bitmap,
|
Bridge.setCachedBitmap(stringValue, bitmap,
|
||||||
isFramework ? null : context.getProjectKey());
|
value.isFramework() ? null : context.getProjectKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BitmapDrawable(context.getResources(), bitmap);
|
return new BitmapDrawable(context.getResources(), bitmap);
|
||||||
|
|||||||
Reference in New Issue
Block a user