CustomBar.java revision 02d2b5a4031c80bfe1012ce2f4f7b3695762abd9
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.ResourceHelper; 26import com.android.resources.Density; 27import com.android.resources.ResourceType; 28 29import org.kxml2.io.KXmlParser; 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 protected abstract TextView getStyleableTextView(); 62 63 protected CustomBar(Context context, Density density, String layoutPath) 64 throws XmlPullParserException { 65 super(context); 66 setOrientation(LinearLayout.HORIZONTAL); 67 setGravity(Gravity.CENTER_VERTICAL); 68 69 LayoutInflater inflater = (LayoutInflater) getContext().getSystemService( 70 Context.LAYOUT_INFLATER_SERVICE); 71 72 KXmlParser parser = new KXmlParser(); 73 parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true); 74 parser.setInput( 75 getClass().getResourceAsStream(layoutPath), 76 "UTF8"); 77 78 BridgeXmlBlockParser bridgeParser = new BridgeXmlBlockParser( 79 parser, (BridgeContext) context, false /*platformFile*/); 80 81 try { 82 inflater.inflate(bridgeParser, this, true); 83 } finally { 84 bridgeParser.ensurePopped(); 85 } 86 } 87 88 private InputStream getIcon(String iconName, Density[] densityInOut, String[] pathOut, 89 boolean tryOtherDensities) { 90 // current density 91 Density density = densityInOut[0]; 92 93 // bitmap url relative to this class 94 pathOut[0] = "/bars/" + density.getResourceValue() + "/" + iconName; 95 96 InputStream stream = getClass().getResourceAsStream(pathOut[0]); 97 if (stream == null && tryOtherDensities) { 98 for (Density d : Density.values()) { 99 if (d != density) { 100 densityInOut[0] = d; 101 stream = getIcon(iconName, densityInOut, pathOut, false /*tryOtherDensities*/); 102 if (stream != null) { 103 return stream; 104 } 105 } 106 } 107 } 108 109 return stream; 110 } 111 112 protected void loadIcon(int index, String iconName, Density density) { 113 View child = getChildAt(index); 114 if (child instanceof ImageView) { 115 ImageView imageView = (ImageView) child; 116 117 String[] pathOut = new String[1]; 118 Density[] densityInOut = new Density[] { density }; 119 InputStream stream = getIcon(iconName, densityInOut, pathOut, 120 true /*tryOtherDensities*/); 121 density = densityInOut[0]; 122 123 if (stream != null) { 124 // look for a cached bitmap 125 Bitmap bitmap = Bridge.getCachedBitmap(pathOut[0], true /*isFramework*/); 126 if (bitmap == null) { 127 try { 128 bitmap = Bitmap_Delegate.createBitmap(stream, false /*isMutable*/, density); 129 Bridge.setCachedBitmap(pathOut[0], bitmap, true /*isFramework*/); 130 } catch (IOException e) { 131 return; 132 } 133 } 134 135 if (bitmap != null) { 136 BitmapDrawable drawable = new BitmapDrawable(getContext().getResources(), 137 bitmap); 138 imageView.setBackgroundDrawable(drawable); 139 } 140 } 141 } 142 } 143 144 protected void loadIcon(int index, String iconReference) { 145 ResourceValue value = getResourceValue(iconReference); 146 if (value != null) { 147 loadIcon(index, value); 148 } 149 } 150 151 protected Drawable loadIcon(int index, ResourceType type, String name) { 152 BridgeContext bridgeContext = (BridgeContext) mContext; 153 RenderResources res = bridgeContext.getRenderResources(); 154 155 // find the resource 156 ResourceValue value = res.getFrameworkResource(type, name); 157 158 // resolve it if needed 159 value = res.resolveResValue(value); 160 return loadIcon(index, value); 161 } 162 163 private Drawable loadIcon(int index, ResourceValue value) { 164 View child = getChildAt(index); 165 if (child instanceof ImageView) { 166 ImageView imageView = (ImageView) child; 167 168 Drawable drawable = ResourceHelper.getDrawable( 169 value, (BridgeContext) mContext); 170 if (drawable != null) { 171 imageView.setBackgroundDrawable(drawable); 172 } 173 174 return drawable; 175 } 176 177 return null; 178 } 179 180 protected TextView setText(int index, String stringReference) { 181 View child = getChildAt(index); 182 if (child instanceof TextView) { 183 TextView textView = (TextView) child; 184 ResourceValue value = getResourceValue(stringReference); 185 if (value != null) { 186 textView.setText(value.getValue()); 187 } else { 188 textView.setText(stringReference); 189 } 190 return textView; 191 } 192 193 return null; 194 } 195 196 protected void setStyle(String themeEntryName) { 197 198 BridgeContext bridgeContext = (BridgeContext) mContext; 199 RenderResources res = bridgeContext.getRenderResources(); 200 201 ResourceValue value = res.findItemInTheme(themeEntryName); 202 value = res.resolveResValue(value); 203 204 if (value instanceof StyleResourceValue == false) { 205 return; 206 } 207 208 StyleResourceValue style = (StyleResourceValue) value; 209 210 // get the background 211 ResourceValue backgroundValue = res.findItemInStyle(style, "background"); 212 backgroundValue = res.resolveResValue(backgroundValue); 213 if (backgroundValue != null) { 214 Drawable d = ResourceHelper.getDrawable(backgroundValue, bridgeContext); 215 if (d != null) { 216 setBackgroundDrawable(d); 217 } 218 } 219 220 TextView textView = getStyleableTextView(); 221 if (textView != null) { 222 // get the text style 223 ResourceValue textStyleValue = res.findItemInStyle(style, "titleTextStyle"); 224 textStyleValue = res.resolveResValue(textStyleValue); 225 if (textStyleValue instanceof StyleResourceValue) { 226 StyleResourceValue textStyle = (StyleResourceValue) textStyleValue; 227 228 ResourceValue textSize = res.findItemInStyle(textStyle, "textSize"); 229 textSize = res.resolveResValue(textSize); 230 231 if (textSize != null) { 232 TypedValue out = new TypedValue(); 233 if (ResourceHelper.stringToFloat(textSize.getValue(), out)) { 234 textView.setTextSize( 235 out.getDimension(bridgeContext.getResources().mMetrics)); 236 } 237 } 238 239 240 ResourceValue textColor = res.findItemInStyle(textStyle, "textColor"); 241 textColor = res.resolveResValue(textColor); 242 if (textColor != null) { 243 ColorStateList stateList = ResourceHelper.getColorStateList( 244 textColor, bridgeContext); 245 if (stateList != null) { 246 textView.setTextColor(stateList); 247 } 248 } 249 } 250 } 251 } 252 253 private ResourceValue getResourceValue(String reference) { 254 BridgeContext bridgeContext = (BridgeContext) mContext; 255 RenderResources res = bridgeContext.getRenderResources(); 256 257 // find the resource 258 ResourceValue value = res.findResValue(reference, false /*isFramework*/); 259 260 // resolve it if needed 261 return res.resolveResValue(value); 262 } 263} 264