Merge "Add tools:openDrawer to open a DrawerLayout." into mnc-dev

This commit is contained in:
Deepanshu Gupta
2015-07-16 00:59:33 +00:00
committed by Android (Google) Code Review
6 changed files with 111 additions and 6 deletions

View File

@@ -25,6 +25,7 @@ import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.BridgeConstants;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.BridgeXmlBlockParser;
import com.android.layoutlib.bridge.android.support.DrawerLayoutUtil;
import com.android.layoutlib.bridge.android.support.RecyclerViewUtil;
import com.android.layoutlib.bridge.impl.ParserFactory;
import com.android.layoutlib.bridge.util.ReflectionUtils;
@@ -33,10 +34,13 @@ import com.android.util.Pair;
import org.xmlpull.v1.XmlPullParser;
import android.annotation.NonNull;
import android.content.Context;
import android.util.AttributeSet;
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
@@ -48,6 +52,7 @@ public final class BridgeInflater extends LayoutInflater {
private final LayoutlibCallback mLayoutlibCallback;
private boolean mIsInMerge = false;
private ResourceReference mResourceReference;
private Map<View, String> mOpenDrawerLayouts;
/**
* List of class prefixes which are tried first by default.
@@ -256,7 +261,14 @@ public final class BridgeInflater extends LayoutInflater {
resourceId = 0;
}
RecyclerViewUtil.setAdapter(view, bc, mLayoutlibCallback, resourceId);
} else if (ReflectionUtils.isInstanceOf(view, DrawerLayoutUtil.CN_DRAWER_LAYOUT)) {
String attrVal = attrs.getAttributeValue(BridgeConstants.NS_TOOLS_URI,
BridgeConstants.ATTR_OPEN_DRAWER);
if (attrVal != null) {
getDrawerLayoutMap().put(view, attrVal);
}
}
}
}
@@ -312,4 +324,28 @@ public final class BridgeInflater extends LayoutInflater {
return viewKey;
}
public void postInflateProcess(View view) {
if (mOpenDrawerLayouts != null) {
String gravity = mOpenDrawerLayouts.get(view);
if (gravity != null) {
DrawerLayoutUtil.openDrawer(view, gravity);
}
mOpenDrawerLayouts.remove(view);
}
}
@NonNull
private Map<View, String> getDrawerLayoutMap() {
if (mOpenDrawerLayouts == null) {
mOpenDrawerLayouts = new HashMap<View, String>(4);
}
return mOpenDrawerLayouts;
}
public void onDoneInflation() {
if (mOpenDrawerLayouts != null) {
mOpenDrawerLayouts.clear();
}
}
}

View File

@@ -54,4 +54,5 @@ public class BridgeConstants {
/** Attribute in the tools namespace used to specify layout manager for RecyclerView. */
@SuppressWarnings("SpellCheckingInspection")
public static final String ATTR_LIST_ITEM = "listitem";
public static final String ATTR_OPEN_DRAWER = "openDrawer";
}

View File

@@ -0,0 +1,63 @@
/*
* Copyright (C) 2015 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.support;
import com.android.ide.common.rendering.api.LayoutLog;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import android.annotation.Nullable;
import android.view.View;
import static android.view.Gravity.END;
import static android.view.Gravity.LEFT;
import static android.view.Gravity.RIGHT;
import static android.view.Gravity.START;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
public class DrawerLayoutUtil {
public static final String CN_DRAWER_LAYOUT = "android.support.v4.widget.DrawerLayout";
public static void openDrawer(View drawerLayout, @Nullable String drawerGravity) {
int gravity = -1;
if ("left".equals(drawerGravity)) {
gravity = LEFT;
} else if ("right".equals(drawerGravity)) {
gravity = RIGHT;
} else if ("start".equals(drawerGravity)) {
gravity = START;
} else if ("end".equals(drawerGravity)) {
gravity = END;
}
if (gravity > 0) {
openDrawer(drawerLayout, gravity);
}
}
private static void openDrawer(View drawerLayout, int gravity) {
try {
invoke(getMethod(drawerLayout.getClass(), "openDrawer", int.class), drawerLayout,
gravity);
} catch (ReflectionException e) {
Bridge.getLog().error(LayoutLog.TAG_BROKEN, "Unable to open navigation drawer",
getCause(e), null);
}
}
}

View File

@@ -21,6 +21,7 @@ import com.android.ide.common.rendering.api.LayoutlibCallback;
import com.android.layoutlib.bridge.Bridge;
import com.android.layoutlib.bridge.android.BridgeContext;
import com.android.layoutlib.bridge.android.RenderParamsFlags;
import com.android.layoutlib.bridge.util.ReflectionUtils;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -30,6 +31,7 @@ import android.view.View;
import java.lang.reflect.Method;
import static com.android.layoutlib.bridge.util.ReflectionUtils.ReflectionException;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getCause;
import static com.android.layoutlib.bridge.util.ReflectionUtils.getMethod;
import static com.android.layoutlib.bridge.util.ReflectionUtils.invoke;
@@ -70,11 +72,6 @@ public class RecyclerViewUtil {
}
}
private static Throwable getCause(Throwable throwable) {
Throwable cause = throwable.getCause();
return cause == null ? throwable : cause;
}
private static void setLayoutManager(@NonNull View recyclerView, @NonNull BridgeContext context,
@NonNull LayoutlibCallback callback) throws ReflectionException {
if (getLayoutManager(recyclerView) == null) {

View File

@@ -423,6 +423,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
// post-inflate process. For now this supports TabHost/TabWidget
postInflateProcess(view, params.getLayoutlibCallback(), isPreference ? view : null);
mInflater.onDoneInflation();
setActiveToolbar(view, context, params);
@@ -1342,6 +1343,7 @@ public class RenderSessionImpl extends RenderAction<SessionParams> {
}
}
} else if (view instanceof ViewGroup) {
mInflater.postInflateProcess(view);
ViewGroup group = (ViewGroup) view;
final int count = group.getChildCount();
for (int c = 0; c < count; c++) {

View File

@@ -27,7 +27,7 @@ import java.lang.reflect.Method;
*/
public class ReflectionUtils {
@Nullable
@NonNull
public static Method getMethod(@NonNull Class<?> clazz, @NonNull String name,
@Nullable Class<?>... params) throws ReflectionException {
try {
@@ -67,6 +67,12 @@ public class ReflectionUtils {
return false;
}
@NonNull
public static Throwable getCause(@NonNull Throwable throwable) {
Throwable cause = throwable.getCause();
return cause == null ? throwable : cause;
}
/**
* Wraps all reflection related exceptions. Created since ReflectiveOperationException was
* introduced in 1.7 and we are still on 1.6