diff options
Diffstat (limited to 'tools/layoutlib')
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 } |