web-dev-qa-db-fra.com

Android La liaison de données transmet les arguments à la méthode onClick

Est-il possible de passer des arguments personnalisés à la méthode onClick à l'aide de la bibliothèque de liaisons de données? J'ai mon fichier XML de mise en page où je dois utiliser le onClickListener:

<?xml version="1.0" encoding="utf-8"?>
<layout ...>

    <data>
        <variable
            name="viewModel"
            type="com.productivity.tiktak.ui.tracker.viewModel.CategoryViewModel"/>
        <variable
            name="callback"
            type="com.productivity.tiktak.ui.tracker.TrackerAdapter"/>
    </data>

    <Android.support.v7.widget.CardView
        Android:onClick="@{callback.onCategoryClick(viewModel)}"
        ...
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">

       <!-- ... Some stuff -->

    </Android.support.v7.widget.CardView>
</layout>

et j'ai un code de gestionnaire de clics ici:

public void onCategoryClick(View view, CategoryViewModel categoryViewModel)
{
    //handler code...
}

Est-il possible de passer mon objet CategoryViewModel de XML au gestionnaire de clics?

41
kolodach

Vous pouvez utiliser une expression lambda.

 Android:onClick="@{() -> callback.onCategoryClick(viewModel)}"

Si vous avez besoin de la vue, vous pouvez également la transmettre avec:

 Android:onClick="@{(v) -> callback.onCategoryClick(v, viewModel)}"
86
yigit

Plusieurs façons:

Solution 1 (lorsque vous avez le présentateur)

Vous avez une classe de présentateur ou de gestionnaire comme ci-dessous

public class Presenter {
    public void onSaveClick(View view, Task task){}
}

Maintenant, prenons une variable de type Presenter dans votre mise en page. et placez le clic comme ci-dessous.

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <data>
        <variable name="task" type="com.Android.example.Task" />
        <variable name="presenter" type="com.Android.example.Presenter" />
    </data>
    <LinearLayout ...>
        <Button 
           Android:layout_width="wrap_content" 
           Android:layout_height="wrap_content"
           Android:onClick="@{(view) -> presenter.onSaveClick(view, task)}"
           />
    </LinearLayout>
</layout>

Vous pouvez ajouter d'autres arguments dans ceci.

Veuillez noter que vous devez définir ces variables de données. Comme

ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
binding.setTask(task);
binding.setPresenter(presenter);

Solution 2 (lorsque vous n'avez pas de présentateur)

Créez un type de variable de votre activité/fragment

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android">
    <data>
        <variable name="task" type="com.Android.example.Task" />
        <variable name="activity" type="com.example.MainActivity" />
    </data>
    <LinearLayout ...>
        <Button 
           Android:layout_width="wrap_content" 
           Android:layout_height="wrap_content"
           Android:onClick="@{(view) -> activity.onSaveClick(view, task)}"
           />
    </LinearLayout>
</layout>

et créez dans votre activité la méthode que vous souhaitez appeler à partir de la mise en page obligatoire. et n'oubliez pas d'appeler setActivity(YourActivity.this) depuis Activity.

public class MainActivity extends AppCompatActivity {
    public void onSaveClick(View view, Task task) {
        System.out.println("MainActivity.onSaveClick");
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main);
        binding.setActivity(this);
        binding.setTask(task);
    }
}

Lectures supplémentaires documentation Android DataBinding

Il y a beaucoup d'autres façons de définir click, check this answer.

6
Khemraj