/*
* portions Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.view;
import android.content.Context;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.util.AttributeSet;
import android.util.Slog;
import android.util.Xml;
import java.io.FileReader;
import java.lang.reflect.Constructor;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
public class LayoutInflater {
private static final String TAG = "LayoutInflater";
/* pretty print for debugging */
private int indent = 1;
private String tabs(int indent) {
return indent > 0 ? String.format("%"+indent+"s", "").replace(" ", "\t") : "";
}
public interface Factory {
}
public interface Factory2 {
}
private Factory2 mFactory2;
private Context context;
public LayoutInflater(Context context) {
this.context = context;
}
private Factory mFactory;
public final LayoutInflater.Factory getFactory() {
return mFactory;
}
public final void setFactory(LayoutInflater.Factory factory){
mFactory = factory;
}
public void setFactory2(Factory2 factory) {
this.mFactory2 = factory;
}
public static LayoutInflater from(Context context) {
return new LayoutInflater(context);
}
public final View createView(String name, String prefix, AttributeSet attrs) throws Exception {
Slog.v(TAG, tabs(indent) + "createView(" + name + ", " + prefix + ", " + attrs + ");");
String view_class_name = prefix!=null ? prefix + name : name;
Class view_class = Class.forName(view_class_name);
Constructor constructor = view_class.getConstructor(Context.class, AttributeSet.class);
Context context = this.context;
final TypedArray ta = context.obtainStyledAttributes(attrs, new int[]{com.android.internal.R.attr.theme});
final int themeResId = ta.getResourceId(0, 0);
if (themeResId != 0) {
context = new ContextThemeWrapper(context, themeResId);
}
ta.recycle();
View view_instance = (View)constructor.newInstance(context, attrs);
return view_instance;
}
/**
* taken as-is
*/
protected View onCreateView(String name, AttributeSet attrs) throws Exception {
try { // FIXME ugly
return createView(name, "android.view.", attrs);
} catch (java.lang.ClassNotFoundException e) {
try {
return createView(name, "android.widget.", attrs);
} catch (java.lang.ClassNotFoundException e1) {
return createView(name, "android.webkit.", attrs);
}
}
}
/**
* taken as-is
*/
protected View onCreateView(View parent, String name, AttributeSet attrs) throws Exception {
return onCreateView(name, attrs);
}
View createViewFromTag(View parent, String name, AttributeSet attrs) throws Exception {
if (name.equals("view")) {
name = attrs.getAttributeValue(null, "class");
}
Slog.v(TAG, tabs(indent) + "createViewFromTag called: parent: " + parent + ", name: " + name);
View view;
if (-1 == name.indexOf('.')) {
view = onCreateView(parent, name, attrs);
} else {
view = createView(name, null, attrs);
}
Slog.v(TAG, tabs(indent) + "createViewFromTag: Created view is: " + view + " | id: " + String.format("%x", view.getId()) + ", id_str: " + view.getIdName());
return view;
}
public View inflate(int resource, ViewGroup root) {
return inflate(resource, root, root != null);
}
public View inflate(int layoutResID, ViewGroup root, boolean attachToRoot) {
Slog.v(TAG, "inflating view from layout id: " + String.format("%x", layoutResID) + ", id_str: " + Context.this_application.getResources().getResourceName(layoutResID));
XmlResourceParser xpp = context.getResources().getLayout(layoutResID);
try {
return inflate(xpp, root, attachToRoot);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public View inflate(XmlPullParser parser, ViewGroup root, boolean attachToRoot) throws Exception {
final AttributeSet attrs = Xml.asAttributeSet(parser);
View result = root;
// Look for the root node.
int type;
while ((type = parser.next()) != XmlPullParser.START_TAG &&
type != XmlPullParser.END_DOCUMENT) {
// Empty
}
if (type != XmlPullParser.START_TAG) {
throw new Exception(parser.getPositionDescription() + ": No start tag found!");
}
final String name = parser.getName();
Slog.v(TAG, tabs(indent) + "**************************");
Slog.v(TAG, tabs(indent) + "Creating root view: " + name);
Slog.v(TAG, tabs(indent) + "**************************");
if (name.equals("merge")) {
if (root == null || !attachToRoot) {
throw new Exception(" 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
View temp;
if (name.equals("blink")) {
throw new Exception("