summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorXavier Ducrohet <xav@android.com>2010-11-18 22:12:34 -0800
committerXavier Ducrohet <xav@android.com>2010-11-18 22:17:14 -0800
commit55acd60be3c027c224a74290df7bedc1a80c669f (patch)
treecf721af3e912bc534926ba3225cfc611baaf2811 /tools
parent60899fac2bf35086b0083bfbffa2f6bf5c18f2d9 (diff)
downloadframeworks_base-55acd60be3c027c224a74290df7bedc1a80c669f.zip
frameworks_base-55acd60be3c027c224a74290df7bedc1a80c669f.tar.gz
frameworks_base-55acd60be3c027c224a74290df7bedc1a80c669f.tar.bz2
Layoutlib: support viewkey in include nodes.
When an include tag is parsed, the custom bridge code never has access to both parsers at the same time. The child parser is created out of an in (representing the layout id), and the code inflating the content of the include layout doesn't see the parent parser either. This changeset adds a parser stack in the BridgeContext in order to allow access to the parent parser when setting the viewkey. This is only used if the current parser depth is 1 (top node), as we only want to set the include node to the top node of the included layout. Change-Id: I2ac3b72a0c84a269d9019f44f98cbc0b615ab959
Diffstat (limited to 'tools')
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java18
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java63
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java32
3 files changed, 69 insertions, 44 deletions
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 02db2cf..ac7fada 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -65,6 +65,7 @@ import java.io.InputStream;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.Map;
+import java.util.Stack;
import java.util.TreeMap;
import java.util.Map.Entry;
@@ -99,6 +100,8 @@ public final class BridgeContext extends Activity {
private final ILayoutLog mLogger;
private BridgeContentResolver mContentResolver;
+ private final Stack<BridgeXmlBlockParser> mParserStack = new Stack<BridgeXmlBlockParser>();
+
/**
* @param projectKey An Object identifying the project. This is used for the cache mechanism.
* @param metrics the {@link DisplayMetrics}.
@@ -188,6 +191,21 @@ public final class BridgeContext extends Activity {
return mDefaultPropMaps.get(key);
}
+ public void pushParser(BridgeXmlBlockParser parser) {
+ mParserStack.push(parser);
+ }
+
+ public void popParser() {
+ mParserStack.pop();
+ }
+
+ public BridgeXmlBlockParser getPreviousParser() {
+ if (mParserStack.size() < 2) {
+ return null;
+ }
+ return mParserStack.get(mParserStack.size() - 2);
+ }
+
// ------------- Activity Methods
@Override
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
index b4a28a6..d9e26e2 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeInflater.java
@@ -35,17 +35,17 @@ import java.io.File;
import java.io.FileReader;
/**
- * Custom implementation of {@link LayoutInflater} to handle custom views.
+ * Custom implementation of {@link LayoutInflater} to handle custom views.
*/
public final class BridgeInflater extends LayoutInflater {
-
+
private final IProjectCallback mProjectCallback;
/**
* List of class prefixes which are tried first by default.
* <p/>
* This should match the list in com.android.internal.policy.impl.PhoneLayoutInflater.
- */
+ */
private static final String[] sClassPrefixList = {
"android.widget.",
"android.webkit."
@@ -55,10 +55,10 @@ public final class BridgeInflater extends LayoutInflater {
super(original, newContext);
mProjectCallback = null;
}
-
+
/**
* Instantiate a new BridgeInflater with an {@link IProjectCallback} object.
- *
+ *
* @param context The Android application context.
* @param projectCallback the {@link IProjectCallback} object.
*/
@@ -84,7 +84,7 @@ public final class BridgeInflater extends LayoutInflater {
// Ignore. We'll try again using the base class below.
}
}
-
+
// Next try using the parent loader. This will most likely only work for
// fully-qualified class names.
try {
@@ -94,7 +94,7 @@ public final class BridgeInflater extends LayoutInflater {
} catch (ClassNotFoundException e) {
// Ignore. We'll try again using the custom view loader below.
}
-
+
// Finally try again using the custom view loader
try {
if (view == null) {
@@ -111,12 +111,12 @@ public final class BridgeInflater extends LayoutInflater {
ClassNotFoundException exception = new ClassNotFoundException("onCreateView", e);
throw exception;
}
-
+
setupViewInContext(view, attrs);
-
+
return view;
}
-
+
@Override
public View createViewFromTag(View parent, String name, AttributeSet attrs) {
View view = null;
@@ -130,7 +130,7 @@ public final class BridgeInflater extends LayoutInflater {
// Wrap the real exception in an InflateException so that the calling
// method can deal with it.
InflateException exception = new InflateException();
- if (e2.getClass().equals(ClassNotFoundException.class) == false) {
+ if (e2.getClass().equals(ClassNotFoundException.class) == false) {
exception.initCause(e2);
} else {
exception.initCause(e);
@@ -138,18 +138,18 @@ public final class BridgeInflater extends LayoutInflater {
throw exception;
}
}
-
+
setupViewInContext(view, attrs);
-
+
return view;
}
-
+
@Override
public View inflate(int resource, ViewGroup root) {
Context context = getContext();
if (context instanceof BridgeContext) {
BridgeContext bridgeContext = (BridgeContext)context;
-
+
IResourceValue value = null;
String[] layoutInfo = Bridge.resolveResourceValue(resource);
@@ -158,7 +158,7 @@ public final class BridgeInflater extends LayoutInflater {
layoutInfo[0]);
} else {
layoutInfo = mProjectCallback.resolveResourceValue(resource);
-
+
if (layoutInfo != null) {
value = bridgeContext.getProjectResource(BridgeConstants.RES_LAYOUT,
layoutInfo[0]);
@@ -172,10 +172,10 @@ public final class BridgeInflater extends LayoutInflater {
KXmlParser parser = new KXmlParser();
parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
parser.setInput(new FileReader(f));
-
+
BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser(
parser, bridgeContext, false);
-
+
return inflate(bridgeParser, root);
} catch (Exception e) {
bridgeContext.getLogger().error(e);
@@ -186,7 +186,7 @@ public final class BridgeInflater extends LayoutInflater {
}
return null;
}
-
+
private View loadCustomView(String name, AttributeSet attrs) throws ClassNotFoundException,
Exception{
if (mProjectCallback != null) {
@@ -194,12 +194,12 @@ public final class BridgeInflater extends LayoutInflater {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
}
-
+
mConstructorArgs[1] = attrs;
Object customView = mProjectCallback.loadView(name, mConstructorSignature,
mConstructorArgs);
-
+
if (customView instanceof View) {
return (View)customView;
}
@@ -207,14 +207,27 @@ public final class BridgeInflater extends LayoutInflater {
return null;
}
-
-
-
+
+
+
private void setupViewInContext(View view, AttributeSet attrs) {
if (getContext() instanceof BridgeContext) {
BridgeContext bc = (BridgeContext) getContext();
if (attrs instanceof BridgeXmlBlockParser) {
- Object viewKey = ((BridgeXmlBlockParser) attrs).getViewKey();
+ BridgeXmlBlockParser parser = (BridgeXmlBlockParser) attrs;
+
+ // get the view key
+ Object viewKey = parser.getViewKey();
+
+ // if there's no view key and the depth is 1 (ie this is the first tag),
+ // look for a previous parser in the context, and check if this one has a viewkey.
+ if (viewKey == null && parser.getDepth() == 1) {
+ BridgeXmlBlockParser previousParser = bc.getPreviousParser();
+ if (previousParser != null) {
+ viewKey = previousParser.getViewKey();
+ }
+ }
+
if (viewKey != null) {
bc.addViewKey(view, viewKey);
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
index 24f61c8..073a019 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeXmlBlockParser.java
@@ -40,10 +40,9 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
private XmlPullAttributes mAttrib;
private boolean mStarted = false;
- private boolean mDecNextDepth = false;
- private int mDepth = 0;
private int mEventType = START_DOCUMENT;
private final boolean mPlatformFile;
+ private final BridgeContext mContext;
/**
* Builds a {@link BridgeXmlBlockParser}.
@@ -53,10 +52,13 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
*/
public BridgeXmlBlockParser(XmlPullParser parser, BridgeContext context, boolean platformFile) {
mParser = parser;
+ mContext = context;
mPlatformFile = platformFile;
mAttrib = new BridgeXmlPullAttributes(parser, context, mPlatformFile);
+
+ mContext.pushParser(this);
}
-
+
public boolean isPlatformFile() {
return mPlatformFile;
}
@@ -68,10 +70,9 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
return null;
}
-
-
+
// ------- XmlResourceParser implementation
-
+
public void setFeature(String name, boolean state)
throws XmlPullParserException {
if (FEATURE_PROCESS_NAMESPACES.equals(name) && state) {
@@ -145,7 +146,7 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
}
public int getDepth() {
- return mDepth;
+ return mParser.getDepth();
}
public String getText() {
@@ -236,17 +237,10 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
return START_DOCUMENT;
}
int ev = mParser.next();
- if (mDecNextDepth) {
- mDepth--;
- mDecNextDepth = false;
- }
- switch (ev) {
- case START_TAG:
- mDepth++;
- break;
- case END_TAG:
- mDecNextDepth = true;
- break;
+
+ if (ev == END_TAG && mParser.getDepth() == 1) {
+ // done with parser remove it from the context stack.
+ mContext.popParser();
}
mEventType = ev;
return ev;
@@ -301,7 +295,7 @@ public class BridgeXmlBlockParser implements XmlResourceParser {
// AttributeSet implementation
-
+
public void close() {
// pass
}