Возможность добавить параметры в кнопку xml? - PullRequest
39 голосов
/ 18 апреля 2011

В настоящее время у меня есть действие с некоторыми кнопками.

В моем xml кнопки определены следующим образом:

    <ImageButton (...) android:onClick="GoToPageX"/>

, и у меня в активности:

public void GotoPageX() {
    startActivity(new Intent(this, PageX.class));
    finish();

}

Проблема в том, что у меня есть сотни кнопок и я не хочу писать

<ImageButton (...) android:onClick="GoToPage1"/>
<ImageButton (...) android:onClick="GoToPage2"/>
<ImageButton (...) android:onClick="GoToPage3"/>
...
<ImageButton (...) android:onClick="GoToPage100"/>

и все сценарии.

Я сейчас использую

public void GotoPage( int i) {
    startActivity(new Intent(getBaseContext(), activities.get(i)));
    finish();
}

и хотел бы дать параметр i из xml, это возможно?

Большое спасибо за любую помощь.

Ответы [ 4 ]

93 голосов
/ 18 апреля 2011

Это не возможно напрямую.Однако, возможно, вы могли бы использовать android:tag для получения вашего параметра.

<ImageButton (...) android:onClick="goToPage" android:tag="25"/>

public void goToPage(View v) {
    String pageNumber = v.getTag().toString(); 
    /* ... */
}
2 голосов
/ 07 февраля 2019

Вы также можете сделать это, включив привязку данных и используя лямбда-выражение для значения onClick. Этот способ особенно полезен, если вы планируете использовать несколько входов разных типов. Вот пример простого MainActivity.xml , в котором используется эта стратегия.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="main" type="com.example.android.myapp.MainActivity" />
    </data>
    <LinearLayout android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(1,"one")}'/>
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(2,"two")}'/>
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(3,"three")}'/>
        ...
        <ImageButton (...) android:onClick='@{() -> main.GotoPage(100,"one hundred")}'/>
    </LinearLayout>
</layout>

и MainActivity.java

public void GotoPage(int i, String otherVariable) {
    /** code using i and otherVariable **/
}

ОБНОВЛЕНИЕ: Для тех, кто не знает, как настроить привязку данных, я объясню здесь, чтобы вам не приходилось гуглить. Сначала включите dataBinding в файле build.gradle :

android {
    ...
    dataBinding {
        enabled = true
    }
    ...
}

Также убедитесь, что jcenter() есть в ваших репозиториях.

Затем перейдите к XML макета, где будет использоваться onClick, и оберните его макет в тег layout с секцией data, например:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
    <data>
        <variable name="main" type="com.example.android.yourapp.MainActivity" />
    </data>
    <YourLayout>
        ...
    </YourLayout>
</layout>

Для параметра type тега variable необходимо указать класс, который будет содержать функцию, на которую указывает onClick. В этом примере я буду использовать основной класс активности с именем MainActivity в моем тестовом проекте.

После того, как ваш макет обернут в тег layout, как в примере выше, очистите проект в Android Studio. Вам также может понадобиться отключить кэш / перезапустить или закрыть и снова открыть Android Studio.

Далее, если макет с onClick, для которого вы пытаетесь настроить привязку данных, совпадает с макетом, установленным setContentView в вашем основном классе активности, откройте файл, содержащий ваш основной класс активности. Если макет с onClick, для которого вы пытаетесь настроить привязку данных, программно раздувается в другом файле, откройте файл, в котором вместо этого раздувается макет.

Добавьте этот импорт в этот файл:

import com.example.android.yourapp.databinding.YourLayoutBinding;
import android.databinding.DataBindingUtil;

Этот первый класс, который вы импортируете, генерируется при очистке проекта (и, возможно, придется аннулировать кэш / перезапуск), и ему автоматически присваивается имя XML-файла, к которому вы добавили оболочку layout. Если файл макета имеет имя your_layout.xml , класс импорта будет иметь имя YourLayoutBinding. Точный путь импорта будет зависеть от имени и структуры вашего приложения, но он всегда будет в пределах databinding родительского класса.

Следующий шаг зависит от того, задан ли макет, к которому вы добавляете привязку данных, с помощью setContentView или надут ли inflate. Обе версии следующего шага используют метод setMain. Метод setMain генерируется автоматически и получает имя с использованием значения параметра name в добавленной нами оболочке layout. Поскольку мы ставим name="main", метод называется setMain.


Если макет, к которому вы добавляете привязку данных, совпадает с макетом, установленным setContentView, найдите строку в вашем основном классе активности, которая выглядит как setContentView(R.layout.your_layout);, и измените ее на использование DataBindingUtil.setContentView setContentView, добавив this в качестве первого аргумента. Используйте binding.setMain, чтобы указать переменную макета main на текущее действие.

YourLayoutBinding binding = DataBindingUtil.setContentView(this, R.layout.your_layout);
binding.setMain(this);

Если компоновка, к которой вы добавляете привязку данных, установлена ​​не setContentView, а скорее раздутой , перейдите туда, где она завышена в вашем коде. Это должно выглядеть примерно так:

return inflater.inflate(R.layout.your_layout, container, false);

Измените его, чтобы использовать DataBindingUtil.inflate, добавив предыдущий инфлятор в качестве первого аргумента. Используйте binding.setMain, чтобы указать переменную макета main на основное действие, и используйте binding.getRoot(), чтобы получить представление. Это должно закончиться так:

YourLayoutBinding binding = DataBindingUtil.inflate(inflater, R.layout.your_layout, container, false);
binding.setMain((MainActivity) getActivity());
return binding.getRoot();

Теперь привязка данных готова к использованию. Добавьте функцию для onClick, чтобы она указывала в вашем основном классе активности.

public void exampleFunction(int number, String text) {
    System.out.println("Number: " + number + ", Text: " + text);
}

Вы можете вызвать его из макета, к которому вы добавили привязку данных, используя лямбда-выражение. Для этого примера функции не требуется View, поэтому ее можно использовать так:

<Button android:id="@+id/buttonID"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="26sp"
    android:text="Test"
    android:onClick='@{() -> main.exampleFunction(123, "test")}'/>

Обязательно используйте одинарные кавычки вокруг значения для onClick, если вы планируете использовать String.

Если вам нужно передать представление кнопки в вашу функцию, просто добавьте параметр View к обязательным аргументам вашей функции и используйте вместо этого лямбда-выражение:

<Button android:id="@+id/buttonID"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:textSize="26sp"
    android:text="Test"
    android:onClick='@{(view) -> main.exampleFunction(view, 123, "test")}'/>
2 голосов
/ 18 апреля 2011

Если вы создадите какой-то элемент макета в xml, вы можете использовать его там

<ImageButton
    android:id="@+id/some_id_value" />

, где some_id_value - это уникальная строка, которая будет преобразована в id, который хранится в R.java (лучше длявы ничего не меняете там), чем в коде вы можете получить этот идентификатор, используя

R.id.some_id_value

прочитайте немного там это действительно основы.

1 голос
/ 26 февраля 2016

Вы можете установить теги для просмотра.Теги - это, по сути, способ представления воспоминаний.

xml:

<ImageButton
    ...Other Parameters...
    android:id="@+id/Button2"
    android:tag="2"
    android:onClick="GoToPageX"/>
<ImageButton
    ...Other Parameters...
    android:id="@+id/Button3"
    android:tag="3"
    android:onClick="GoToPageX"/>

Строка android:tag="2" устанавливает значение тега 2 (тип данных строки) равным Button2

Java-файл:

Общий случай:
Внутри GoToPageX(View v), используйте v.getTag(), чтобы получить значение тегасоответствующий вид (из которого когда-либо был вызван метод).

Ваш случай:
Добавьте метод следующим образом

public void GoToPageX(View v){
    int i = Integer.parseInt(v.getTag()); //parseInt converts string to integer
    startActivity(new Intent(getBaseContext(), activities.get(i)));
    finish();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...