2020import android .os .Handler ;
2121import android .os .Message ;
2222import android .widget .FrameLayout ;
23+ import com .android .internal .R ;
2324import org .xmlpull .v1 .XmlPullParser ;
2425import org .xmlpull .v1 .XmlPullParserException ;
2526
4344 *
4445 * <pre>LayoutInflater inflater = (LayoutInflater)context.getSystemService
4546 * (Context.LAYOUT_INFLATER_SERVICE);</pre>
46- *
47+ *
4748 * <p>
4849 * To create a new LayoutInflater with an additional {@link Factory} for your
4950 * own views, you can use {@link #cloneInContext} to clone an existing
5051 * ViewFactory, and then call {@link #setFactory} on it to include your
5152 * Factory.
52- *
53+ *
5354 * <p>
5455 * For performance reasons, view inflation relies heavily on pre-processing of
5556 * XML files that is done at build time. Therefore, it is not currently possible
5657 * to use LayoutInflater with an XmlPullParser over a plain XML file at runtime;
5758 * it only works with an XmlPullParser returned from a compiled resource
5859 * (R.<em>something</em> file.)
59- *
60+ *
6061 * @see Context#getSystemService
6162 */
6263public abstract class LayoutInflater {
@@ -82,7 +83,7 @@ public abstract class LayoutInflater {
8283
8384 private static final HashMap <String , Constructor <? extends View >> sConstructorMap =
8485 new HashMap <String , Constructor <? extends View >>();
85-
86+
8687 private HashMap <String , Boolean > mFilterMap ;
8788
8889 private static final String TAG_MERGE = "merge" ;
@@ -93,36 +94,36 @@ public abstract class LayoutInflater {
9394 /**
9495 * Hook to allow clients of the LayoutInflater to restrict the set of Views that are allowed
9596 * to be inflated.
96- *
97+ *
9798 */
9899 public interface Filter {
99100 /**
100101 * Hook to allow clients of the LayoutInflater to restrict the set of Views
101102 * that are allowed to be inflated.
102- *
103+ *
103104 * @param clazz The class object for the View that is about to be inflated
104- *
105+ *
105106 * @return True if this class is allowed to be inflated, or false otherwise
106107 */
107108 @ SuppressWarnings ("unchecked" )
108109 boolean onLoadClass (Class clazz );
109110 }
110-
111+
111112 public interface Factory {
112113 /**
113114 * Hook you can supply that is called when inflating from a LayoutInflater.
114115 * You can use this to customize the tag names available in your XML
115116 * layout files.
116- *
117+ *
117118 * <p>
118119 * Note that it is good practice to prefix these custom names with your
119120 * package (i.e., com.coolcompany.apps) to avoid conflicts with system
120121 * names.
121- *
122+ *
122123 * @param name Tag name to be inflated.
123124 * @param context The context the view is being created in.
124125 * @param attrs Inflation attributes as specified in XML file.
125- *
126+ *
126127 * @return View Newly created view. Return null for the default
127128 * behavior.
128129 */
@@ -150,14 +151,14 @@ public interface Factory2 extends Factory {
150151 private static class FactoryMerger implements Factory2 {
151152 private final Factory mF1 , mF2 ;
152153 private final Factory2 mF12 , mF22 ;
153-
154+
154155 FactoryMerger (Factory f1 , Factory2 f12 , Factory f2 , Factory2 f22 ) {
155156 mF1 = f1 ;
156157 mF2 = f2 ;
157158 mF12 = f12 ;
158159 mF22 = f22 ;
159160 }
160-
161+
161162 public View onCreateView (String name , Context context , AttributeSet attrs ) {
162163 View v = mF1 .onCreateView (name , context , attrs );
163164 if (v != null ) return v ;
@@ -172,13 +173,13 @@ public View onCreateView(View parent, String name, Context context, AttributeSet
172173 : mF2 .onCreateView (name , context , attrs );
173174 }
174175 }
175-
176+
176177 /**
177178 * Create a new LayoutInflater instance associated with a particular Context.
178179 * Applications will almost always want to use
179180 * {@link Context#getSystemService Context.getSystemService()} to retrieve
180181 * the standard {@link Context#LAYOUT_INFLATER_SERVICE Context.INFLATER_SERVICE}.
181- *
182+ *
182183 * @param context The Context in which this LayoutInflater will create its
183184 * Views; most importantly, this supplies the theme from which the default
184185 * values for their attributes are retrieved.
@@ -191,7 +192,7 @@ protected LayoutInflater(Context context) {
191192 * Create a new LayoutInflater instance that is a copy of an existing
192193 * LayoutInflater, optionally with its Context changed. For use in
193194 * implementing {@link #cloneInContext}.
194- *
195+ *
195196 * @param original The original LayoutInflater to copy.
196197 * @param newContext The new Context to use.
197198 */
@@ -202,7 +203,7 @@ protected LayoutInflater(LayoutInflater original, Context newContext) {
202203 mPrivateFactory = original .mPrivateFactory ;
203204 mFilter = original .mFilter ;
204205 }
205-
206+
206207 /**
207208 * Obtains the LayoutInflater from the given context.
208209 */
@@ -220,15 +221,15 @@ public static LayoutInflater from(Context context) {
220221 * pointing to a different Context than the original. This is used by
221222 * {@link ContextThemeWrapper} to create a new LayoutInflater to go along
222223 * with the new Context theme.
223- *
224+ *
224225 * @param newContext The new Context to associate with the new LayoutInflater.
225226 * May be the same as the original Context if desired.
226- *
227+ *
227228 * @return Returns a brand spanking new LayoutInflater object associated with
228229 * the given Context.
229230 */
230231 public abstract LayoutInflater cloneInContext (Context newContext );
231-
232+
232233 /**
233234 * Return the context we are running in, for access to resources, class
234235 * loader, etc.
@@ -264,7 +265,7 @@ public final Factory2 getFactory2() {
264265 * called on each element name as the xml is parsed. If the factory returns
265266 * a View, that is added to the hierarchy. If it returns null, the next
266267 * factory default {@link #onCreateView} method is called.
267- *
268+ *
268269 * <p>If you have an existing
269270 * LayoutInflater and want to add your own factory to it, use
270271 * {@link #cloneInContext} to clone the existing instance and then you
@@ -320,13 +321,13 @@ public void setPrivateFactory(Factory2 factory) {
320321 public Filter getFilter () {
321322 return mFilter ;
322323 }
323-
324+
324325 /**
325326 * Sets the {@link Filter} to by this LayoutInflater. If a view is attempted to be inflated
326327 * which is not allowed by the {@link Filter}, the {@link #inflate(int, ViewGroup)} call will
327328 * throw an {@link InflateException}. This filter will replace any previous filter set on this
328329 * LayoutInflater.
329- *
330+ *
330331 * @param filter The Filter which restricts the set of Views that are allowed to be inflated.
331332 * This filter will replace any previous filter set on this LayoutInflater.
332333 */
@@ -340,7 +341,7 @@ public void setFilter(Filter filter) {
340341 /**
341342 * Inflate a new view hierarchy from the specified xml resource. Throws
342343 * {@link InflateException} if there is an error.
343- *
344+ *
344345 * @param resource ID for an XML layout resource to load (e.g.,
345346 * <code>R.layout.main_page</code>)
346347 * @param root Optional view to be the parent of the generated hierarchy.
@@ -360,7 +361,7 @@ public View inflate(int resource, ViewGroup root) {
360361 * reasons, view inflation relies heavily on pre-processing of XML files
361362 * that is done at build time. Therefore, it is not currently possible to
362363 * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
363- *
364+ *
364365 * @param parser XML dom node containing the description of the view
365366 * hierarchy.
366367 * @param root Optional view to be the parent of the generated hierarchy.
@@ -375,7 +376,7 @@ public View inflate(XmlPullParser parser, ViewGroup root) {
375376 /**
376377 * Inflate a new view hierarchy from the specified xml resource. Throws
377378 * {@link InflateException} if there is an error.
378- *
379+ *
379380 * @param resource ID for an XML layout resource to load (e.g.,
380381 * <code>R.layout.main_page</code>)
381382 * @param root Optional view to be the parent of the generated hierarchy (if
@@ -407,7 +408,7 @@ public View inflate(int resource, ViewGroup root, boolean attachToRoot) {
407408 * reasons, view inflation relies heavily on pre-processing of XML files
408409 * that is done at build time. Therefore, it is not currently possible to
409410 * use LayoutInflater with an XmlPullParser over a plain XML file at runtime.
410- *
411+ *
411412 * @param parser XML dom node containing the description of the view
412413 * hierarchy.
413414 * @param root Optional view to be the parent of the generated hierarchy (if
@@ -442,7 +443,7 @@ public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
442443 }
443444
444445 final String name = parser .getName ();
445-
446+
446447 if (DEBUG ) {
447448 System .out .println ("**************************" );
448449 System .out .println ("Creating root view: "
@@ -528,17 +529,17 @@ public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot)
528529 * Low-level function for instantiating a view by name. This attempts to
529530 * instantiate a view class of the given <var>name</var> found in this
530531 * LayoutInflater's ClassLoader.
531- *
532+ *
532533 * <p>
533534 * There are two things that can happen in an error case: either the
534535 * exception describing the error will be thrown, or a null will be
535536 * returned. You must deal with both possibilities -- the former will happen
536537 * the first time createView() is called for a class of a particular name,
537538 * the latter every time there-after for that class name.
538- *
539+ *
539540 * @param name The full name of the class to be instantiated.
540541 * @param attrs The XML attributes supplied for this instance.
541- *
542+ *
542543 * @return View The newly instantiated view, or null.
543544 */
544545 public final View createView (String name , String prefix , AttributeSet attrs )
@@ -551,7 +552,7 @@ public final View createView(String name, String prefix, AttributeSet attrs)
551552 // Class not found in the cache, see if it's real, and try to add it
552553 clazz = mContext .getClassLoader ().loadClass (
553554 prefix != null ? (prefix + name ) : name ).asSubclass (View .class );
554-
555+
555556 if (mFilter != null && clazz != null ) {
556557 boolean allowed = mFilter .onLoadClass (clazz );
557558 if (!allowed ) {
@@ -569,7 +570,7 @@ public final View createView(String name, String prefix, AttributeSet attrs)
569570 // New class -- remember whether it is allowed
570571 clazz = mContext .getClassLoader ().loadClass (
571572 prefix != null ? (prefix + name ) : name ).asSubclass (View .class );
572-
573+
573574 boolean allowed = clazz != null && mFilter .onLoadClass (clazz );
574575 mFilterMap .put (name , allowed );
575576 if (!allowed ) {
@@ -632,10 +633,10 @@ private void failNotAllowed(String name, String prefix, AttributeSet attrs) {
632633 * given the xml element name. Override it to handle custom view objects. If
633634 * you override this in your subclass be sure to call through to
634635 * super.onCreateView(name) for names you do not recognize.
635- *
636+ *
636637 * @param name The fully qualified class name of the View to be create.
637638 * @param attrs An AttributeSet of attributes to apply to the View.
638- *
639+ *
639640 * @return View The View created.
640641 */
641642 protected View onCreateView (String name , AttributeSet attrs )
@@ -679,7 +680,7 @@ View createViewFromTag(View parent, String name, AttributeSet attrs) {
679680 if (view == null && mPrivateFactory != null ) {
680681 view = mPrivateFactory .onCreateView (parent , name , mContext , attrs );
681682 }
682-
683+
683684 if (view == null ) {
684685 if (-1 == name .indexOf ('.' )) {
685686 view = onCreateView (parent , name , attrs );
@@ -726,7 +727,7 @@ void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
726727 }
727728
728729 final String name = parser .getName ();
729-
730+
730731 if (TAG_REQUEST_FOCUS .equals (name )) {
731732 parseRequestFocus (parser , parent );
732733 } else if (TAG_INCLUDE .equals (name )) {
@@ -741,7 +742,7 @@ void rInflate(XmlPullParser parser, View parent, final AttributeSet attrs,
741742 final ViewGroup viewGroup = (ViewGroup ) parent ;
742743 final ViewGroup .LayoutParams params = viewGroup .generateLayoutParams (attrs );
743744 rInflate (parser , view , attrs , true );
744- viewGroup .addView (view , params );
745+ viewGroup .addView (view , params );
745746 } else {
746747 final View view = createViewFromTag (parent , name , attrs );
747748 final ViewGroup viewGroup = (ViewGroup ) parent ;
@@ -810,21 +811,14 @@ private void parseInclude(XmlPullParser parser, View parent, AttributeSet attrs)
810811 // We try to load the layout params set in the <include /> tag. If
811812 // they don't exist, we will rely on the layout params set in the
812813 // included XML file.
813- // During a layoutparams generation, a runtime exception is thrown
814- // if either layout_width or layout_height is missing. We catch
815- // this exception and set localParams accordingly: true means we
816- // successfully loaded layout params from the <include /> tag,
817- // false means we need to rely on the included layout params.
818- ViewGroup .LayoutParams params = null ;
819- try {
820- params = group .generateLayoutParams (attrs );
821- } catch (RuntimeException e ) {
822- params = group .generateLayoutParams (childAttrs );
823- } finally {
824- if (params != null ) {
825- view .setLayoutParams (params );
826- }
827- }
814+ TypedArray ta = getContext ().obtainStyledAttributes (attrs ,
815+ R .styleable .ViewGroup_Layout );
816+ boolean definesBothWidthAndHeight =
817+ ta .hasValue (R .styleable .ViewGroup_Layout_layout_width ) &&
818+ ta .hasValue (R .styleable .ViewGroup_Layout_layout_height );
819+ AttributeSet attributes = definesBothWidthAndHeight ? attrs : childAttrs ;
820+ view .setLayoutParams (group .generateLayoutParams (attributes ));
821+ ta .recycle ();
828822
829823 // Inflate all children.
830824 rInflate (childParser , view , childAttrs , true );
0 commit comments