summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/preference/Preference.java2
-rw-r--r--core/java/android/preference/PreferenceManager.java2
-rw-r--r--tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java51
-rw-r--r--tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java94
-rw-r--r--tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java4
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java33
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java35
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java37
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java3
-rw-r--r--tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java1
10 files changed, 226 insertions, 36 deletions
diff --git a/core/java/android/preference/Preference.java b/core/java/android/preference/Preference.java
index 56d5617..0224c73 100644
--- a/core/java/android/preference/Preference.java
+++ b/core/java/android/preference/Preference.java
@@ -215,7 +215,7 @@ public class Preference implements Comparable<Preference> {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.Preference, defStyleAttr, defStyleRes);
- for (int i = a.getIndexCount(); i >= 0; i--) {
+ for (int i = a.getIndexCount() - 1; i >= 0; i--) {
int attr = a.getIndex(i);
switch (attr) {
case com.android.internal.R.styleable.Preference_icon:
diff --git a/core/java/android/preference/PreferenceManager.java b/core/java/android/preference/PreferenceManager.java
index ad940c6..0a0e625 100644
--- a/core/java/android/preference/PreferenceManager.java
+++ b/core/java/android/preference/PreferenceManager.java
@@ -156,7 +156,7 @@ public class PreferenceManager {
* should be used ANY time a preference will be displayed, since some preference
* types need an Activity for managed queries.
*/
- private PreferenceManager(Context context) {
+ /*package*/ PreferenceManager(Context context) {
init(context);
}
diff --git a/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java b/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
new file mode 100644
index 0000000..c2122f4
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/preference/BridgePreferenceInflater.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 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.preference;
+
+import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+import java.util.Map;
+
+public class BridgePreferenceInflater extends PreferenceInflater {
+
+ private final Map<Preference, Object> mViewCookieMap;
+
+ public BridgePreferenceInflater(Context context, PreferenceManager preferenceManager,
+ Map<Preference, Object> viewCookieMap) {
+ super(context, preferenceManager);
+ mViewCookieMap = viewCookieMap;
+ }
+
+ @Override
+ protected Preference onCreateItem(String name, AttributeSet attrs)
+ throws ClassNotFoundException {
+ Object viewKey;
+ if (attrs instanceof BridgeXmlBlockParser) {
+ viewKey = ((BridgeXmlBlockParser) attrs).getViewCookie();
+ } else {
+ viewKey = null;
+ }
+ Preference preference = super.onCreateItem(name, attrs);
+ if (viewKey != null) {
+ mViewCookieMap.put(preference, viewKey);
+ }
+ return preference;
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java b/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
new file mode 100644
index 0000000..230fe8c
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/preference/Preference_Delegate.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2014 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.preference;
+
+import com.android.internal.R;
+import com.android.layoutlib.bridge.android.BridgeContext;
+import com.android.tools.layoutlib.annotations.LayoutlibDelegate;
+
+import org.xmlpull.v1.XmlPullParser;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListView;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Delegate that provides implementation for native methods in {@link Preference}
+ * <p/>
+ * Through the layoutlib_create tool, selected methods of Preference have been replaced by calls to
+ * methods of the same name in this delegate class.
+ */
+public class Preference_Delegate {
+
+ private static final Map<Preference, Object> sViewCookies = new HashMap<Preference, Object>();
+
+ @LayoutlibDelegate
+ /*package*/ static void dispatchSetInitialValue(Preference preference) {
+ // pass.
+ }
+
+ @LayoutlibDelegate
+ /*package*/ static View getView(Preference pref, View convertView, ViewGroup parent) {
+ Context context = pref.getContext();
+ BridgeContext bc = context instanceof BridgeContext ? ((BridgeContext) context) : null;
+ convertView = pref.getView_Original(convertView, parent);
+ Object cookie = sViewCookies.get(pref);
+ if (bc != null && cookie != null) {
+ bc.addViewKey(convertView, cookie);
+ }
+ return convertView;
+ }
+
+ /**
+ * Inflates the parser and returns the ListView containing the Preferences. The caller must call
+ * {@link #clearCookiesMap()} when the rendering is complete.
+ */
+ public static View inflatePreference(Context context, XmlPullParser parser, ViewGroup root) {
+ assert sViewCookies.isEmpty();
+ PreferenceManager pm = new PreferenceManager(context);
+ PreferenceScreen ps = pm.getPreferenceScreen();
+ PreferenceInflater inflater = new BridgePreferenceInflater(context, pm, sViewCookies);
+ ps = (PreferenceScreen) inflater.inflate(parser, ps, true);
+ ListView preferenceView = createContainerView(context, root);
+ ps.bind(preferenceView);
+ return preferenceView;
+ }
+
+ private static ListView createContainerView(Context context, ViewGroup root) {
+ TypedArray a = context.obtainStyledAttributes(null, R.styleable.PreferenceFragment,
+ R.attr.preferenceFragmentStyle, 0);
+ int mLayoutResId = a.getResourceId(R.styleable.PreferenceFragment_layout,
+ R.layout.preference_list_fragment);
+ a.recycle();
+
+ LayoutInflater inflater =
+ (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(mLayoutResId, root, true);
+
+ return (ListView) root.findViewById(android.R.id.list);
+ }
+
+ public static void clearCookiesMap() {
+ sViewCookies.clear();
+ }
+}
diff --git a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
index 5a467b2..b0d79a8 100644
--- a/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/text/StaticLayout_Delegate.java
@@ -13,8 +13,8 @@ import javax.swing.text.Segment;
/**
* Delegate that provides implementation for native methods in {@link android.text.StaticLayout}
- *
- * Through the layoutlib_create tool, selected methods of Handler have been replaced
+ * <p/>
+ * Through the layoutlib_create tool, selected methods of StaticLayout have been replaced
* by calls to methods of the same name in this delegate class.
*
*/
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
index 0af04ec..4d2c2fc 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/Bridge.java
@@ -22,6 +22,7 @@ import static com.android.ide.common.rendering.api.Result.Status.SUCCESS;
import com.android.annotations.NonNull;
import com.android.ide.common.rendering.api.Capability;
import com.android.ide.common.rendering.api.DrawableParams;
+import com.android.ide.common.rendering.api.Features;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.ide.common.rendering.api.RenderSession;
import com.android.ide.common.rendering.api.Result;
@@ -180,7 +181,7 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
*/
private static LayoutLog sCurrentLog = sDefaultLog;
- private EnumSet<Capability> mCapabilities;
+ private static final int LAST_SUPPORTED_FEATURE = Features.PREFERENCES_RENDERING;
@Override
public int getApiLevel() {
@@ -188,8 +189,16 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
}
@Override
+ @Deprecated
public EnumSet<Capability> getCapabilities() {
- return mCapabilities;
+ // The Capability class is deprecated and frozen. All Capabilities enumerated there are
+ // supported by this version of LayoutLibrary. So, it's safe to use EnumSet.allOf()
+ return EnumSet.allOf(Capability.class);
+ }
+
+ @Override
+ public boolean supports(int feature) {
+ return feature <= LAST_SUPPORTED_FEATURE;
}
@Override
@@ -200,26 +209,6 @@ public final class Bridge extends com.android.ide.common.rendering.api.Bridge {
sPlatformProperties = platformProperties;
sEnumValueMap = enumValueMap;
- // don't use EnumSet.allOf(), because the bridge doesn't come with its specific version
- // of layoutlib_api. It is provided by the client which could have a more recent version
- // with newer, unsupported capabilities.
- mCapabilities = EnumSet.of(
- Capability.UNBOUND_RENDERING,
- Capability.CUSTOM_BACKGROUND_COLOR,
- Capability.RENDER,
- Capability.LAYOUT_ONLY,
- Capability.EMBEDDED_LAYOUT,
- Capability.VIEW_MANIPULATION,
- Capability.PLAY_ANIMATION,
- Capability.ANIMATED_VIEW_MANIPULATION,
- Capability.ADAPTER_BINDING,
- Capability.EXTENDED_VIEWINFO,
- Capability.FIXED_SCALABLE_NINE_PATCH,
- Capability.RTL,
- Capability.ACTION_BAR,
- Capability.SIMULATE_PLATFORM);
-
-
BridgeAssetManager.initSystem();
// When DEBUG_LAYOUT is set and is not 0 or false, setup a default listener
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java
new file mode 100644
index 0000000..e00ea6a
--- /dev/null
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/SessionParamsFlags.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2014 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 com.android.layoutlib.bridge.android;
+
+import com.android.ide.common.rendering.api.SessionParams;
+
+/**
+ * This contains all known keys for the {@link SessionParams#getFlag(SessionParams.Key)}.
+ * <p/>
+ * The IDE has its own copy of this class which may be newer or older than this one.
+ * <p/>
+ * Constants should never be modified or removed from this class.
+ */
+public final class SessionParamsFlags {
+
+ public static final SessionParams.Key<String> FLAG_KEY_ROOT_TAG =
+ new SessionParams.Key<String>("rootTag", String.class);
+
+ // Disallow instances.
+ private SessionParamsFlags() {}
+}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
index a2eed9a..c8e8ba7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/impl/RenderSessionImpl.java
@@ -49,6 +49,7 @@ import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeLayoutParamsMapAttributes;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
+import com.android.layoutlib.bridge.android.SessionParamsFlags;
import com.android.layoutlib.bridge.bars.Config;
import com.android.layoutlib.bridge.bars.NavigationBar;
import com.android.layoutlib.bridge.bars.StatusBar;
@@ -73,6 +74,7 @@ import android.graphics.Bitmap;
import android.graphics.Bitmap_Delegate;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
+import android.preference.Preference_Delegate;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.AttachInfo_Accessor;
@@ -87,7 +89,6 @@ import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup.MarginLayoutParams;
import android.view.ViewParent;
import android.view.WindowManagerGlobal_Delegate;
-import android.view.ViewParent;
import android.widget.AbsListView;
import android.widget.AbsSpinner;
import android.widget.ActionMenuView;
@@ -397,7 +398,15 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// it can instantiate the custom Fragment.
Fragment_Delegate.setProjectCallback(params.getProjectCallback());
- View view = mInflater.inflate(mBlockParser, mContentRoot);
+ String rootTag = params.getFlag(SessionParamsFlags.FLAG_KEY_ROOT_TAG);
+ boolean isPreference = "PreferenceScreen".equals(rootTag);
+ View view;
+ if (isPreference) {
+ view = Preference_Delegate.inflatePreference(getContext(), mBlockParser,
+ mContentRoot);
+ } else {
+ view = mInflater.inflate(mBlockParser, mContentRoot);
+ }
// done with the parser, pop it.
context.popParser();
@@ -408,7 +417,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
AttachInfo_Accessor.setAttachInfo(mViewRoot);
// post-inflate process. For now this supports TabHost/TabWidget
- postInflateProcess(view, params.getProjectCallback());
+ postInflateProcess(view, params.getProjectCallback(), isPreference ? view : null);
// get the background drawable
if (mWindowBackground != null) {
@@ -590,6 +599,9 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
mSystemViewInfoList = visitAllChildren(mViewRoot, 0, params.getExtendedViewInfoMode(),
false);
+ // clear the preferences cookie map.
+ Preference_Delegate.clearCookiesMap();
+
// success!
return SUCCESS.createResult();
} catch (Throwable e) {
@@ -1210,12 +1222,16 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
* based on the content of the {@link FrameLayout}.
* @param view the root view to process.
* @param projectCallback callback to the project.
+ * @param skip the view and it's children are not processed.
*/
@SuppressWarnings("deprecation") // For the use of Pair
- private void postInflateProcess(View view, IProjectCallback projectCallback)
+ private void postInflateProcess(View view, IProjectCallback projectCallback, View skip)
throws PostInflateException {
+ if (view == skip) {
+ return;
+ }
if (view instanceof TabHost) {
- setupTabHost((TabHost)view, projectCallback);
+ setupTabHost((TabHost) view, projectCallback);
} else if (view instanceof QuickContactBadge) {
QuickContactBadge badge = (QuickContactBadge) view;
badge.setImageToDefault();
@@ -1248,7 +1264,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
boolean skipCallbackParser = false;
int count = binding.getHeaderCount();
- for (int i = 0 ; i < count ; i++) {
+ for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(
binding.getHeaderAt(i),
list, false /*attachToRoot*/, skipCallbackParser);
@@ -1260,7 +1276,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
}
count = binding.getFooterCount();
- for (int i = 0 ; i < count ; i++) {
+ for (int i = 0; i < count; i++) {
Pair<View, Boolean> pair = context.inflateView(
binding.getFooterAt(i),
list, false /*attachToRoot*/, skipCallbackParser);
@@ -1289,11 +1305,11 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
}
}
} else if (view instanceof ViewGroup) {
- ViewGroup group = (ViewGroup)view;
+ ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount();
- for (int c = 0 ; c < count ; c++) {
+ for (int c = 0; c < count; c++) {
View child = group.getChildAt(c);
- postInflateProcess(child, projectCallback);
+ postInflateProcess(child, projectCallback, skip);
}
}
}
@@ -1361,6 +1377,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
for (int i = 0 ; i < count ; i++) {
View child = content.getChildAt(i);
String tabSpec = String.format("tab_spec%d", i+1);
+ @SuppressWarnings("ConstantConditions") // child cannot be null.
int id = child.getId();
@SuppressWarnings("deprecation")
Pair<ResourceType, String> resource = projectCallback.resolveResourceId(id);
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 500c338..2f04b11 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -152,6 +152,8 @@ public final class CreateInfo implements ICreateInfo {
"android.graphics.Typeface#getSystemFontConfigLocation",
"android.os.Handler#sendMessageAtTime",
"android.os.HandlerThread#run",
+ "android.preference.Preference#dispatchSetInitialValue",
+ "android.preference.Preference#getView",
"android.text.format.DateFormat#is24HourFormat",
"android.util.Xml#newPullParser",
"android.view.Choreographer#getRefreshRate",
@@ -273,6 +275,7 @@ public final class CreateInfo implements ICreateInfo {
private final static String[] EXCLUDED_CLASSES =
new String[] {
+ "android.preference.PreferenceActivity",
"org.kxml2.io.KXmlParser"
};
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
index cd3c39e..fa570c8 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/Main.java
@@ -108,6 +108,7 @@ public class Main {
"android.graphics.drawable.*",
"android.content.*",
"android.content.res.*",
+ "android.preference.*",
"org.apache.harmony.xml.*",
"com.android.internal.R**",
"android.pim.*", // for datepicker