Defining your own subclass of LayoutInflater.Factory seems like a lot of work to me. Just override Activity onCreateView () with some common code:
@Override public View onCreateView(String name, Context context, AttributeSet attrs) { View view; // No need wasting microseconds getting the inflater every time. // This method gets called a great many times. // Better still define these instance variables in onCreate() if (mInflator == null){ mInflator = LayoutInflater.from(context); mPrefix = ((Activity) context).getComponentName().getClassName(); // Take off the package name including the last period // and look for custom views in the same directory. mPrefix = mPrefix.substring(0, mPrefix.lastIndexOf(".")+1); } // Don't bother if 'a path' is already specified. if (name.indexOf('.') > -1) return null; try{ view = mInflator.createView(name, mPrefix, attrs); } catch (ClassNotFoundException e) { view = null; } catch (InflateException e) { view = null; } // Returning null is no big deal. The super class will continue the inflation. return view; }
Please note that user views must be in the same package (i.e. in the same directory) as this action, but then this is just a common piece of code that you can tickle in any activity (or even better, inherit from user parent activity class). You are not worried about looking for a specific class, as indicated in the solution offered by kcoppock:
if (MyCustomView.class.getSimpleName().equals(name)) {....
Of course, you are not creating a completely new class.
The real magic is in the class of the main library LayoutInflator.java. See Call, mPrivateFactory.onCreateView (), below ?:
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); } }
You see, if the so-called mPrivateFactory returns null (mPrivateFactory, by the way, is your activity class), LayoutInflator simply continues with it another alternative approach and continues inflation:
if (view == null) { if (-1 == name.indexOf('.')) { view = onCreateView(parent, name, attrs); } else { view = createView(name, null, attrs); } }
Itโs a good idea to โgo throughโ the library classes using the IDE debugger and really see how Android works. :)
Please note that the code if (-1 == name.indexOf('.')) { Is for you guys who still insist on pasting the full path with your custom views, <com.wehavelongdomainname.android.ui.MyButton> If there is a "dot" in the name, then creatview () is called with a prefix (second parameter) as null: view = createView(name, null, attrs);
Why I use this approach because I discovered that there were times when the package name moves (i.e. changed) during the initial development. However, unlike changes to the package name that are performed in the Java code itself, the compiler does not detect the changes and discrepancies that are now present in any XML files. Using this approach, now it is not necessary.
Greetings.