Comment utiliser la liaison de données dans Android pour placer une ressource image dans un ImageView
?
<ImageView
Android:id="@+id/is_synced"
Android:src="@{model.pending ? @mipmap/pending: @mipmap/synced}"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content" />
Je veux une image si en attente est vraie et une autre image si en attente est fausse. Mais cela montre une erreur. Comment puis-je obtenir cette fonctionnalité?
définir l'image comme ça,
<ImageView
Android:layout_width="28dp"
Android:layout_height="28dp"
Android:src="@{model.isActive ? @drawable/white_activated_icon :@drawable/activated_icon}"
tools:src="@mipmap/white_activated_icon" />
Le réponse :
définir:
@BindingAdapter({"Android:src"})
public static void setImageViewResource(ImageView imageView, int resource) {
imageView.setImageResource(resource);
}
utilisation:
<ImageView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_centerInParent="true"
Android:scaleType="center"
Android:src="@{viewModel.imageRes, default=@drawable/guide_1}"/>
J'ai essayé ceci et cela fonctionne pour moi (buildToolsVersion: 24.0.1):
<ImageView
Android:layout_width="50dp"
Android:layout_height="50dp"
Android:layout_margin="8dp"
Android:scaleType="centerInside"
app:imageResource="@{item.avatarResId}"/>
utilisez simplement app:imageResource
pour remplacer Android:src
, Android:src="@{item.avatarResId}"
ne fonctionne pas, sinon définissez une @BindAdapter("Android:src")
personnalisée pour elle.
mais utiliser app:imageResource
ne nécessite pas de définir un @BindAdapter
en plus, parce que ImageView a une méthode appelée setImageResource()
, lorsque vous utilisez app:imageResource
, il appelle setImageResource()
automatiquement.
Si vous souhaitez passer un argument à la méthode comme un @IdRes
vous pouvez utiliser
XML
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
xmlns:tools="http://schemas.Android.com/tools">
<data>
<import type="<package_name>.R" />
</data>
<ImageView
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
app:load_image="@{R.drawable.image}" />
</layout>
Code
@BindingAdapter("load_image")
public static void loadImage(ImageView view, @IdRes int imageId) {
//Logic
}
Vous pouvez le faire sans rien faire par programme si votre modèle de données contient l'ID de ressource de l'image.
Exemple:
<layout>
<data>
<import type="Android.support.v4.content.ContextCompat" />
<variable
name="roomInfoItem"
type="com.example......model.RoomInfoModel" /> </data>
<RelativeLayout>
<ImageView
Android:id="@+id/iv_room_info_item"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
/>
</RelativeLayout>
</layout>
Ajoutez simplement la ligne suivante à votre imageView (je n’ai pas pu formater le code lorsque je l’ajoutais là-bas):
Android:src="@{ContextCompat.getDrawable(context,roomInfoItem.resId)}"
où resId
contient R.drawable.your_image_name
En accord avec ce superbe article: Chargement des images avec Data Binding et Picasso
il y a deux façons de le faire:
@BindingAdapter
ObservableField
& cible Picasso personnaliséeDans Android Référence des développeurs Guide de liaison des données , vous ne trouverez que le premier.
Veuillez lire les deux articles.
Plus d'informations:
J'espère que ça vous aidera.
Plus de détails Voir ici Détails Chargement d'images avec liaison de données et Picasso
public class ProfileViewModel {
// The URL will usually come from a model (i.e Profile)
static final String IMAGE_URL = "http://cdn.meme.am/instances/60677654.jpg";
public ObservableField<Drawable> profileImage;
private BindableFieldTarget bindableFieldTarget;
public ProfileViewModel(Context context) {
profileImage = new ObservableField<>();
// Picasso keeps a weak reference to the target so it needs to be stored in a field
bindableFieldTarget = new BindableFieldTarget(profileImage, context.getResources());
Picasso.with(context)
.load(IMAGE_URL)
.placeholder(R.drawable.placeholder)
.into(bindableFieldTarget);
}
public class BindableFieldTarget implements Target {
private ObservableField<Drawable> observableField;
private Resources resources;
public BindableFieldTarget(ObservableField<Drawable> observableField, Resources resources) {
this.observableField = observableField;
this.resources = resources;
}
@Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
observableField.set(new BitmapDrawable(resources, bitmap));
}
@Override
public void onBitmapFailed(Drawable errorDrawable) {
observableField.set(errorDrawable);
}
@Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
observableField.set(placeHolderDrawable);
}
}
}
Le problème est avec tous les attributs qui ont sur des setters avec le même nom. par exemple. Android: x ne fonctionnera pas si la méthode setX () n'est pas présente dans cette vue, de même si nous avions la méthode setSrc () sur ImageView, votre code aurait fonctionné sans adaptateur de liaison personnalisé.