Использование библиотеки привязки данных для привязки событий
Я пытаюсь связать события с представлениями в xml, используя библиотеку привязки данных , поставляемую с Android M. Я следую примерам из разработчиков Android и реализую шаг за шагом. для атрибутов представления, таких как видимость, текст его работает нормально, но если я попытаюсь связать с onclick, он не работает, как ожидалось. Вот пример кода, который я пробовал до сих пор:
<data>
<import type="android.view.View"/>
<variable name="user" type="com.example.databinding.User"/>
<variable name="handlers" type="com.example.databinding.MyHandlers"/>
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@{user.firstName}"
android:visibility="@{user.isFriend ? View.VISIBLE : View.GONE}" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
android:id="@+id/button"
android:layout_gravity="left"
android:onClick="@{handlers.onClickFriend}"/>
Основная активность:
public class MainActivity extends AppCompatActivity {
User user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityMainBinding binding =
DataBindingUtil.setContentView(this,R.layout.activity_main);
user = new User("Pankaj","Kumar",true,true);
binding.setUser(user);
}
}
MyHandlers:
public class MyHandlers {
public void onClickFriend(View view){
Log.i(MyHandlers.class.getSimpleName(),"Now Friend");
}
public void onClickEnemy(View view){
Log.i(MyHandlers.class.getSimpleName(),"Now Enemy");
}
}
Я написал только необходимый код, чтобы улучшите читабельность. Может кто-нибудь мне в этом помочь?
8 ответов:
Я думаю, что вам также нужно будет связать
handlers
, возможно, что-то вроде этого вonCreate
:MyHandlers handlers = new MyHandlers(); binding.setHandlers(handlers);
Используйте этот формат в xml:
android:onClick="@{handlers::onClickFriend}"
Обратите внимание на
::
, Не беспокойтесь о красных линиях в xml-редакторе, потому что в настоящее время это открытый баг для редактора xml Android Studio.Где
handlers
- переменная из тега data:<data> <variable name="handlers" type="com.example.databinding.MyHandlers"/> </data>
И
onClickFriend
- это ваш метод:public class MyHandlers { public void onClickFriend(View view) { Log.i(MyHandlers.class.getSimpleName(),"Now Friend"); } }
Добавлено
Для дескриптора
onLongClick
в xml добавьте следующее:android:onLongClick="@{handlers::onLongClickFriend}"
И добавьте метод
onLongClickFriend
в ViewModel класс:public class MyHandlers { public boolean onLongClickFriend(View view) { Log.i(MyHandlers.class.getSimpleName(),"Long clicked Friend"); return true; } }
Добавлено
Если вам нужно показать сообщение тоста, вы можете использовать интерфейс (лучший вариант) или передать
context
в классеMyHandlers
в конструкции:public class MyHandlers { private Context context; public MyHandlers(Context context) { this.context = context; } public boolean onLongClickFriend(View view) { Toast.makeText(context, "On Long Click Listener", Toast.LENGTH_SHORT).show(); return true; } }
Не обязательно создавать отдельный класс
MyHandlers
и вызыватьsetHandlers
для обработкиandroid:onClick
. Вы можете просто использовать методы:public void onClickFriend(View view)
иpublic void onClickEnemy(View view)
вMainActivity
. Вид деятельности:public class MainActivity extends AppCompatActivity { User user; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); user = new User("Pankaj", "Kumar", true, true); binding.setUser(user); } public void onClickFriend(View view) { Log.i(MyHandlers.class.getSimpleName(), "Now Friend"); } public void onClickEnemy(View view) { Log.i(MyHandlers.class.getSimpleName(), "Now Enemy"); } }
Макет:
<data> <import type="android.view.View"/> <variable name="user" type="com.example.databinding.User"/> </data> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@{user.firstName}" android:visibility="@{user.isFriend ? View.VISIBLE : View.GONE}" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Click Me" android:id="@+id/button" android:layout_gravity="left" android:onClick="@{onClickFriend}"/>
Рассмотрим пример использования библиотеки привязки данных для шаблона MVVM: http://cases.azoft.com/mvvm-android-data-binding
Если вы собираетесь использовать свою активность, можно также заменить объект
context
, который автоматически привязывается, иначе вы тратите пространство.Для использования в привязке создается специальная переменная с именем context выражения по мере необходимости. Значение для контекста-это контекст из корневое представление getContext (). Переменная контекста будет переопределена явное объявление переменной с таким именем.
binding.setContext(this);
И
<variable name="context" type="com.example.MyActivity"/>
Примечание, Если вы просто используете обычная строка
onClick="someFunc"
, которая вообще не является функцией привязки данных. Это более старая функция, которая использует небольшое размышление, чтобы найти метод в контексте.
Я публикую это, потому что у меня была другая ситуация, в которой это произошло. Если у вас есть два действия, ссылающиеся на файл макета, и одно определяет событие onclick, а другое-нет, вы получаете одно и то же предупреждение и странно в действии, где вы определили событие.
Чтобы проверить это, я рекомендую найти использование файла макета по
right clicking
на имени макета и нажатьfind references
. Не забудьте восстановить послесловие приложения.
Множество способов установить клики
1) передать обработчик в привязку.
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main); Hander handler = new Handler(); binding.setHandlers(handlers);
2) установить клики (используйте любой из приведенных ниже)
android:onClick="@{handler::onClickMethodReference}" android:onClick="@{() -> handler.onClickLamda()}" android:onClick="@{(v) -> handler.onClickLamdaWithView(v)}" android:onClick="@{() -> handler.onClickLamdaWithView(model)}" public class Handler { public void onClickMethodReference(View view) { // } public void onClickLamda() { // } public void onClickLamdaWithView(View view) { // } public void onClickLamdaWithObject(Model model) { // } }
Обратите внимание, что
- Вы можете использоватьссылку на метод (::) , когда у вас есть тот же аргумент, что и атрибутonClick .
- вы можете передать любой объект, например
onClickLamdaWithObject
.- Если вам нужно передать
View
объект, то просто используйте(v)->
выражение лица.Дальнейшее чтение
Https://developer.android.com/topic/libraries/data-binding/expressions
Я публикую это только для того, чтобы охватить оба способа достижения этого. 1. на слушателя обязательными 2. по методу refernce
Расположение:
<layout...> <data> <variable name="handlers" type="com.example.databinding.MyPresenter" /> <variable name="user" type="com.example.databinding.User"/> </data> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="Using Listener Binding" android:onClick="@{() -> handlers.onLisClick(user)}"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="32dp" android:text="Using Method Ref" android:onClick="@{handlers::onButtonClicked}"/> </LinearLayout> </layout>
Деятельность:
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); MyPresenter presenter = new MyPresenter(); User user = new User("Alex","RJ") binding.setUser(user); binding.setHandlers(presenter); }
MyPresenter:
public class MyPresenter{ //using listener binding public void onLisClick(User user){ //do something.. } //using method reference public void onButtonClicked(View view){ // do something } }
Примечание:
1.При использовании ссылки на метод сигнатура метода должна быть такой же, как и для любого другого метода onClick, т. е. public и View as parameter.2.При использовании привязки слушателя у вас есть преимущество, что вы можете непосредственно передать объект также, если вы хотите и сделать любой операция.