J'essaie de lier des événements avec des vues au format xml en utilisant la bibliothèque DataBinding fournie avec Android M. Je suis exemples de Développeurs Android et implémentation étape par étape pour les attributs de la vue tels que la visibilité, le texte fonctionne correctement, mais si j'essaie de faire une liaison avec onclick, cela ne fonctionne pas comme prévu. Voici l'exemple de l'exemple code que j'ai essayé jusqu'à présent:
<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}"/>
Activité principale :
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");
}
}
J'ai écrit seulement le code requis pour améliorer la lisibilité. Quelqu'un pourrait-il m'aider à ce sujet?.
Je pense que vous aurez également besoin de lier le handlers
, peut-être quelque chose comme ceci dans onCreate
:
MyHandlers handlers = new MyHandlers();
binding.setHandlers(handlers);
1) Passez le gestionnaire à la liaison.
ActivityMainBinding binding = DataBindingUtil.setContentView(this,R.layout.activity_main);
Hander handler = new Handler();
binding.setHandlers(handlers);
2) Définissez les clics (utilisez l’un des choix ci-dessous)
Android:onClick="@{handler::onClickMethodReference}"
OR
Android:onClick="@{handler.onClickMethodReference}"
OR
Android:onClick="@{() -> handler.onClickLamda()}"
OR
Android:onClick="@{(v) -> handler.onClickLamdaWithView(v)}"
OR
Android:onClick="@{() -> handler.onClickLamdaWithView(model)}"
Voir la classe Handler pour comprendre.
public class Handler {
public void onClickMethodReference(View view) {
//
}
public void onClickLamda() {
//
}
public void onClickLamdaWithView(View view) {
//
}
public void onClickLamdaWithObject(Model model) {
//
}
}
Notez que
onClickLamdaWithObject
example.View
, utilisez simplement (v)->
_ expression.Autres lectures
https://developer.Android.com/topic/libraries/data-binding/expressions
Utilisez ce format dans votre XML:
Android:onClick="@{handlers::onClickFriend}"
Faites attention au ::
_, ne vous inquiétez pas des lignes rouges dans l'éditeur xml, car c'est actuellement ouvert bug pour l'éditeur Android Studio xml.
Où handlers
est votre variable de balise de données:
<data>
<variable name="handlers" type="com.example.databinding.MyHandlers"/>
</data>
et onClickFriend
est votre méthode:
public class MyHandlers {
public void onClickFriend(View view) {
Log.i(MyHandlers.class.getSimpleName(),"Now Friend");
}
}
[~ # ~] ajouté [~ # ~]
Pour le handle onLongClick
au format XML, ajoutez ceci:
Android:onLongClick="@{handlers::onLongClickFriend}"
et ajoutez la méthode onLongClickFriend
dans votre classe ViewModel:
public class MyHandlers {
public boolean onLongClickFriend(View view) {
Log.i(MyHandlers.class.getSimpleName(),"Long clicked Friend");
return true;
}
}
[~ # ~] ajouté [~ # ~]
Si vous devez afficher un message toast, vous pouvez utiliser l'interface (meilleure variante) ou passer context
dans la classe MyHandlers
en construction:
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;
}
}
Si vous souhaitez utiliser votre activité, vous pouvez également remplacer l'objet context
qui est automatiquement lié, sinon vous perdez de l'espace.
Une variable spéciale nommée context est générée pour être utilisée dans les expressions de liaison en fonction des besoins. La valeur de context est le contexte de getContext () de la vue racine. La variable de contexte sera remplacée par une déclaration de variable explicite portant ce nom.
binding.setContext(this);
et
<variable name="context" type="com.example.MyActivity"/>
Notez que si vous utilisez simplement la chaîne onClick="someFunc"
ce n'est pas du tout une fonctionnalité de liaison de données. C'est une ancienne fonctionnalité qui utilise un peu de réflexion pour trouver la méthode sur le contexte.
Tu devrais faire
Android:onClick="@{() -> handlers.onClickFriend()}"
Je poste ceci juste pour couvrir les deux manières d'y parvenir. 1. par Listener binding 2. par méthode refernce
disposition:
<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>
Activité:
@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);
}
Mon présentateur:
public class MyPresenter{
//using listener binding
public void onLisClick(User user){
//do something..
}
//using method reference
public void onButtonClicked(View view){
// do something
}
}
Remarque:
1.Lorsque vous utilisez la référence à la méthode, la signature de la méthode doit être identique à celle que vous écrivez pour toute autre méthode de onClick, c'est-à-dire publique et Voir comme paramètre.
2.Lorsque vous utilisez la liaison d’écoute, vous avez l’avantage de pouvoir transmettre directement l’objet même si vous le souhaitez et de réaliser n’importe quelle opération.
Il n'est pas obligatoire de créer la classe séparée MyHandlers
et d'appeler setHandlers
pour le traitement de Android:onClick
. Vous pouvez simplement utiliser les méthodes: public void onClickFriend(View view)
et public void onClickEnemy(View view)
dans MainActivity
. La vue d'activité:
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");
}
}
Une mise en page:
<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}"/>
Regardez l'exemple d'utilisation de la bibliothèque de liaisons de données pour le modèle MVVM: http://cases.azoft.com/mvvm-Android-data-binding
Je poste ceci parce que j'ai eu une autre situation dans laquelle ceci s'est produit. Si vous avez deux activités faisant référence au fichier Layout et que l'une définit l'événement onclick et que l'autre ne vous donne pas le même avertissement et étrangement dans l'activité où vous avez défini l'événement.
Pour vérifier cela, je vous recommande de trouver les utilisations du fichier de présentation par right clicking
sur le nom de la mise en page et appuyez sur find references
. N'oubliez pas de reconstruire les mots suivants de l'application.