19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage android.view; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 199c1223a71397b565f38015c07cae57a5015a6500Romain Guyimport android.graphics.Canvas; 209c1223a71397b565f38015c07cae57a5015a6500Romain Guyimport android.os.Handler; 219c1223a71397b565f38015c07cae57a5015a6500Romain Guyimport android.os.Message; 2209f7b93a184d12e5ed584206d903982b3e0915e5Romain Guyimport android.os.Trace; 239c1223a71397b565f38015c07cae57a5015a6500Romain Guyimport android.widget.FrameLayout; 240810b63739c9981f993063749f804b54faed0ba5Alan Viverette 253030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunneimport org.xmlpull.v1.XmlPullParser; 263030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunneimport org.xmlpull.v1.XmlPullParserException; 273030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 290810b63739c9981f993063749f804b54faed0ba5Alan Viveretteimport android.content.res.Resources; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.TypedArray; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.res.XmlResourceParser; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.AttributeSet; 330810b63739c9981f993063749f804b54faed0ba5Alan Viveretteimport android.util.Log; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Xml; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.lang.reflect.Constructor; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 4193dc642eaf48e3db58c4929df26283fbc5fd663fScott Main * Instantiates a layout XML file into its corresponding {@link android.view.View} 4293dc642eaf48e3db58c4929df26283fbc5fd663fScott Main * objects. It is never used directly. Instead, use 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.app.Activity#getLayoutInflater()} or 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Context#getSystemService} to retrieve a standard LayoutInflater instance 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that is already hooked up to the current context and correctly configured 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * for the device you are running on. For example: 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService 49bd6fda11d287ba8ac749e06053dc9488653d1471Christian Mehlmauer * (Context.LAYOUT_INFLATER_SERVICE);</pre> 50579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * To create a new LayoutInflater with an additional {@link Factory} for your 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * own views, you can use {@link #cloneInContext} to clone an existing 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ViewFactory, and then call {@link #setFactory} on it to include your 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Factory. 56579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * For performance reasons, view inflation relies heavily on pre-processing of 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML files that is done at build time. Therefore, it is not currently possible 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to use LayoutInflater with an XmlPullParser over a plain XML file at runtime; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * it only works with an XmlPullParser returned from a compiled resource 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * (R.<em>something</em> file.) 63579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see Context#getSystemService 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic abstract class LayoutInflater { 670810b63739c9981f993063749f804b54faed0ba5Alan Viverette private static final String TAG = LayoutInflater.class.getSimpleName(); 680810b63739c9981f993063749f804b54faed0ba5Alan Viverette private static final boolean DEBUG = false; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This field should be made private, so it is hidden from the SDK. 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected final Context mContext; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these are optional, set by the caller 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mFactorySet; 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Factory mFactory; 79625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn private Factory2 mFactory2; 80420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn private Factory2 mPrivateFactory; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Filter mFilter; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 837f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet final Object[] mConstructorArgs = new Object[2]; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 857f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet static final Class<?>[] mConstructorSignature = new Class[] { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Context.class, AttributeSet.class}; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 883030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne private static final HashMap<String, Constructor<? extends View>> sConstructorMap = 893030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne new HashMap<String, Constructor<? extends View>>(); 90579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String, Boolean> mFilterMap; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_MERGE = "merge"; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_INCLUDE = "include"; 959c1223a71397b565f38015c07cae57a5015a6500Romain Guy private static final String TAG_1995 = "blink"; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG_REQUEST_FOCUS = "requestFocus"; 97451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette private static final String TAG_TAG = "tag"; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99ef259e4484deb69ada76970e26f2b2542b1fe4c1Alan Viverette private static final int[] ATTRS_THEME = new int[] { 100ef259e4484deb69ada76970e26f2b2542b1fe4c1Alan Viverette com.android.internal.R.attr.theme }; 10124927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * to be inflated. 105579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Filter { 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hook to allow clients of the LayoutInflater to restrict the set of Views 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that are allowed to be inflated. 111579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param clazz The class object for the View that is about to be inflated 113579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return True if this class is allowed to be inflated, or false otherwise 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 116e6ac8b9aade9443ab8456c8f7a47cdfba3b70266Gilles Debunne @SuppressWarnings("unchecked") 117e6ac8b9aade9443ab8456c8f7a47cdfba3b70266Gilles Debunne boolean onLoadClass(Class clazz); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 119579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public interface Factory { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Hook you can supply that is called when inflating from a LayoutInflater. 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You can use this to customize the tag names available in your XML 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * layout files. 125579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note that it is good practice to prefix these custom names with your 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * package (i.e., com.coolcompany.apps) to avoid conflicts with system 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * names. 130579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name Tag name to be inflated. 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The context the view is being created in. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs Inflation attributes as specified in XML file. 134579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return View Newly created view. Return null for the default 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * behavior. 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View onCreateView(String name, Context context, AttributeSet attrs); 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 141625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn public interface Factory2 extends Factory { 142625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn /** 143625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * Version of {@link #onCreateView(String, Context, AttributeSet)} 144625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * that also supplies the parent that the view created view will be 145625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * placed in. 146625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * 147625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param parent The parent that the created view will be placed 148625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * in; <em>note that this may be null</em>. 149625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param name Tag name to be inflated. 150625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param context The context the view is being created in. 151625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param attrs Inflation attributes as specified in XML file. 152625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * 153625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @return View Newly created view. Return null for the default 154625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * behavior. 155625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn */ 156625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn public View onCreateView(View parent, String name, Context context, AttributeSet attrs); 157625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 158625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn 159625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn private static class FactoryMerger implements Factory2 { 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Factory mF1, mF2; 161625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn private final Factory2 mF12, mF22; 162579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 163625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn FactoryMerger(Factory f1, Factory2 f12, Factory f2, Factory2 f22) { 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mF1 = f1; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mF2 = f2; 166625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mF12 = f12; 167625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mF22 = f22; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 169579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View onCreateView(String name, Context context, AttributeSet attrs) { 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View v = mF1.onCreateView(name, context, attrs); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (v != null) return v; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mF2.onCreateView(name, context, attrs); 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 175625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn 176625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { 177625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn View v = mF12 != null ? mF12.onCreateView(parent, name, context, attrs) 178625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn : mF1.onCreateView(name, context, attrs); 179625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn if (v != null) return v; 180625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn return mF22 != null ? mF22.onCreateView(parent, name, context, attrs) 181625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn : mF2.onCreateView(name, context, attrs); 182625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 184579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new LayoutInflater instance associated with a particular Context. 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Applications will almost always want to use 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link Context#getSystemService Context.getSystemService()} to retrieve 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}. 190579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context The Context in which this LayoutInflater will create its 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Views; most importantly, this supplies the theme from which the default 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * values for their attributes are retrieved. 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LayoutInflater(Context context) { 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a new LayoutInflater instance that is a copy of an existing 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * LayoutInflater, optionally with its Context changed. For use in 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * implementing {@link #cloneInContext}. 203579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param original The original LayoutInflater to copy. 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param newContext The new Context to use. 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected LayoutInflater(LayoutInflater original, Context newContext) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = newContext; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFactory = original.mFactory; 210625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mFactory2 = original.mFactory2; 211420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn mPrivateFactory = original.mPrivateFactory; 2120c7bb33e03392416fc98c27738d1bcca386a6b2fDan Sandler setFilter(original.mFilter); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 214579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Obtains the LayoutInflater from the given context. 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static LayoutInflater from(Context context) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LayoutInflater LayoutInflater = 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LayoutInflater == null) { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new AssertionError("LayoutInflater not found."); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return LayoutInflater; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Create a copy of the existing LayoutInflater object, with the copy 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * pointing to a different Context than the original. This is used by 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link ContextThemeWrapper} to create a new LayoutInflater to go along 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with the new Context theme. 232579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param newContext The new Context to associate with the new LayoutInflater. 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * May be the same as the original Context if desired. 235579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return Returns a brand spanking new LayoutInflater object associated with 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the given Context. 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public abstract LayoutInflater cloneInContext(Context newContext); 240579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Return the context we are running in, for access to resources, class 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * loader, etc. 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Context getContext() { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mContext; 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 250625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * Return the current {@link Factory} (or null). This is called on each element 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * name. If the factory returns a View, add that to the hierarchy. If it 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returns null, proceed to call onCreateView(name). 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final Factory getFactory() { 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFactory; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 259625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * Return the current {@link Factory2}. Returns null if no factory is set 260625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * or the set factory does not implement the {@link Factory2} interface. 261625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * This is called on each element 262625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * name. If the factory returns a View, add that to the hierarchy. If it 263625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * returns null, proceed to call onCreateView(name). 264625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn */ 265625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn public final Factory2 getFactory2() { 266625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn return mFactory2; 267625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 268625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn 269625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn /** 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Attach a custom Factory interface for creating views while using 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this LayoutInflater. This must not be null, and can only be set once; 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * after setting, you can not change the factory. This is 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called on each element name as the xml is parsed. If the factory returns 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * a View, that is added to the hierarchy. If it returns null, the next 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * factory default {@link #onCreateView} method is called. 276579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p>If you have an existing 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * LayoutInflater and want to add your own factory to it, use 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link #cloneInContext} to clone the existing instance and then you 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can use this function (once) on the returned new instance. This will 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * merge your own factory with whatever factory the original instance is 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * using. 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFactory(Factory factory) { 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFactorySet) { 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("A factory has already been set on this LayoutInflater"); 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (factory == null) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new NullPointerException("Given factory can not be null"); 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFactorySet = true; 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFactory == null) { 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFactory = factory; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 295625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mFactory = new FactoryMerger(factory, null, mFactory, mFactory2); 296625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 297625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 298625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn 299625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn /** 300625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * Like {@link #setFactory}, but allows you to set a {@link Factory2} 301625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * interface. 302625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn */ 303625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn public void setFactory2(Factory2 factory) { 304625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn if (mFactorySet) { 305625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn throw new IllegalStateException("A factory has already been set on this LayoutInflater"); 306625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 307625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn if (factory == null) { 308625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn throw new NullPointerException("Given factory can not be null"); 309625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 310625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mFactorySet = true; 311625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn if (mFactory == null) { 312625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn mFactory = mFactory2 = factory; 313625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } else { 314371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell mFactory = mFactory2 = new FactoryMerger(factory, factory, mFactory, mFactory2); 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 319420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn * @hide for use by framework 320420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn */ 321420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn public void setPrivateFactory(Factory2 factory) { 322371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell if (mPrivateFactory == null) { 323371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell mPrivateFactory = factory; 324371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell } else { 325371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell mPrivateFactory = new FactoryMerger(factory, factory, mPrivateFactory, mPrivateFactory); 326371a809179c843d7ae661a10bc9b4b8cfcaff566Adam Powell } 327420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn } 328420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn 329420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn /** 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The {@link Filter} currently used by this LayoutInflater to restrict the set of Views 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that are allowed to be inflated. 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Filter getFilter() { 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mFilter; 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 336579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * throw an {@link InflateException}. This filter will replace any previous filter set on this 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * LayoutInflater. 342579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param filter The Filter which restricts the set of Views that are allowed to be inflated. 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This filter will replace any previous filter set on this LayoutInflater. 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setFilter(Filter filter) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilter = filter; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (filter != null) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilterMap = new HashMap<String, Boolean>(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflate a new view hierarchy from the specified xml resource. Throws 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InflateException} if there is an error. 356579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource ID for an XML layout resource to load (e.g., 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>R.layout.main_page</code>) 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param root Optional view to be the parent of the generated hierarchy. 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The root View of the inflated hierarchy. If root was supplied, 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this is the root View; otherwise it is the root of the inflated 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML file. 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View inflate(int resource, ViewGroup root) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return inflate(resource, root, root != null); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflate a new view hierarchy from the specified xml node. Throws 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InflateException} if there is an error. * 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em><strong>Important</strong></em> For performance 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reasons, view inflation relies heavily on pre-processing of XML files 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that is done at build time. Therefore, it is not currently possible to 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. 376579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parser XML dom node containing the description of the view 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy. 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param root Optional view to be the parent of the generated hierarchy. 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The root View of the inflated hierarchy. If root was supplied, 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * this is the root View; otherwise it is the root of the inflated 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * XML file. 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View inflate(XmlPullParser parser, ViewGroup root) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return inflate(parser, root, root != null); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflate a new view hierarchy from the specified xml resource. Throws 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InflateException} if there is an error. 391579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param resource ID for an XML layout resource to load (e.g., 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <code>R.layout.main_page</code>) 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param root Optional view to be the parent of the generated hierarchy (if 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>attachToRoot</em> is true), or else simply an object that 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * provides a set of LayoutParams values for root of the returned 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy (if <em>attachToRoot</em> is false.) 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attachToRoot Whether the inflated hierarchy should be attached to 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the root parameter? If false, root is only used to create the 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * correct subclass of LayoutParams for the root view in the XML. 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The root View of the inflated hierarchy. If root was supplied and 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attachToRoot is true, this is root; otherwise it is the root of 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the inflated XML file. 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View inflate(int resource, ViewGroup root, boolean attachToRoot) { 4060810b63739c9981f993063749f804b54faed0ba5Alan Viverette final Resources res = getContext().getResources(); 4070810b63739c9981f993063749f804b54faed0ba5Alan Viverette if (DEBUG) { 4080810b63739c9981f993063749f804b54faed0ba5Alan Viverette Log.d(TAG, "INFLATING from resource: \"" + res.getResourceName(resource) + "\" (" 4090810b63739c9981f993063749f804b54faed0ba5Alan Viverette + Integer.toHexString(resource) + ")"); 4100810b63739c9981f993063749f804b54faed0ba5Alan Viverette } 4110810b63739c9981f993063749f804b54faed0ba5Alan Viverette 4120810b63739c9981f993063749f804b54faed0ba5Alan Viverette final XmlResourceParser parser = res.getLayout(resource); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return inflate(parser, root, attachToRoot); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.close(); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Inflate a new view hierarchy from the specified XML node. Throws 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link InflateException} if there is an error. 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em><strong>Important</strong></em> For performance 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * reasons, view inflation relies heavily on pre-processing of XML files 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * that is done at build time. Therefore, it is not currently possible to 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * use LayoutInflater with an XmlPullParser over a plain XML file at runtime. 428579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param parser XML dom node containing the description of the view 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy. 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param root Optional view to be the parent of the generated hierarchy (if 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <em>attachToRoot</em> is true), or else simply an object that 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * provides a set of LayoutParams values for root of the returned 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * hierarchy (if <em>attachToRoot</em> is false.) 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attachToRoot Whether the inflated hierarchy should be attached to 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the root parameter? If false, root is only used to create the 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * correct subclass of LayoutParams for the root view in the XML. 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return The root View of the inflated hierarchy. If root was supplied and 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * attachToRoot is true, this is root; otherwise it is the root of 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the inflated XML file. 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mConstructorArgs) { 44409f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy Trace.traceBegin(Trace.TRACE_TAG_VIEW, "inflate"); 44509f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final AttributeSet attrs = Xml.asAttributeSet(parser); 4479dae48e3992521f104cde7c916ed1fb5ee1ecb54Dianne Hackborn Context lastContext = (Context)mConstructorArgs[0]; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mConstructorArgs[0] = mContext; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project View result = root; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Look for the root node. 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type = parser.next()) != XmlPullParser.START_TAG && 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type != XmlPullParser.END_DOCUMENT) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Empty 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException(parser.getPositionDescription() 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": No start tag found!"); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String name = parser.getName(); 465579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("**************************"); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Creating root view: " 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + name); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("**************************"); 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TAG_MERGE.equals(name)) { 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root == null || !attachToRoot) { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("<merge /> can be used only with a valid " 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "ViewGroup root and attachToRoot=true"); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette rInflate(parser, root, attrs, false, false); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Temp is the root view that was found in the xml 48224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette final View temp = createViewFromTag(root, name, attrs, false); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ViewGroup.LayoutParams params = null; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root != null) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("Creating params from root: " + 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create layout params that match root, if supplied 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project params = root.generateLayoutParams(attrs); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!attachToRoot) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set the layout params for temp if we are not 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // attaching. (If we are, we use addView, below) 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project temp.setLayoutParams(params); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("-----> start inflating children"); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inflate all children under temp 50424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette rInflate(parser, temp, attrs, true, true); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.out.println("-----> done inflating children"); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We are supposed to attach all the views we found (int temp) 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // to root. Do that now. 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root != null && attachToRoot) { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project root.addView(temp, params); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Decide whether to return the root that was passed in or the 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // top view found in xml. 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (root == null || !attachToRoot) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = temp; 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (XmlPullParserException e) { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ex = new InflateException(e.getMessage()); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ex.initCause(e); 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ex; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ex = new InflateException( 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getPositionDescription() 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": " + e.getMessage()); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ex.initCause(e); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ex; 5329dae48e3992521f104cde7c916ed1fb5ee1ecb54Dianne Hackborn } finally { 5339dae48e3992521f104cde7c916ed1fb5ee1ecb54Dianne Hackborn // Don't retain static reference on context. 5349dae48e3992521f104cde7c916ed1fb5ee1ecb54Dianne Hackborn mConstructorArgs[0] = lastContext; 5359dae48e3992521f104cde7c916ed1fb5ee1ecb54Dianne Hackborn mConstructorArgs[1] = null; 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 53809f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy Trace.traceEnd(Trace.TRACE_TAG_VIEW); 53909f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Low-level function for instantiating a view by name. This attempts to 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * instantiate a view class of the given <var>name</var> found in this 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * LayoutInflater's ClassLoader. 548579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * <p> 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * There are two things that can happen in an error case: either the 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * exception describing the error will be thrown, or a null will be 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * returned. You must deal with both possibilities -- the former will happen 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the first time createView() is called for a class of a particular name, 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * the latter every time there-after for that class name. 555579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name The full name of the class to be instantiated. 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs The XML attributes supplied for this instance. 558579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 5593030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne * @return View The newly instantiated view, or null. 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public final View createView(String name, String prefix, AttributeSet attrs) 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ClassNotFoundException, InflateException { 5633030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne Constructor<? extends View> constructor = sConstructorMap.get(name); 5643030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne Class<? extends View> clazz = null; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 56709f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy Trace.traceBegin(Trace.TRACE_TAG_VIEW, name); 56809f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (constructor == null) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Class not found in the cache, see if it's real, and try to add it 571d03b880836bcc4fae83a95458e0709cd45aa6313Romain Guy clazz = mContext.getClassLoader().loadClass( 5723030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne prefix != null ? (prefix + name) : name).asSubclass(View.class); 573579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFilter != null && clazz != null) { 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowed = mFilter.onLoadClass(clazz); 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowed) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failNotAllowed(name, prefix, attrs); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project constructor = clazz.getConstructor(mConstructorSignature); 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sConstructorMap.put(name, constructor); 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If we have a filter, apply it to cached constructor 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFilter != null) { 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Have we seen this name before? 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Boolean allowedState = mFilterMap.get(name); 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (allowedState == null) { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // New class -- remember whether it is allowed 589d03b880836bcc4fae83a95458e0709cd45aa6313Romain Guy clazz = mContext.getClassLoader().loadClass( 5903030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne prefix != null ? (prefix + name) : name).asSubclass(View.class); 591579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowed = clazz != null && mFilter.onLoadClass(clazz); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFilterMap.put(name, allowed); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowed) { 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failNotAllowed(name, prefix, attrs); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (allowedState.equals(Boolean.FALSE)) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project failNotAllowed(name, prefix, attrs); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Object[] args = mConstructorArgs; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project args[1] = attrs; 605b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey 606e3abd2ccbef4c50b48df3605c65d732fa49a980bJeff Hao constructor.setAccessible(true); 607b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey final View view = constructor.newInstance(args); 608b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey if (view instanceof ViewStub) { 609a9ddb8dc23b253c53f24ceb81e9d596c072d834eAlan Viverette // Use the same context when inflating ViewStub later. 610b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey final ViewStub viewStub = (ViewStub) view; 611a9ddb8dc23b253c53f24ceb81e9d596c072d834eAlan Viverette viewStub.setLayoutInflater(cloneInContext((Context) args[0])); 612b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey } 613b27b7a152437d6ebb4f2a2700858b69634c00acdJeff Sharkey return view; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (NoSuchMethodException e) { 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ie = new InflateException(attrs.getPositionDescription() 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": Error inflating class " 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (prefix != null ? (prefix + name) : name)); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ie.initCause(e); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ie; 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6223030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne } catch (ClassCastException e) { 6233030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne // If loaded class is not a View subclass 6243030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne InflateException ie = new InflateException(attrs.getPositionDescription() 6253030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne + ": Class is not a View " 6263030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne + (prefix != null ? (prefix + name) : name)); 6273030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne ie.initCause(e); 6283030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne throw ie; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (ClassNotFoundException e) { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If loadClass fails, we should propagate the exception. 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ie = new InflateException(attrs.getPositionDescription() 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": Error inflating class " 635d03b880836bcc4fae83a95458e0709cd45aa6313Romain Guy + (clazz == null ? "<unknown>" : clazz.getName())); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ie.initCause(e); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ie; 63809f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy } finally { 63909f7b93a184d12e5ed584206d903982b3e0915e5Romain Guy Trace.traceEnd(Trace.TRACE_TAG_VIEW); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6443030193dc179b3010f2dd3bffe9c1dec54da38fcGilles Debunne * Throw an exception because the specified class is not allowed to be inflated. 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void failNotAllowed(String name, String prefix, AttributeSet attrs) { 6479c1223a71397b565f38015c07cae57a5015a6500Romain Guy throw new InflateException(attrs.getPositionDescription() 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": Class not allowed to be inflated " 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + (prefix != null ? (prefix + name) : name)); 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This routine is responsible for creating the correct subclass of View 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * given the xml element name. Override it to handle custom view objects. If 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you override this in your subclass be sure to call through to 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * super.onCreateView(name) for names you do not recognize. 657579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param name The fully qualified class name of the View to be create. 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param attrs An AttributeSet of attributes to apply to the View. 660579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke * 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return View The View created. 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected View onCreateView(String name, AttributeSet attrs) 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws ClassNotFoundException { 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return createView(name, "android.view.", attrs); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 668625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn /** 669625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * Version of {@link #onCreateView(String, AttributeSet)} that also 670430742f09063574271e6c4091de13b9b9e762514Chet Haase * takes the future parent of the view being constructed. The default 671625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * implementation simply calls {@link #onCreateView(String, AttributeSet)}. 672625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * 673625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param parent The future parent of the returned view. <em>Note that 674625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * this may be null.</em> 675625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param name The fully qualified class name of the View to be create. 676625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @param attrs An AttributeSet of attributes to apply to the View. 677625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * 678625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn * @return View The View created. 679625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn */ 680625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn protected View onCreateView(View parent, String name, AttributeSet attrs) 681625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn throws ClassNotFoundException { 682625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn return onCreateView(name, attrs); 683625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn } 684625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn 68524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette /** 68624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * Creates a view from a tag name using the supplied attribute set. 68724927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * <p> 68824927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * If {@code inheritContext} is true and the parent is non-null, the view 68924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * will be inflated in parent view's context. If the view specifies a 69024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * <theme> attribute, the inflation context will be wrapped with the 69124927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * specified theme. 69224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * <p> 69324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * Note: Default visibility so the BridgeInflater can override it. 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 69524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette View createViewFromTag(View parent, String name, AttributeSet attrs, boolean inheritContext) { 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (name.equals("view")) { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project name = attrs.getAttributeValue(null, "class"); 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 70024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette Context viewContext; 70124927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette if (parent != null && inheritContext) { 70224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette viewContext = parent.getContext(); 70324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } else { 70424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette viewContext = mContext; 70524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } 70624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette 70724927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette // Apply a theme wrapper, if requested. 708ef259e4484deb69ada76970e26f2b2542b1fe4c1Alan Viverette final TypedArray ta = viewContext.obtainStyledAttributes(attrs, ATTRS_THEME); 709ef259e4484deb69ada76970e26f2b2542b1fe4c1Alan Viverette final int themeResId = ta.getResourceId(0, 0); 71024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette if (themeResId != 0) { 71124927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette viewContext = new ContextThemeWrapper(viewContext, themeResId); 71224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } 713ef259e4484deb69ada76970e26f2b2542b1fe4c1Alan Viverette ta.recycle(); 71424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette 71524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette if (name.equals(TAG_1995)) { 71624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette // Let's party like it's 1995! 71724927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette return new BlinkLayout(viewContext, attrs); 71824927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } 71924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) System.out.println("******** Creating view: " + name); 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 723625ac271f80777668f832a344486a6fcdc06d0aeDianne Hackborn View view; 72424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette if (mFactory2 != null) { 72524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = mFactory2.onCreateView(parent, name, viewContext, attrs); 72624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } else if (mFactory != null) { 72724927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = mFactory.onCreateView(name, viewContext, attrs); 72824927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } else { 72924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = null; 73024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 732420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn if (view == null && mPrivateFactory != null) { 73324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = mPrivateFactory.onCreateView(parent, name, viewContext, attrs); 734420829ef78c5d86e470fc445279c7c10be6b5dbeDianne Hackborn } 73524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (view == null) { 73724927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette final Object lastContext = mConstructorArgs[0]; 73824927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette mConstructorArgs[0] = viewContext; 73924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette try { 74024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette if (-1 == name.indexOf('.')) { 74124927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = onCreateView(parent, name, attrs); 74224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } else { 74324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette view = createView(name, null, attrs); 74424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } 74524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette } finally { 74624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette mConstructorArgs[0] = lastContext; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (DEBUG) System.out.println("Created view is: " + view); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return view; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InflateException e) { 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw e; 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (ClassNotFoundException e) { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ie = new InflateException(attrs.getPositionDescription() 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": Error inflating class " + name); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ie.initCause(e); 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ie; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project InflateException ie = new InflateException(attrs.getPositionDescription() 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ": Error inflating class " + name); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ie.initCause(e); 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw ie; 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Recursive method used to descend down the xml hierarchy and instantiate 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * views, instantiate their children, and then call onFinishInflate(). 77324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * 77424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * @param inheritContext Whether the root view should be inflated in its 77524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * parent's context. This should be true when called inflating 77624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette * child views recursively, or false otherwise. 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7787f9f99ea11051614a7727dfb9f9578b518e76e3cXavier Ducrohet void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs, 77924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette boolean finishInflate, boolean inheritContext) throws XmlPullParserException, 78024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette IOException { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int depth = parser.getDepth(); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((type = parser.next()) != XmlPullParser.END_TAG || 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getDepth() > depth) && type != XmlPullParser.END_DOCUMENT) { 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String name = parser.getName(); 793579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TAG_REQUEST_FOCUS.equals(name)) { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parseRequestFocus(parser, parent); 796451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette } else if (TAG_TAG.equals(name)) { 797451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette parseViewTag(parser, parent, attrs); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (TAG_INCLUDE.equals(name)) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parser.getDepth() == 0) { 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("<include /> cannot be the root element"); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 80224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette parseInclude(parser, parent, attrs, inheritContext); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (TAG_MERGE.equals(name)) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("<merge /> must be the root element"); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 80624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette final View view = createViewFromTag(parent, name, attrs, inheritContext); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup viewGroup = (ViewGroup) parent; 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup.LayoutParams params = viewGroup.generateLayoutParams(attrs); 80924927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette rInflate(parser, view, attrs, true, true); 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project viewGroup.addView(view, params); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8149295ada0ec89fa7a666be4a2f1006a4b722adf4fRomain Guy if (finishInflate) parent.onFinishInflate(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 817451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette /** 818451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette * Parses a <code><request-focus></code> element and requests focus on 819451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette * the containing View. 820451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette */ 821451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette private void parseRequestFocus(XmlPullParser parser, View view) 822451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette throws XmlPullParserException, IOException { 823451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette int type; 824451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette view.requestFocus(); 825451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette final int currentDepth = parser.getDepth(); 826451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette while (((type = parser.next()) != XmlPullParser.END_TAG || 827451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) { 828451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette // Empty 829451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette } 830451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette } 831451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette 832451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette /** 833451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette * Parses a <code><tag></code> element and sets a keyed tag on the 834451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette * containing View. 835451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette */ 836451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette private void parseViewTag(XmlPullParser parser, View view, AttributeSet attrs) 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throws XmlPullParserException, IOException { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 839451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette 840451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette final TypedArray ta = mContext.obtainStyledAttributes( 841451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette attrs, com.android.internal.R.styleable.ViewTag); 842451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette final int key = ta.getResourceId(com.android.internal.R.styleable.ViewTag_id, 0); 843451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette final CharSequence value = ta.getText(com.android.internal.R.styleable.ViewTag_value); 844451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette view.setTag(key, value); 845451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette ta.recycle(); 846451a3417e97d9d3bb835290a65f9af30b112c789Alan Viverette 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currentDepth = parser.getDepth(); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((type = parser.next()) != XmlPullParser.END_TAG || 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Empty 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 85424927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs, 85524927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette boolean inheritContext) throws XmlPullParserException, IOException { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int type; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (parent instanceof ViewGroup) { 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int layout = attrs.getAttributeResourceValue(null, "layout", 0); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (layout == 0) { 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String value = attrs.getAttributeValue(null, "layout"); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (value == null) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("You must specifiy a layout in the" 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " include tag: <include layout=\"@layout/layoutID\" />"); 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("You must specifiy a valid layout " 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + "reference. The layout ID " + value + " is not valid."); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final XmlResourceParser childParser = 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project getContext().getResources().getLayout(layout); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final AttributeSet childAttrs = Xml.asAttributeSet(childParser); 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while ((type = childParser.next()) != XmlPullParser.START_TAG && 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project type != XmlPullParser.END_DOCUMENT) { 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Empty. 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (type != XmlPullParser.START_TAG) { 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException(childParser.getPositionDescription() + 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ": No start tag found!"); 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String childName = childParser.getName(); 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (TAG_MERGE.equals(childName)) { 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inflate all children. 89024927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette rInflate(childParser, parent, childAttrs, false, inheritContext); 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 89224927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette final View view = createViewFromTag(parent, childName, childAttrs, 89324927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette inheritContext); 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ViewGroup group = (ViewGroup) parent; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We try to load the layout params set in the <include /> tag. If 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // they don't exist, we will rely on the layout params set in the 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // included XML file. 899579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke // During a layoutparams generation, a runtime exception is thrown 900579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke // if either layout_width or layout_height is missing. We catch 901579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke // this exception and set localParams accordingly: true means we 902579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke // successfully loaded layout params from the <include /> tag, 903579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke // false means we need to rely on the included layout params. 904579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke ViewGroup.LayoutParams params = null; 905579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke try { 906579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke params = group.generateLayoutParams(attrs); 907579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } catch (RuntimeException e) { 908579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke params = group.generateLayoutParams(childAttrs); 909579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } finally { 910579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke if (params != null) { 911579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke view.setLayoutParams(params); 912579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } 913579e14016c4a972e70cd2bd0c6d89bbd7e9e941cDave Burke } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Inflate all children. 91624927f2798fdeee3aa4fa13dee5acfa218e993e3Alan Viverette rInflate(childParser, view, childAttrs, true, true); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempt to override the included layout's android:id with the 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // one set on the <include /> tag itself. 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project TypedArray a = mContext.obtainStyledAttributes(attrs, 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project com.android.internal.R.styleable.View, 0, 0); 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int id = a.getResourceId(com.android.internal.R.styleable.View_id, View.NO_ID); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // While we're at it, let's try to override android:visibility. 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int visibility = a.getInt(com.android.internal.R.styleable.View_visibility, -1); 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project a.recycle(); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (id != View.NO_ID) { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setId(id); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project switch (visibility) { 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 0: 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setVisibility(View.VISIBLE); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 1: 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setVisibility(View.INVISIBLE); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project case 2: 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project view.setVisibility(View.GONE); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project group.addView(view); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project childParser.close(); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new InflateException("<include /> can only be used inside of a ViewGroup"); 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int currentDepth = parser.getDepth(); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (((type = parser.next()) != XmlPullParser.END_TAG || 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parser.getDepth() > currentDepth) && type != XmlPullParser.END_DOCUMENT) { 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Empty 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9589c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9599c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9609c1223a71397b565f38015c07cae57a5015a6500Romain Guy private static class BlinkLayout extends FrameLayout { 9619c1223a71397b565f38015c07cae57a5015a6500Romain Guy private static final int MESSAGE_BLINK = 0x42; 9629c1223a71397b565f38015c07cae57a5015a6500Romain Guy private static final int BLINK_DELAY = 500; 9639c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9649c1223a71397b565f38015c07cae57a5015a6500Romain Guy private boolean mBlink; 9659c1223a71397b565f38015c07cae57a5015a6500Romain Guy private boolean mBlinkState; 9669c1223a71397b565f38015c07cae57a5015a6500Romain Guy private final Handler mHandler; 9679c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9689c1223a71397b565f38015c07cae57a5015a6500Romain Guy public BlinkLayout(Context context, AttributeSet attrs) { 9699c1223a71397b565f38015c07cae57a5015a6500Romain Guy super(context, attrs); 9709c1223a71397b565f38015c07cae57a5015a6500Romain Guy mHandler = new Handler(new Handler.Callback() { 9719c1223a71397b565f38015c07cae57a5015a6500Romain Guy @Override 9729c1223a71397b565f38015c07cae57a5015a6500Romain Guy public boolean handleMessage(Message msg) { 9739c1223a71397b565f38015c07cae57a5015a6500Romain Guy if (msg.what == MESSAGE_BLINK) { 9749c1223a71397b565f38015c07cae57a5015a6500Romain Guy if (mBlink) { 9759c1223a71397b565f38015c07cae57a5015a6500Romain Guy mBlinkState = !mBlinkState; 9769c1223a71397b565f38015c07cae57a5015a6500Romain Guy makeBlink(); 9779c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9789c1223a71397b565f38015c07cae57a5015a6500Romain Guy invalidate(); 9799c1223a71397b565f38015c07cae57a5015a6500Romain Guy return true; 9809c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9819c1223a71397b565f38015c07cae57a5015a6500Romain Guy return false; 9829c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9839c1223a71397b565f38015c07cae57a5015a6500Romain Guy }); 9849c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9859c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9869c1223a71397b565f38015c07cae57a5015a6500Romain Guy private void makeBlink() { 9879c1223a71397b565f38015c07cae57a5015a6500Romain Guy Message message = mHandler.obtainMessage(MESSAGE_BLINK); 9889c1223a71397b565f38015c07cae57a5015a6500Romain Guy mHandler.sendMessageDelayed(message, BLINK_DELAY); 9899c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 9909c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9919c1223a71397b565f38015c07cae57a5015a6500Romain Guy @Override 9929c1223a71397b565f38015c07cae57a5015a6500Romain Guy protected void onAttachedToWindow() { 9939c1223a71397b565f38015c07cae57a5015a6500Romain Guy super.onAttachedToWindow(); 9949c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9959c1223a71397b565f38015c07cae57a5015a6500Romain Guy mBlink = true; 9969c1223a71397b565f38015c07cae57a5015a6500Romain Guy mBlinkState = true; 9979c1223a71397b565f38015c07cae57a5015a6500Romain Guy 9989c1223a71397b565f38015c07cae57a5015a6500Romain Guy makeBlink(); 9999c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 10009c1223a71397b565f38015c07cae57a5015a6500Romain Guy 10019c1223a71397b565f38015c07cae57a5015a6500Romain Guy @Override 10029c1223a71397b565f38015c07cae57a5015a6500Romain Guy protected void onDetachedFromWindow() { 10039c1223a71397b565f38015c07cae57a5015a6500Romain Guy super.onDetachedFromWindow(); 10049c1223a71397b565f38015c07cae57a5015a6500Romain Guy 10059c1223a71397b565f38015c07cae57a5015a6500Romain Guy mBlink = false; 10069c1223a71397b565f38015c07cae57a5015a6500Romain Guy mBlinkState = true; 10079c1223a71397b565f38015c07cae57a5015a6500Romain Guy 10089c1223a71397b565f38015c07cae57a5015a6500Romain Guy mHandler.removeMessages(MESSAGE_BLINK); 10099c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 10109c1223a71397b565f38015c07cae57a5015a6500Romain Guy 10119c1223a71397b565f38015c07cae57a5015a6500Romain Guy @Override 10129c1223a71397b565f38015c07cae57a5015a6500Romain Guy protected void dispatchDraw(Canvas canvas) { 10139c1223a71397b565f38015c07cae57a5015a6500Romain Guy if (mBlinkState) { 10149c1223a71397b565f38015c07cae57a5015a6500Romain Guy super.dispatchDraw(canvas); 10159c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 10169c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 10179c1223a71397b565f38015c07cae57a5015a6500Romain Guy } 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1019