Как расширить тег включения на Android - PullRequest
4 голосов
/ 13 марта 2011

В итоге у меня было много xml-файлов с одинаковым кодом в верхнем и нижнем колонтитулах.Есть ли какой-нибудь хороший способ создать какой-то шаблон и передать ему ресурс для включения в середину?

Другими словами, как расширить тег «Включить» таким образом, как я мог бы, а не просто включитьпредставление, включить шаблон, который включает данный ресурс?

Мой грязный код:

<?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 ]

2 голосов
/ 05 апреля 2011

Это не дает точного ответа на ваш вопрос, но я использовал стили для подобных ситуаций.

res / layout / 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 / values ​​/ 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 голос
/ 04 апреля 2011

вот шаблон 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);
1 голос
/ 03 апреля 2011

Если вам нужно описанное вами поведение, то это возможно - вам придется создать собственный класс представления, расширяющий LinearLayout (см. Создание пользовательских компонентов) . Когда это представление создано, оно может получить атрибуты, указанные в XML (см. Передача пользовательских переменных через ресурсы XML ), и накачать эти ресурсы.

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 представление позже и отправлю код.

1 голос
/ 13 марта 2011

Просто идея: внутри settings_section xml я бы создал контейнер (LinearLayout) с идентификатором. Затем в Activity.onCreate() я бы нашел этот контейнер по его идентификатору и добавил к нему дочерний элемент (default_template).

Тогда я бы создал какой-то YourBaseActivity с защищенным методом addContent(int contentId), поэтому код для поиска контейнера и вставки в него содержимого не повторяется при других подобных действиях.

0 голосов
/ 02 апреля 2011

Система сборки Eclipse по умолчанию не очень гибкая из того, что я видел, но если вы хотите использовать Ant для своей системы сборки, вы можете сделать гораздо больше во время сборки, например, генерировать файлы XML.Eclipse может использовать Ant для сборки проекта вместо своей собственной системы сборки, как это часто бывает в некоторых проектах.Генерируя XML-файлы во время сборки, а не во время выполнения, как предлагает @Arhimed, вы можете увидеть исходный XML-файл и отобразить его в Eclipse, чтобы убедиться, что он выглядит правильно.Этот подход немного более продвинутый, но он предлагает гораздо большую гибкость.После того, как вы используете Ant, вы также можете создавать другие версии приложения с разными настройками, например, платную и облегченную версии.Вот введение Ant в FilterChains: http://ant.apache.org/manual/Types/filterchain.html и документ об использовании Ant для таможенных сборок Android apk: http://blog.elsdoerfer.name/2010/04/29/android-build-multiple-versions-of-a-project/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...