如何在Android上扩展包含标记

时间:2011-03-13 13:52:39

标签: android templates view android-layout

我最终有许多xml文件在页眉和页脚上共享相同的代码。有没有什么好方法可以创建某种模板并将其传递给中间包含的资源?

换句话说,如何以这样一种方式扩展Include标记,而不是简单地包含一个视图,包括一个包含给定资源的模板?

我凌乱的代码:

<?xml version="1.0" encoding="utf-8"?>
<include layout="@layout/settings_section" />

settings_section.xml:

<?xml version="1.0" encoding="utf-8"?>
<!--Header Begin-->
<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical"
  android:padding="10dp"
 >
<LinearLayout
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@layout/my_shape"
 android:orientation="vertical"
 ><include layout="@layout/header" />
<!--End header-->


          <TextView 
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="10dp"
                android:text="Blah blah blah"
                />


<!--Footer Begin -->
</LinearLayout>        
</LinearLayout>
<!-- Footer End -->    

我想要的是什么:

<include layout="@layout/header" />
<com.example.Include layout="@layout/settings_section" inside="@layout/default_template" />

编辑:我正在寻找代码示例。

5 个答案:

答案 0 :(得分:2)

这并不能完全回答你的问题,但我已经将风格用于类似情况。

RES /布局/ layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    style="@style/header1" >
    <LinearLayout
        style="@style/header2" >
        <include layout="@layout/header" />
...

RES /值/ styles.xml

...
<style name="header1">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:orientation">vertical</item>
    <item name="android:padding">10dp</item>
</style>
<style name="header2">
    <item name="android:layout_width">fill_parent</item>
    <item name="android:layout_height">fill_parent</item>
    <item name="android:background">@layout/my_shape</item>
    <item name="android:orientation">vertical</item>
<style>
...

无论如何,这种方法简化了您必须复制/粘贴到多个文件的部分,并使修改它们变得相当简单和灵活。如果需要,您可以在layout.xml中进行修改 - 您在样式中给出的值会被覆盖 - 修改样式会影响使用它们的所有布局。

答案 1 :(得分:1)

只是一个想法:在settings_section xml内部,我将创建一个带有id的容器(LinearLayout)。然后在Activity.onCreate()中,我会通过其ID找到该容器,并向其添加一个子项(default_template)。

然后我会使用受保护的方法YourBaseActivity创建某种addContent(int contentId),因此查找容器并向其插入内容的代码不会在其他类似活动中重复。

答案 2 :(得分:1)

如果你想要你描述的行为,那么它是可能的 - 你必须创建一个扩展LinearLayout的自定义视图类(参见Building Custom Components)。创建这个视图时,它可以获得指定的属性在XML中(参见Passing custom variables via XML resources),并夸大这些资源。

设置XML看起来像

<LinearLayout
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@layout/my_shape"
 android:orientation="vertical"
 ><include layout="@layout/header" />
<!--End header-->
<TextView 
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:padding="10dp"
                android:text="Blah blah blah"
                />


<!--Footer Begin -->
</LinearLayout>  

请注意,我已经删除了内容的最外层LinearLayout,因为您的自定义视图无论如何都是LinearLayout的类型。如果我有时间,我会稍后点击DoubleInclude视图并发布代码。

答案 3 :(得分:1)

这是一个xml模板

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView 
android:id="@+id/myviewHeader" 
android:layout_height="wrap_content" 
android:layout_width="fill_parent" >
</TextView>
<LinearLayout
android:id="@+id/myviewIncluder" 
android:layout_height="wrap_content" 
android:layout_width="fill_parent" >
</LinearLayout>
<TextView 
android:id="@+id/myviewFooter" 
android:layout_height="wrap_content" 
android:layout_width="fill_parent" >
</TextView>
</LinearLayout>

和具有动态内容的ViewGroup的类

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MyView extends ViewGroup {
private LayoutInflater mInflater;
private TextView header;
private TextView footer;
public MyView(Context context,View child) {
super(context);
mInflater = LayoutInflater.from(context);
mInflater.inflate(R.layout.myview, this);  
LinearLayout includer = (LinearLayout) findViewById(R.id.myviewIncluder);
header = (TextView) findViewById(R.id.myviewHeader);
footer = (TextView) findViewById(R.id.myviewFooter);
includer.addView(child);
}


@Override
protected void onLayout(boolean arg0, int arg1, int arg2, int arg3, int arg4) {
    // TODO Auto-generated method stub

}

public void set_HeaderText(String text){
    header.setText(text);
}

public void set_FooterText(String text){
    footer.setText(text);
}
}

如果您想在Includer部分添加视图,yozu可能会这样:

    View include = null;
    LayoutInflater mInflater = LayoutInflater.from(this);
    include = mInflater.inflate(R.xml.list_item_icon_text,null);
    ViewGroup text = new MyView(this,include);

答案 4 :(得分:0)

默认的Eclipse构建系统不像我看到的那么灵活,但如果您愿意使用Ant作为构建系统,那么您可以在构建时执行更多操作,例如生成XML文件。 Eclipse可以使用Ant来构建项目而不是它自己的构建系统,因为这对于某些项目来说是常见的。通过在@Arhimed建议的构建时而不是运行时生成XML文件,您可以看到文件XML源并在Eclipse中呈现它以确保它看起来正确。这种方法更先进,但它提供了更大的灵活性。一旦您使用Ant,您还可以执行其他操作,例如生成具有不同设置的应用程序的两个版本,例如付费版本和精简版本。这是Ant对FilterChains的介绍:http://ant.apache.org/manual/Types/filterchain.html以及使用Ant进行安卓apk的海关构建的文档:http://blog.elsdoerfer.name/2010/04/29/android-build-multiple-versions-of-a-project/