CustomBar.java revision 553a4e91385111f20ddf426f81b3193b9e951762
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.layoutlib.bridge.bars; 18 19import com.android.ide.common.rendering.api.RenderResources; 20import com.android.ide.common.rendering.api.ResourceValue; 21import com.android.ide.common.rendering.api.StyleResourceValue; 22import com.android.layoutlib.bridge.Bridge; 23import com.android.layoutlib.bridge.android.BridgeContext; 24import com.android.layoutlib.bridge.android.BridgeXmlBlockParser; 25import com.android.layoutlib.bridge.impl.ParserFactory; 26import com.android.layoutlib.bridge.impl.ResourceHelper; 27import com.android.resources.Density; 28import com.android.resources.LayoutDirection; 29 30import org.xmlpull.v1.XmlPullParser; 31import org.xmlpull.v1.XmlPullParserException; 32 33import android.content.Context; 34import android.content.res.ColorStateList; 35import android.graphics.Bitmap; 36import android.graphics.Bitmap_Delegate; 37import android.graphics.drawable.BitmapDrawable; 38import android.graphics.drawable.Drawable; 39import android.util.TypedValue; 40import android.view.Gravity; 41import android.view.LayoutInflater; 42import android.view.View; 43import android.widget.ImageView; 44import android.widget.LinearLayout; 45import android.widget.TextView; 46 47import java.io.IOException; 48import java.io.InputStream; 49 50/** 51 * Base "bar" class for the window decor around the the edited layout. 52 * This is basically an horizontal layout that loads a given layout on creation (it is read 53 * through {@link Class#getResourceAsStream(String)}). 54 * 55 * The given layout should be a merge layout so that all the children belong to this class directly. 56 * 57 * It also provides a few utility methods to configure the content of the layout. 58 */ 59abstract class CustomBar extends LinearLayout { 60 61 62 private final int mSimulatedPlatformVersion; 63 64 protected abstract TextView getStyleableTextView(); 65 66 protected CustomBar(Context context, int orientation, String layoutPath, 67 String name, int simulatedPlatformVersion) throws XmlPullParserException { 68 super(context); 69 mSimulatedPlatformVersion = simulatedPlatformVersion; 70 setOrientation(orientation); 71 if (orientation == LinearLayout.HORIZONTAL) { 72 setGravity(Gravity.CENTER_VERTICAL); 73 } else { 74 setGravity(Gravity.CENTER_HORIZONTAL); 75 } 76 77 LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( 78 Context.LAYOUT_INFLATER_SERVICE); 79 80 XmlPullParser parser = ParserFactory.create(getClass().getResourceAsStream(layoutPath), 81 name); 82 83 BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( 84 parser, (BridgeContext) context, false /*platformFile*/); 85 86 try { 87 inflater.inflate(bridgeParser, this, true); 88 } finally { 89 bridgeParser.ensurePopped(); 90 } 91 } 92 93 protected void loadIcon(int index, String iconName, Density density) { 94 loadIcon(index, iconName, density, false); 95 } 96 97 protected void loadIcon(int index, String iconName, Density density, boolean isRtl) { 98 View child = getChildAt(index); 99 if (child instanceof ImageView) { 100 ImageView imageView = (ImageView) child; 101 102 LayoutDirection dir = isRtl ? LayoutDirection.RTL : null; 103 IconLoader iconLoader = new IconLoader(iconName, density, mSimulatedPlatformVersion, 104 dir); 105 InputStream stream = iconLoader.getIcon(); 106 107 if (stream != null) { 108 density = iconLoader.getDensity(); 109 String path = iconLoader.getPath(); 110 // look for a cached bitmap 111 Bitmap bitmap = Bridge.getCachedBitmap(path, true /*isFramework*/); 112 if (bitmap == null) { 113 try { 114 bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density); 115 Bridge.setCachedBitmap(path, bitmap, true /*isFramework*/); 116 } catch (IOException e) { 117 return; 118 } 119 } 120 121 if (bitmap != null) { 122 BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), 123 bitmap); 124 imageView.setImageDrawable(drawable); 125 } 126 } 127 } 128 } 129 130 protected TextView setText(int index, String string, boolean reference) { 131 View child = getChildAt(index); 132 if (child instanceof TextView) { 133 TextView textView = (TextView) child; 134 setText(textView, string, reference); 135 return textView; 136 } 137 138 return null; 139 } 140 141 private void setText(TextView textView, String string, boolean reference) { 142 if (reference) { 143 ResourceValue value = getResourceValue(string); 144 if (value != null) { 145 string = value.getValue(); 146 } 147 } 148 textView.setText(string); 149 } 150 151 protected void setStyle(String themeEntryName) { 152 153 BridgeContext bridgeContext = (BridgeContext) mContext; 154 RenderResources res = bridgeContext.getRenderResources(); 155 156 ResourceValue value = res.findItemInTheme(themeEntryName, true /*isFrameworkAttr*/); 157 value = res.resolveResValue(value); 158 159 if (!(value instanceof StyleResourceValue)) { 160 return; 161 } 162 163 StyleResourceValue style = (StyleResourceValue) value; 164 165 // get the background 166 ResourceValue backgroundValue = res.findItemInStyle(style, "background", 167 true /*isFrameworkAttr*/); 168 backgroundValue = res.resolveResValue(backgroundValue); 169 if (backgroundValue != null) { 170 Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext); 171 if (d != null) { 172 setBackground(d); 173 } 174 } 175 176 TextView textView = getStyleableTextView(); 177 if (textView != null) { 178 // get the text style 179 ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle", 180 true /*isFrameworkAttr*/); 181 textStyleValue = res.resolveResValue(textStyleValue); 182 if (textStyleValue instanceof StyleResourceValue) { 183 StyleResourceValue textStyle = (StyleResourceValue) textStyleValue; 184 185 ResourceValue textSize = res.findItemInStyle(textStyle, "textSize", 186 true /*isFrameworkAttr*/); 187 textSize = res.resolveResValue(textSize); 188 189 if (textSize != null) { 190 TypedValue out = new TypedValue(); 191 if (ResourceHelper.parseFloatAttribute("textSize", textSize.getValue(), out, 192 true /*requireUnit*/)) { 193 textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, 194 out.getDimension(bridgeContext.getResources().getDisplayMetrics())); 195 } 196 } 197 198 199 ResourceValue textColor = res.findItemInStyle(textStyle, "textColor", 200 true /*isFrameworkAttr*/); 201 textColor = res.resolveResValue(textColor); 202 if (textColor != null) { 203 ColorStateList stateList = ResourceHelper.getColorStateList( 204 textColor, bridgeContext); 205 if (stateList != null) { 206 textView.setTextColor(stateList); 207 } 208 } 209 } 210 } 211 } 212 213 private ResourceValue getResourceValue(String reference) { 214 BridgeContext bridgeContext = (BridgeContext) mContext; 215 RenderResources res = bridgeContext.getRenderResources(); 216 217 // find the resource 218 ResourceValue value = res.findResValue(reference, false /*isFramework*/); 219 220 // resolve it if needed 221 return res.resolveResValue(value); 222 } 223} 224