Merge "LayoutLib: Use special view cookie for include-merge case." into honeycomb
This commit is contained in:
committed by
Android (Google) Code Review
commit
5b9936f651
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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.IProjectCallback;
|
||||||
import com.android.ide.common.rendering.api.LayoutLog;
|
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.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;
|
||||||
@@ -41,6 +42,7 @@ import java.io.FileReader;
|
|||||||
public final class BridgeInflater extends LayoutInflater {
|
public final class BridgeInflater extends LayoutInflater {
|
||||||
|
|
||||||
private final IProjectCallback mProjectCallback;
|
private final IProjectCallback mProjectCallback;
|
||||||
|
private boolean mIsInMerge = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of class prefixes which are tried first by default.
|
* List of class prefixes which are tried first by default.
|
||||||
@@ -211,8 +213,6 @@ public final class BridgeInflater extends LayoutInflater {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void setupViewInContext(View view, AttributeSet attrs) {
|
private void setupViewInContext(View view, AttributeSet attrs) {
|
||||||
if (getContext() instanceof BridgeContext) {
|
if (getContext() instanceof BridgeContext) {
|
||||||
BridgeContext bc = (BridgeContext) getContext();
|
BridgeContext bc = (BridgeContext) getContext();
|
||||||
@@ -222,9 +222,11 @@ public final class BridgeInflater extends LayoutInflater {
|
|||||||
// get the view key
|
// get the view key
|
||||||
Object viewKey = parser.getViewCookie();
|
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.
|
// 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();
|
BridgeXmlBlockParser previousParser = bc.getPreviousParser();
|
||||||
if (previousParser != null) {
|
if (previousParser != null) {
|
||||||
viewKey = previousParser.getViewCookie();
|
viewKey = previousParser.getViewCookie();
|
||||||
@@ -232,12 +234,21 @@ public final class BridgeInflater extends LayoutInflater {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (viewKey != null) {
|
if (viewKey != null) {
|
||||||
|
if (testDepth == 2) {
|
||||||
|
// include-merge case
|
||||||
|
viewKey = new MergeCookie(viewKey);
|
||||||
|
}
|
||||||
|
|
||||||
bc.addViewKey(view, viewKey);
|
bc.addViewKey(view, viewKey);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setIsInMerge(boolean isInMerge) {
|
||||||
|
mIsInMerge = isInMerge;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public LayoutInflater cloneInContext(Context newContext) {
|
public LayoutInflater cloneInContext(Context newContext) {
|
||||||
return new BridgeInflater(this, newContext);
|
return new BridgeInflater(this, newContext);
|
||||||
|
|||||||
@@ -104,7 +104,12 @@ public class TestDelegates extends TestCase {
|
|||||||
parameters);
|
parameters);
|
||||||
|
|
||||||
// check that the method is static
|
// 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) {
|
} catch (NoSuchMethodException e) {
|
||||||
// compute a full class name that's long but not too long.
|
// compute a full class name that's long but not too long.
|
||||||
StringBuilder sb = new StringBuilder(originalMethod.getName() + "(");
|
StringBuilder sb = new StringBuilder(originalMethod.getName() + "(");
|
||||||
|
|||||||
@@ -96,8 +96,9 @@ public final class CreateInfo implements ICreateInfo {
|
|||||||
private final static String[] DELEGATE_METHODS = new String[] {
|
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.app.Fragment#instantiate", //(Landroid/content/Context;Ljava/lang/String;Landroid/os/Bundle;)Landroid/app/Fragment;",
|
||||||
"android.os.Handler#sendMessageAtTime",
|
"android.os.Handler#sendMessageAtTime",
|
||||||
|
"android.view.LayoutInflater#rInflate",
|
||||||
"android.view.View#isInEditMode",
|
"android.view.View#isInEditMode",
|
||||||
"com.android.internal.util.XmlUtils#convertValueToInt"
|
"com.android.internal.util.XmlUtils#convertValueToInt",
|
||||||
// TODO: comment out once DelegateClass is working
|
// TODO: comment out once DelegateClass is working
|
||||||
// "android.content.res.Resources$Theme#obtainStyledAttributes",
|
// "android.content.res.Resources$Theme#obtainStyledAttributes",
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user