/// <summary>Low-level function for instantiating a view by name.</summary> /// <remarks> /// Low-level function for instantiating a view by name. This attempts to /// instantiate a view class of the given <var>name</var> found in this /// LayoutInflater's ClassLoader. /// <p> /// There are two things that can happen in an error case: either the /// exception describing the error will be thrown, or a null will be /// returned. You must deal with both possibilities -- the former will happen /// the first time createView() is called for a class of a particular name, /// the latter every time there-after for that class name. /// </remarks> /// <param name="name">The full name of the class to be instantiated.</param> /// <param name="attrs">The XML attributes supplied for this instance.</param> /// <returns>View The newly instantiated view, or null.</returns> /// <exception cref="java.lang.ClassNotFoundException"></exception> /// <exception cref="android.view.InflateException"></exception> public android.view.View createView(string name, string prefix, android.util.AttributeSet attrs) { System.Reflection.ConstructorInfo constructor = sConstructorMap.get(name); System.Type clazz = null; try { if (constructor == null) { // Class not found in the cache, see if it's real, and try to add it clazz = XobotOS.Runtime.Reflection.AsSubclass(mContext.getClassLoader().loadClass (prefix != null ? (prefix + name) : name), typeof(android.view.View)); if (mFilter != null && clazz != null) { bool allowed = mFilter.onLoadClass(clazz); if (!allowed) { failNotAllowed(name, prefix, attrs); } } constructor = XobotOS.Runtime.Reflection.GetConstructor(clazz, mConstructorSignature ); sConstructorMap.put(name, constructor); } else { // If we have a filter, apply it to cached constructor if (mFilter != null) { // Have we seen this name before? bool allowedState = mFilterMap.get(name); if (allowedState == null) { // New class -- remember whether it is allowed clazz = XobotOS.Runtime.Reflection.AsSubclass(mContext.getClassLoader().loadClass (prefix != null ? (prefix + name) : name), typeof(android.view.View)); bool allowed = clazz != null && mFilter.onLoadClass(clazz); mFilterMap.put(name, allowed); if (!allowed) { failNotAllowed(name, prefix, attrs); } } else { if (allowedState.Equals(false)) { failNotAllowed(name, prefix, attrs); } } } } object[] args = mConstructorArgs; args[1] = attrs; return (android.view.View)constructor.Invoke(args); } catch (java.lang.NoSuchMethodException e) { android.view.InflateException ie = new android.view.InflateException(attrs.getPositionDescription () + ": Error inflating class " + (prefix != null ? (prefix + name) : name)); ie.InnerException = e; throw ie; } catch (System.InvalidCastException e) { // If loaded class is not a View subclass android.view.InflateException ie = new android.view.InflateException(attrs.getPositionDescription () + ": Class is not a View " + (prefix != null ? (prefix + name) : name)); ie.InnerException = e; throw ie; } catch (java.lang.ClassNotFoundException e) { // If loadClass fails, we should propagate the exception. throw; } catch (System.Exception e) { android.view.InflateException ie = new android.view.InflateException(attrs.getPositionDescription () + ": Error inflating class " + (clazz == null ? "<unknown>" : clazz.FullName) ); ie.InnerException = e; throw ie; } }
internal virtual android.view.View createViewFromTag(android.view.View parent, string name, android.util.AttributeSet attrs) { if (name.Equals("view")) { name = attrs.getAttributeValue(null, "class"); } try { android.view.View view; if (mFactory2 != null) { view = mFactory2.onCreateView(parent, name, mContext, attrs); } else { if (mFactory != null) { view = mFactory.onCreateView(name, mContext, attrs); } else { view = null; } } if (view == null && mPrivateFactory != null) { view = mPrivateFactory.onCreateView(parent, name, mContext, attrs); } if (view == null) { if (-1 == name.IndexOf('.')) { view = onCreateView(parent, name, attrs); } else { view = createView(name, null, attrs); } } return view; } catch (android.view.InflateException e) { throw; } catch (java.lang.ClassNotFoundException e) { android.view.InflateException ie = new android.view.InflateException(attrs.getPositionDescription () + ": Error inflating class " + name); ie.InnerException = e; throw ie; } catch (System.Exception e) { android.view.InflateException ie = new android.view.InflateException(attrs.getPositionDescription () + ": Error inflating class " + name); ie.InnerException = e; throw ie; } }
/// <summary>Inflate a new view hierarchy from the specified XML node.</summary> /// <remarks> /// Inflate a new view hierarchy from the specified XML node. Throws /// <see cref="InflateException">InflateException</see> /// if there is an error. /// <p> /// <em><strong>Important</strong></em> For performance /// reasons, view inflation relies heavily on pre-processing of XML files /// that is done at build time. Therefore, it is not currently possible to /// use LayoutInflater with an XmlPullParser over a plain XML file at runtime. /// </remarks> /// <param name="parser"> /// XML dom node containing the description of the view /// hierarchy. /// </param> /// <param name="root"> /// Optional view to be the parent of the generated hierarchy (if /// <em>attachToRoot</em> is true), or else simply an object that /// provides a set of LayoutParams values for root of the returned /// hierarchy (if <em>attachToRoot</em> is false.) /// </param> /// <param name="attachToRoot"> /// Whether the inflated hierarchy should be attached to /// the root parameter? If false, root is only used to create the /// correct subclass of LayoutParams for the root view in the XML. /// </param> /// <returns> /// The root View of the inflated hierarchy. If root was supplied and /// attachToRoot is true, this is root; otherwise it is the root of /// the inflated XML file. /// </returns> public virtual android.view.View inflate(org.xmlpull.v1.XmlPullParser parser, android.view.ViewGroup root, bool attachToRoot) { lock (mConstructorArgs) { android.util.AttributeSet attrs = android.util.Xml.asAttributeSet(parser); android.content.Context lastContext = (android.content.Context)mConstructorArgs[0 ]; mConstructorArgs[0] = mContext; android.view.View result = root; try { // Look for the root node. int type; while ((type = parser.next()) != org.xmlpull.v1.XmlPullParserClass.START_TAG && type != org.xmlpull.v1.XmlPullParserClass.END_DOCUMENT) { } // Empty if (type != org.xmlpull.v1.XmlPullParserClass.START_TAG) { throw new android.view.InflateException(parser.getPositionDescription() + ": No start tag found!" ); } string name = parser.getName(); if (TAG_MERGE.Equals(name)) { if (root == null || !attachToRoot) { throw new android.view.InflateException("<merge /> can be used only with a valid " + "ViewGroup root and attachToRoot=true"); } rInflate(parser, root, attrs, false); } else { // Temp is the root view that was found in the xml android.view.View temp; if (TAG_1995.Equals(name)) { temp = new android.view.LayoutInflater.BlinkLayout(mContext, attrs); } else { temp = createViewFromTag(root, name, attrs); } android.view.ViewGroup.LayoutParams @params = null; if (root != null) { // Create layout params that match root, if supplied @params = root.generateLayoutParams(attrs); if (!attachToRoot) { // Set the layout params for temp if we are not // attaching. (If we are, we use addView, below) temp.setLayoutParams(@params); } } // Inflate all children under temp rInflate(parser, temp, attrs, true); // We are supposed to attach all the views we found (int temp) // to root. Do that now. if (root != null && attachToRoot) { root.addView(temp, @params); } // Decide whether to return the root that was passed in or the // top view found in xml. if (root == null || !attachToRoot) { result = temp; } } } catch (org.xmlpull.v1.XmlPullParserException e) { android.view.InflateException ex = new android.view.InflateException(e.Message); ex.InnerException = e; throw ex; } catch (System.IO.IOException e) { android.view.InflateException ex = new android.view.InflateException(parser.getPositionDescription () + ": " + e.Message); ex.InnerException = e; throw ex; } finally { // Don't retain static reference on context. mConstructorArgs[0] = lastContext; mConstructorArgs[1] = null; } return result; } }