Вы также можете сделать это, включив привязку данных и используя лямбда-выражение для значения 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")}'/>