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.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);
|
||||
|
||||
@@ -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() + "(");
|
||||
|
||||
@@ -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",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user