LayoutInflater - 从XMLPullParser扩展布局

时间:2014-11-03 12:27:35

标签: android xml layout xmlpullparser

我正在尝试创建一个自定义的“布局构建器”,其中包含所有子项的一些视图标记(例如相对布局)将从基于某些条件(访问权限)定义布局的XML文件中删除。 / p>

我有一个名为wrapper.xml的主布局包装器:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

</LinearLayout>

然后我有例如test.xml文件定义保存在/ res / raw文件夹中的布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/section1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <Button
            android:id="@+id/button1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />

    </RelativeLayout>

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <RelativeLayout
        android:id="@+id/section2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" >

        <TextView
            android:id="@+id/textView2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="TextView" />

        <Button
            android:id="@+id/button2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Button" />

    </RelativeLayout>

</LinearLayout>

可以说,特定用户无权访问第一部分,因此将从test.xml文件中删除一部分。

XMLDocumentParser(负责将.xml文件解析为Document):

public class XMLDocumentParser implements IXMLDocumentParser {

    @Override
    public Document getDomElement(Context context, int resource) {

        Document doc = null;
        DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();

        try{
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            doc = docBuilder.parse(context.getResources().openRawResource(resource), "UTF-8");
            //doc = docBuilder.parse(new BOMInputStream(context.getResources().openRawResource(resource), false, ByteOrderMark.UTF_8));

        }
        catch (ParserConfigurationException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (SAXException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        } catch (IOException e) {
            Log.e("Error: ", e.getMessage());
            return null;
        }

        return doc;
    }

XML布局构建器(负责删除部分并创建XMLPullParser):

public class XMLLayoutBuilder implements IXMLLayoutBuilder {

    private IXMLDocumentParser documentParser;
    private Context context;

    public XMLLayoutBuilder(Context context) {
        this.context = context;
        documentParser = new XMLDocumentParser();

    }

    @Override
    public XmlPullParser removeUnauthorizedSections(HashMap<String, String> permissions, int resource) {

        Document doc = documentParser.getDomElement(context, resource);

        Node rootNode = doc.getDocumentElement();
        NodeList topLayouts = rootNode.getChildNodes();

        for(int i = 0; i < topLayouts.getLength(); i++){
            Node element = topLayouts.item(i);

            /*
            if(Check for permissions for specific layout and section){
                //Remove node with all its children
                rootNode.removeChild(element);
            }
            */
        }

        return getXMLPullParserFromString(getStringFromDocument(doc));
    }

    private String getStringFromDocument(Document doc)
    {
        try
        {
           DOMSource domSource = new DOMSource(doc);
           StringWriter writer = new StringWriter();
           StreamResult result = new StreamResult(writer);
           TransformerFactory tf = TransformerFactory.newInstance();
           Transformer transformer = tf.newTransformer();
           transformer.transform(domSource, result);
           return writer.toString();
        }
        catch(TransformerException ex)
        {
           ex.printStackTrace();
           return null;
        }
    }

    private XmlPullParser getXMLPullParserFromString(String xml){

        if(xml == null) return null;

        XmlPullParser pullParser;

        try {
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            factory.setNamespaceAware(true);
            pullParser = factory.newPullParser();
            pullParser.setInput(new StringReader(xml));

        } catch (XmlPullParserException e) {
            e.printStackTrace();
            return null;
        } 
        return pullParser;
    }

MainActivity(应该将XMLPullParser的内容扩展到wrapper.xml布局的根元素):

public class MainActivity extends ActionBarActivity {

    private Button btn_login;
    private IHttpRequestProcessor processor;
    private ILayoutBuilder layoutBuilder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.wrapper);

        layoutBuilder = new LayoutBuilder();

        LinearLayout ll = (LinearLayout)findViewById(R.id.ll_root);

        layoutBuilder.buildLayout(null, R.raw.test2, getApplicationContext(), ll);
}
}

LayoutBuilder:

public class LayoutBuilder implements ILayoutBuilder {

    private IXMLLayoutBuilder xmlLayoutBuilder;

    @Override
    public View buildLayout(HashMap<String, String> permissions, int resource, Context context, ViewGroup root) {

        xmlLayoutBuilder = new XMLLayoutBuilder(context);
        XmlPullParser xmlParser = xmlLayoutBuilder.removeUnauthorizedSections(permissions, resource);

        LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(xmlParser, null);


        return null;
    }

}

当我运行应用程序时,我收到此错误:

11-03 12:23:38.822: E/AndroidRuntime(1731): FATAL EXCEPTION: main
11-03 12:23:38.822: E/AndroidRuntime(1731): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.managmentsystem/com.example.managmentsystem.MainActivity}: android.view.InflateException: START_TAG <LinearLayout {http://schemas.android.com/apk/res/android}android:layout_width='match_parent' {http://schemas.android.com/apk/res/android}android:layout_height='match_parent' {http://schemas.android.com/apk/res/android}android:orientation='vertical'>@1:216 in java.io.StringReader@52732da4: Error inflating class <unknown>
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2211)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2261)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.os.Looper.loop(Looper.java:137)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread.main(ActivityThread.java:5103)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at java.lang.reflect.Method.invokeNative(Native Method)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at java.lang.reflect.Method.invoke(Method.java:525)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at dalvik.system.NativeStart.main(Native Method)
11-03 12:23:38.822: E/AndroidRuntime(1731): Caused by: android.view.InflateException: START_TAG <LinearLayout {http://schemas.android.com/apk/res/android}android:layout_width='match_parent' {http://schemas.android.com/apk/res/android}android:layout_height='match_parent' {http://schemas.android.com/apk/res/android}android:orientation='vertical'>@1:216 in java.io.StringReader@52732da4: Error inflating class <unknown>
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.createView(LayoutInflater.java:620)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at com.android.internal.policy.impl.PhoneLayoutInflater.onCreateView(PhoneLayoutInflater.java:56)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.onCreateView(LayoutInflater.java:669)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:694)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.inflate(LayoutInflater.java:469)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.inflate(LayoutInflater.java:373)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at layoutbuilder.LayoutBuilder.buildLayout(LayoutBuilder.java:23)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at com.example.managmentsystem.MainActivity.onCreate(MainActivity.java:40)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.Activity.performCreate(Activity.java:5133)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1087)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2175)
11-03 12:23:38.822: E/AndroidRuntime(1731):     ... 11 more
11-03 12:23:38.822: E/AndroidRuntime(1731): Caused by: java.lang.reflect.InvocationTargetException
11-03 12:23:38.822: E/AndroidRuntime(1731):     at java.lang.reflect.Constructor.constructNative(Native Method)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at java.lang.reflect.Constructor.newInstance(Constructor.java:417)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.LayoutInflater.createView(LayoutInflater.java:594)
11-03 12:23:38.822: E/AndroidRuntime(1731):     ... 21 more
11-03 12:23:38.822: E/AndroidRuntime(1731): Caused by: java.lang.ClassCastException: android.util.XmlPullAttributes cannot be cast to android.content.res.XmlBlock$Parser
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.content.res.Resources$Theme.obtainStyledAttributes(Resources.java:1366)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.content.Context.obtainStyledAttributes(Context.java:416)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.View.<init>(View.java:3317)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.view.ViewGroup.<init>(ViewGroup.java:459)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.widget.LinearLayout.<init>(LinearLayout.java:176)
11-03 12:23:38.822: E/AndroidRuntime(1731):     at android.widget.LinearLayout.<init>(LinearLayout.java:172)
11-03 12:23:38.822: E/AndroidRuntime(1731):     ... 24 more

0 个答案:

没有答案