динамическое количество элементов gui в Android?

#android #user-interface #android-layout

#Android #пользовательский интерфейс #android-layout

Вопрос:

Я хочу создать приложение с графическим интерфейсом для Android, где пользователь сможет добавлять или удалять поля определенного типа (4 разных типа полей) в приложение. Есть ли способ сделать это в xml?

Единственный способ, которым я мог бы это сделать, — отредактировать XML-файл из приложения, что для меня звучит как плохая идея.

Надеюсь, мой вопрос понятен.

Yotam.

Редактировать:

Я добавил простой код для прямого внедрения java:

импортируйте android.app.Activity; импортируйте android.graphics.Цвет; импортировать android.os.Bundle; импортировать android.view.ViewGroup; импортировать android.widget.TextView;

 public class Leonidas extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.counter);
        TextView TV = new TextView (this);
        TextView UV = new TextView (this);
        TV.setText("hello");
        UV.setText("goof");
        //setContentView(TV);
        //setContentView(UV);
        ViewGroup.LayoutParams lpars = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
        this.addContentView(UV,lpars);
        this.addContentView(TV, lpars);
        this.setVisible(true);
    }
}
  

Правка2:

Я искал, например, и получил следующее рабочее:

 LayoutInflater inflater;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    inflater = LayoutInflater.from(this);
    Button b = (Button) this.findViewById(R.id.alert);
    b.setOnClickListener(this);
}

@Override
public void onClick(View v) {
    final LinearLayout canvas = (LinearLayout)Leonidas.this.findViewById(R.id.counter_field);
    final View cv = this.inflater.inflate(R.layout.counter,canvas,false);
    canvas.addView(cv);
}
  

Комментарии:

1. Если у вас есть пользовательские представления, которые определены в XML, вы можете создавать их динамически с помощью Java, используя View Inflator. Я не думаю, что вы даже можете редактировать свои собственные XML-файлы во время работы. Вам почти наверняка придется создавать эти представления на java и добавлять их в свой макет вместо того, чтобы пытаться редактировать XML-файлы макета.

Ответ №1:

Вы также можете сделать это из своего обработчика (в классе реализации).

После расширения вашего XML-макета вы реагируете на какие-либо взаимодействия с пользователем. В обработчике вы

  • либо создайте новое представление с нуля, и укажите его layoutparams ,
  • или раздуть один с помощью xml

После создания нового представления вы добавляете его в текущее ( this ) представление, и благодаря его параметрам layout оно будет того размера, формы, цвета и т.д., Которые вы хотите.

Обновить:

Если вы хотите добавить более сложные представления в свою деятельность, лучше записать их в xml и раздуть:

sample_component.xml : // внутри res/layout

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent" 
    android:layout_height="wrap_content" android:padding="0px">
    <TextView android:id="@ id/servicename_status" android:paddingLeft="15px" 
        android:paddingRight="5px"
        android:textStyle="bold" android:focusable="false" android:textSize="14px"
        android:layout_marginLeft="10px" android:layout_marginRight="3px" 
        android:layout_width="fill_parent" android:layout_height="wrap_content" />
    <TextView android:id="@ id/lastcheck" android:focusable="false"
        android:textSize="14px" android:layout_width="fill_parent"
        android:layout_marginLeft="10px" android:layout_marginRight="3px" 
        android:layout_height="wrap_content" android:layout_below="@id/servicename_status" />
    <TextView android:id="@ id/duration" android:focusable="false"
        android:textSize="14px" android:layout_width="fill_parent"
        android:layout_marginLeft="10px" android:layout_marginRight="3px" 
        android:layout_height="wrap_content" android:layout_below="@id/lastcheck" />
    <TextView android:id="@ id/attempt" android:focusable="false"
        android:textSize="14px" android:layout_width="fill_parent"
        android:layout_marginLeft="10px" android:layout_marginRight="3px" 
        android:layout_height="wrap_content" android:layout_below="@id/duration" />
    <TextView android:id="@ id/statusinfo" android:focusable="false"
        android:textSize="14px" android:layout_width="fill_parent"
        android:layout_marginLeft="10px" android:layout_marginRight="3px" 
        android:layout_height="wrap_content" android:layout_below="@id/attempt" />
    <CheckBox android:id="@ id/alert" android:focusable="false" 
        android:layout_alignParentRight="true" android:freezesText="false"
        android:layout_width="wrap_content" android:layout_height="wrap_content" 
        android:layout_marginTop="5px" />
</RelativeLayout>
  

Внутри вашего Leonidas класса activity у вас есть обработчики, которые должны реагировать на различные действия пользователя, добавляя / удаляя элементы в / из представления.
Ниже приведен пример обработчика события click, который использует LayoutInflater , чтобы добавить sample_component.xml представление к вашей активности:

 public final class MyClickListener implements View.OnClickListener
{
    private LayoutInflater inflater;

    public MyClickListener()
    {
        inflater = LayoutInflater.from(Leonidas .this);
    }

    @Override
    public void onClick(View v)
    {
        //  TODO: change RelativeLayout here to whatever layout 
        //  you'd like to add the new components to
        final RelativeLayout canvas = (RelativeLayout)Leonidas.this.findViewById(R.id.my_canvas);
        final View childView = inflater.inflate(R.layout.sample_component, canvas, false);
        //  TODO: Look up the 5 different signatures of the addView method, 
        //  and pick that best fits your needs
        canvas.addView(childView);

        // check which button was pressed
        switch (view.getId())
        {
            case R.id.btn_prev:
                //handler for the prev button
                break;
            case R.id.btn_next:
                //handler for the next button
                break;
            default:
                break;
        }
    }
}
  

Обратите внимание, что MyClickListener реализован как встроенный класс в вашей активности Leonidas, вот почему для context параметра он используется: this.Leonidas .

Обновить

R.id.my_canvas будет идентификатором представления, в которое вы хотите добавить компоненты. это в вашем main.xml (или любой другой xml, который вы используете для своего представления Leonidas).

Если вы поместите класс MyClickListener в свой Leonidas.java класс (объявите как встроенный класс), он распознает его.

Комментарии:

1. Спасибо. Я попытался найти руководства по использованию xml inflation, но не смог найти ни одного, который был бы мне понятен.

2. я только что обновил этот ответ небольшим примером использования inflater, возможно, это поможет вам прояснить ситуацию.

3. Это немного помогло, но все же …:( Во-первых, ваша строка, которая заканчивается Leonidas.this.findViewById(R.layout.my_canvas), не имеет никакого смысла ни для меня, ни для eclipse. Я пытался что-то угадать из автозаполнения, но тщетно. Во-вторых, когда я пытаюсь ввести Leonidas. в этой части eclipse говорится, что ни один заключающий экземпляр типа Leonidas не доступен в области видимости . Спасибо

4. Спасибо. У меня все работает, но теперь у меня возник новый вопрос. Как я могу определить, какая кнопка была нажата? Я хочу использовать прослушиватель с одним щелчком мыши, чтобы решить, какой метод вызывать. Я предполагаю, что это роль части (View v) в коде, но что я могу с этим сделать? Спасибо

5. Вы должны изучить view.getId() . проверьте обновление для примера

Ответ №2:

Вместо указания элементов в XML, вы можете создавать их динамически и добавлять в пользовательский интерфейс. Это продемонстрировано в руководстве по Android Hello World здесь.

Комментарии:

1. Спасибо. Я пытался это сделать, но не смог понять, как использовать метод addContent. То, что я получил, — это два представления, одно поверх другого. Я предполагаю, что мне нужно установить параметр более «элегантным» способом, чем я сделал. Я прикрепил простой код к своему исходному тексту.