Fix AppCompat action bar theming.
Use themed context to inflate the action bar when AppCompat is used. Also fix minor issues exposed as a result. - Set project callback when LayoutInflater is created by LayoutInflater.from(context). - Remove duplication of code to get base context from context wrapper. Bug: http://b.android.com/159711 Change-Id: I379ba2ba71c0ef547460987c3aa5db521c7de967
This commit is contained in:
@@ -35,6 +35,8 @@ import android.util.AttributeSet;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import static com.android.layoutlib.bridge.android.BridgeContext.getBaseContext;
|
||||
|
||||
/**
|
||||
* Custom implementation of {@link LayoutInflater} to handle custom views.
|
||||
*/
|
||||
@@ -56,7 +58,12 @@ public final class BridgeInflater extends LayoutInflater {
|
||||
|
||||
protected BridgeInflater(LayoutInflater original, Context newContext) {
|
||||
super(original, newContext);
|
||||
mProjectCallback = null;
|
||||
newContext = getBaseContext(newContext);
|
||||
if (newContext instanceof BridgeContext) {
|
||||
mProjectCallback = ((BridgeContext) newContext).getProjectCallback();
|
||||
} else {
|
||||
mProjectCallback = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,9 +158,7 @@ public final class BridgeInflater extends LayoutInflater {
|
||||
@Override
|
||||
public View inflate(int resource, ViewGroup root) {
|
||||
Context context = getContext();
|
||||
while (context instanceof ContextThemeWrapper) {
|
||||
context = ((ContextThemeWrapper) context).getBaseContext();
|
||||
}
|
||||
context = getBaseContext(context);
|
||||
if (context instanceof BridgeContext) {
|
||||
BridgeContext bridgeContext = (BridgeContext)context;
|
||||
|
||||
@@ -217,9 +222,7 @@ public final class BridgeInflater extends LayoutInflater {
|
||||
|
||||
private void setupViewInContext(View view, AttributeSet attrs) {
|
||||
Context context = getContext();
|
||||
while (context instanceof ContextThemeWrapper) {
|
||||
context = ((ContextThemeWrapper) context).getBaseContext();
|
||||
}
|
||||
context = getBaseContext(context);
|
||||
if (context instanceof BridgeContext) {
|
||||
BridgeContext bc = (BridgeContext) context;
|
||||
// get the view key
|
||||
|
||||
@@ -48,9 +48,7 @@ public class MenuInflater_Delegate {
|
||||
AttributeSet attrs) {
|
||||
if (menuItem instanceof BridgeMenuItemImpl) {
|
||||
Context context = thisInflater.getContext();
|
||||
while (context instanceof ContextThemeWrapper) {
|
||||
context = ((ContextThemeWrapper) context).getBaseContext();
|
||||
}
|
||||
context = BridgeContext.getBaseContext(context);
|
||||
if (context instanceof BridgeContext) {
|
||||
Object viewKey = BridgeInflater.getViewKeyFromParser(
|
||||
attrs, ((BridgeContext) context), null, false);
|
||||
|
||||
@@ -122,9 +122,7 @@ public class ViewGroup_Delegate {
|
||||
@NonNull
|
||||
private static DisplayMetrics getMetrics(View view) {
|
||||
Context context = view.getContext();
|
||||
while (context instanceof ContextThemeWrapper) {
|
||||
context = ((ContextThemeWrapper) context).getBaseContext();
|
||||
}
|
||||
context = BridgeContext.getBaseContext(context);
|
||||
if (context instanceof BridgeContext) {
|
||||
return ((BridgeContext) context).getMetrics();
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.android.internal.view.menu;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
|
||||
import android.content.Context;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.View;
|
||||
|
||||
/**
|
||||
@@ -42,9 +41,7 @@ public class BridgeMenuItemImpl extends MenuItemImpl {
|
||||
CharSequence title, int showAsAction) {
|
||||
super(menu, group, id, categoryOrder, ordering, title, showAsAction);
|
||||
Context context = menu.getContext();
|
||||
while (context instanceof ContextThemeWrapper) {
|
||||
context = ((ContextThemeWrapper) context).getBaseContext();
|
||||
}
|
||||
context = BridgeContext.getBaseContext(context);
|
||||
if (context instanceof BridgeContext) {
|
||||
mContext = ((BridgeContext) context);
|
||||
}
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.content.BroadcastReceiver;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.ContextWrapper;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.IntentSender;
|
||||
@@ -924,6 +925,13 @@ public final class BridgeContext extends Context {
|
||||
return defValue;
|
||||
}
|
||||
|
||||
public static Context getBaseContext(Context context) {
|
||||
while (context instanceof ContextWrapper) {
|
||||
context = ((ContextWrapper) context).getBaseContext();
|
||||
}
|
||||
return context;
|
||||
}
|
||||
|
||||
//------------ NOT OVERRIDEN --------------------
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,11 +21,15 @@ import com.android.annotations.Nullable;
|
||||
import com.android.ide.common.rendering.api.RenderResources;
|
||||
import com.android.ide.common.rendering.api.ResourceValue;
|
||||
import com.android.ide.common.rendering.api.SessionParams;
|
||||
import com.android.ide.common.rendering.api.StyleResourceValue;
|
||||
import com.android.layoutlib.bridge.android.BridgeContext;
|
||||
import com.android.layoutlib.bridge.impl.ResourceHelper;
|
||||
import com.android.resources.ResourceType;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
@@ -84,6 +88,27 @@ public class AppCompatActionBar extends BridgeActionBar {
|
||||
"abc_screen_toolbar");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutInflater getInflater(BridgeContext context) {
|
||||
// Other than the resource resolution part, the code has been taken from the support
|
||||
// library. see code from line 269 onwards in
|
||||
// https://android.googlesource.com/platform/frameworks/support/+/android-5.1.0_r1/v7/appcompat/src/android/support/v7/app/ActionBarActivityDelegateBase.java
|
||||
Context themedContext = context;
|
||||
RenderResources resources = context.getRenderResources();
|
||||
ResourceValue actionBarTheme = resources.findItemInTheme("actionBarTheme", false);
|
||||
if (actionBarTheme != null) {
|
||||
// resolve it, if needed.
|
||||
actionBarTheme = resources.resolveResValue(actionBarTheme);
|
||||
}
|
||||
if (actionBarTheme instanceof StyleResourceValue) {
|
||||
int styleId = context.getDynamicIdByStyle(((StyleResourceValue) actionBarTheme));
|
||||
if (styleId != 0) {
|
||||
themedContext = new ContextThemeWrapper(context, styleId);
|
||||
}
|
||||
}
|
||||
return LayoutInflater.from(themedContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setTitle(CharSequence title) {
|
||||
if (title != null && mWindowDecorActionBar != null) {
|
||||
|
||||
@@ -81,7 +81,7 @@ public abstract class BridgeActionBar {
|
||||
}
|
||||
|
||||
// Inflate action bar layout.
|
||||
mDecorContent = LayoutInflater.from(context).inflate(layoutId, mEnclosingLayout, true);
|
||||
mDecorContent = getInflater(context).inflate(layoutId, mEnclosingLayout, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -92,6 +92,10 @@ public abstract class BridgeActionBar {
|
||||
*/
|
||||
protected abstract ResourceValue getLayoutResource(BridgeContext context);
|
||||
|
||||
protected LayoutInflater getInflater(BridgeContext context) {
|
||||
return LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
protected void setContentRoot(@NonNull FrameLayout contentRoot) {
|
||||
mContentRoot = contentRoot;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user