Подтвердить что ты не робот

Использование библиотеки DataBinding для привязки событий

Я пытаюсь связать события с представлениями в 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");
  }
}

Я написал только необходимый код, чтобы улучшить удобочитаемость. Может ли кто-нибудь помочь мне в этом.

4b9b3361

Ответ 1

Я думаю, вам нужно будет привязать handlers, возможно, что-то вроде этого в onCreate:

MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);

Ответ 2

Используйте этот формат в 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;
    }
}

Ответ 3

Ты должен сделать

android:onClick="@{() -> handlers.onClickFriend()}"

Ответ 4

Не обязательно создавать отдельный класс 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

Ответ 5

Если вы собираетесь использовать свою активность, также можно заменить объект context, который автоматически привязан, иначе вы теряете пространство.

Создается специальная переменная с именем context для использования в привязке выражения по мере необходимости. Значение контекста - это контекст из root Посмотреть getContext(). Переменная контекста будет переопределена явное объявление переменной с этим именем.

binding.setContext(this);

и

<variable name="context" type="com.example.MyActivity"/>

Обратите внимание, если вы просто используете обычную строку onClick="someFunc", которая не является функциональностью привязки данных вообще. Это более старая функция, которая использует небольшое отражение для поиска метода в контексте.

Ответ 6

Я публикую это, потому что у меня была другая ситуация, в которой это произошло. Если у вас есть два действия, ссылающиеся на файл макета, и одно определяет событие onclick, а другое не выдает то же предупреждение и странным образом в действии, в котором вы определили событие.

Чтобы проверить это, я рекомендую найти использование файла макета, right clicking по имени макета и нажав " find references. Не забудьте перестроить приложение после слов.

Ответ 7

Много способов установить клики

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) {
        //
    }
}

Обратите внимание, что

  • Вы можете использовать метод Reference (: :), если у вас тот же аргумент, что и у атрибута onClick.
  • Вы можете передать любой объект, например, onClickLamdaWithObject.
  • Если вам нужно передать объект View просто используйте (v)-> expression.

дальнейшее чтение

https://developer.android.com/topic/libraries/data-binding/expressions

Ответ 8

Я публикую это только для того, чтобы охватить оба способа достижения этой цели. 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. При использовании привязки слушателя вы получаете преимущество в том, что вы можете напрямую передавать Объект, если хотите, и выполнять какие-либо операции.