diff options
author | Xavier Ducrohet <xav@android.com> | 2010-11-18 22:12:34 -0800 |
---|---|---|
committer | Xavier Ducrohet <xav@android.com> | 2010-11-18 22:17:14 -0800 |
commit | 55acd60be3c027c224a74290df7bedc1a80c669f (patch) | |
tree | cf721af3e912bc534926ba3225cfc611baaf2811 /tools | |
parent | 60899fac2bf35086b0083bfbffa2f6bf5c18f2d9 (diff) | |
download | frameworks_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')
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 } |