Ответ 1
Я думаю, вам нужно будет привязать handlers
, возможно, что-то вроде этого в onCreate
:
MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
Я пытаюсь связать события с представлениями в xml с помощью DataBinding Library, поставляемой с Android M. Я следую примерам из Android Developers и шаг за шагом. для атрибутов вида, таких как видимость, текст работает нормально, но если я пытаюсь связать с 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}"/>
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);
}
}
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");
}
}
Я написал только необходимый код, чтобы улучшить удобочитаемость. Может ли кто-нибудь помочь мне в этом.
Я думаю, вам нужно будет привязать handlers
, возможно, что-то вроде этого в onCreate
:
MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
Используйте этот формат в xml:
android:onClick="@{handlers::onClickFriend}"
Обратите внимание на ::
, не беспокойтесь о красных строках в редакторе xml, потому что в настоящее время это открыто ошибка для Редактор XML для Android Studio.
Где handlers
- ваша переменная из тега данных:
<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");
}
}
ADDED
Для дескриптора 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;
}
}
ADDED
Если вам нужно показать сообщение тоста, вы можете использовать интерфейс (лучший вариант) или передать 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;
}
}
Ты должен сделать
android:onClick="@{() -> handlers.onClickFriend()}"
Не обязательно создавать отдельный класс 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 для использования в привязке выражения по мере необходимости. Значение контекста - это контекст из root Посмотреть 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) {
//
}
}
Обратите внимание, что
onClickLamdaWithObject
.View
просто используйте (v)->
expression.дальнейшее чтение
https://developer.android.com/topic/libraries/data-binding/expressions
Я публикую это только для того, чтобы охватить оба способа достижения этой цели. 1. привязкой слушателя 2. методом ссылки
расположение:
<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.
2. При использовании привязки слушателя вы получаете преимущество в том, что вы можете напрямую передавать Объект, если хотите, и выполнять какие-либо операции.