Merge "LayoutLib: Use special view cookie for include-merge case." into honeycomb

This commit is contained in:
Xavier Ducrohet
2011-01-24 14:31:28 -08:00
committed by Android (Google) Code Review
4 changed files with 118 additions and 6 deletions

View File

@@ -0,0 +1,95 @@
/*
* 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 android.view;
import com.android.layoutlib.bridge.android.BridgeInflater;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.util.AttributeSet;
import java.io.IOException;
/**
* Delegate used to provide new implementation of a select few methods of {@link LayoutInflater}
*
* Through the layoutlib_create tool, the original methods of LayoutInflater have been replaced
* by calls to methods of the same name in this delegate class.
*
*/
public class LayoutInflater_Delegate {
/**
* Recursive method used to descend down the xml hierarchy and instantiate
* views, instantiate their children, and then call onFinishInflate().
*/
/*package*/ static void rInflate(LayoutInflater thisInflater,
XmlPullParser parser, View parent, final AttributeSet attrs,
boolean finishInflate) throws XmlPullParserException, IOException {
if (finishInflate == false) {
// this is a merge rInflate!
if (thisInflater instanceof BridgeInflater) {
((BridgeInflater) thisInflater).setIsInMerge(true);
}
}
// ---- START DEFAULT IMPLEMENTATION.
final int depth = parser.getDepth();
int type;
while (((type = parser.next()) != XmlPullParser.END_TAG ||
parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) {
if (type != XmlPullParser.START_TAG) {
continue;
}
final String name = parser.getName();
if (LayoutInflater.TAG_REQUEST_FOCUS.equals(name)) {
thisInflater.parseRequestFocus(parser, parent);
} else if (LayoutInflater.TAG_INCLUDE.equals(name)) {
if (parser.getDepth() == 0) {
throw new InflateException("<include /> cannot be the root element");
}
thisInflater.parseInclude(parser, parent, attrs);
} else if (LayoutInflater.TAG_MERGE.equals(name)) {
throw new InflateException("<merge /> must be the root element");
} else {
final View view = thisInflater.createViewFromTag(parent, name, attrs);
final ViewGroup viewGroup = (ViewGroup) parent;
final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs);
thisInflater.rInflate(parser, view, attrs, true);
viewGroup.addView(view, params);
}
}
if (finishInflate) parent.onFinishInflate();
// ---- END DEFAULT IMPLEMENTATION.
if (finishInflate == false) {
// this is a merge rInflate!
if (thisInflater instanceof BridgeInflater) {
((BridgeInflater) thisInflater).setIsInMerge(false);
}
}
}
}

View File

@@ -18,6 +18,7 @@ package com.android.layoutlib.bridge.android;
import com.android.ide.common.rendering.api.IProjectCallback;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.MergeCookie;
import com.android.ide.common.rendering.api.RenderResources;
import com.android.ide.common.rendering.api.ResourceValue;
import com.android.layoutlib.bridge.Bridge;
@@ -41,6 +42,7 @@ import java.io.FileReader;
public final class BridgeInflater extends LayoutInflater {
private final IProjectCallback mProjectCallback;
private boolean mIsInMerge = false;
/**
* List of class prefixes which are tried first by default.
@@ -211,8 +213,6 @@ public final class BridgeInflater extends LayoutInflater {
return null;
}
private void setupViewInContext(View view, AttributeSet attrs) {
if (getContext() instanceof BridgeContext) {
BridgeContext bc = (BridgeContext) getContext();
@@ -222,9 +222,11 @@ public final class BridgeInflater extends LayoutInflater {
// get the view key
Object viewKey = parser.getViewCookie();
// if there's no view key and the depth is 1 (ie this is the first tag),
// if there's no view key and the depth is 1 (ie this is the first tag), or 2
// (this is first item in included merge layout)
// look for a previous parser in the context, and check if this one has a viewkey.
if (viewKey == null && parser.getDepth() == 1) {
int testDepth = mIsInMerge ? 2 : 1;
if (viewKey == null && parser.getDepth() == testDepth) {
BridgeXmlBlockParser previousParser = bc.getPreviousParser();
if (previousParser != null) {
viewKey = previousParser.getViewCookie();
@@ -232,12 +234,21 @@ public final class BridgeInflater extends LayoutInflater {
}
if (viewKey != null) {
if (testDepth == 2) {
// include-merge case
viewKey = new MergeCookie(viewKey);
}
bc.addViewKey(view, viewKey);
}
}
}
}
public void setIsInMerge(boolean isInMerge) {
mIsInMerge = isInMerge;
}
@Override
public LayoutInflater cloneInContext(Context newContext) {
return new BridgeInflater(this, newContext);

View File

@@ -104,7 +104,12 @@ public class TestDelegates extends TestCase {
parameters);
// check that the method is static
assertTrue((delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC);
assertTrue(
String.format(
"Delegate method %1$s for class %2$s is not static",
delegateMethod.getName(),
originalClass.getName()),
(delegateMethod.getModifiers() & Modifier.STATIC) == Modifier.STATIC);
} catch (NoSuchMethodException e) {
// compute a full class name that's long but not too long.
StringBuilder sb = new StringBuilder(originalMethod.getName() + "(");

View File

@@ -96,8 +96,9 @@ public final class CreateInfo implements ICreateInfo {
private final static String[] DELEGATE_METHODS = new String[] {
"android.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
"android.os.Handler#sendMessageAtTime",
"android.view.LayoutInflater#rInflate",
"android.view.View#isInEditMode",
"com.android.internal.util.XmlUtils#convertValueToInt"
"com.android.internal.util.XmlUtils#convertValueToInt",
// TODO: comment out once DelegateClass is working
// "android.content.res.Resources$Theme#obtainStyledAttributes",
};