2016-03-05 17 views
40

Sto cercando di impostare ID di risorsa drawable ad Android: src dei dati ImageView utilizzando vincolanteSet ID di risorsa drawable in Android: src per ImageView utilizzando i dati vincolante Android

Ecco il mio oggetto:

public class Recipe implements Parcelable { 
    public final int imageResource; // resource ID (e.g. R.drawable.some_image) 
    public final String title; 
    // ... 

    public Recipe(int imageResource, String title /* ... */) { 
     this.imageResource = imageResource; 
     this.title = title; 
    } 

    // ... 
} 

Ecco il mio layout:

<?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"> 

    <data> 
     <variable 
      name="recipe" 
      type="com.example.android.fivewaystocookeggs.Recipe" /> 
    </data> 

    <!-- ... --> 

    <ImageView 
     android:id="@+id/recipe_image_view" 
     android:layout_width="match_parent" 
     android:layout_height="200dp" 
     android:scaleType="centerCrop" 
     android:src="@{recipe.imageResource}" /> 

    <!-- ... --> 

</layout> 

E, infine, l'attività di classe:

// ... 

public class RecipeActivity extends AppCompatActivity { 

    public static final String RECIPE_PARCELABLE = "recipe_parcelable"; 
    private Recipe mRecipe; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     mRecipe = getIntent().getParcelableExtra(RECIPE_PARCELABLE); 
     ActivityRecipeBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_recipe); 
     binding.setRecipe(mRecipe); 
    } 

    // ... 

} 

Non visualizza l'immagine. Che cosa sto facendo di sbagliato?

BTW, era perfettamente lavorando con metodo standard:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_recipe); 

    final ImageView recipeImageView = (ImageView) findViewById(R.id.recipe_image_view); 
    recipeImageView.setImageResource(mRecipe.imageResource); 

} 

risposta

45

risposta come di NOV 10 2016

commento di Splash seguito ha messo in evidenza che non è necessario l'utilizzo di un tipo di proprietà personalizzata (come imageResource), possiamo invece creare più metodi per android:src in questo modo:

public class DataBindingAdapters { 

    @BindingAdapter("android:src") 
    public static void setImageUri(ImageView view, String imageUri) { 
     if (imageUri == null) { 
      view.setImageURI(null); 
     } else { 
      view.setImageURI(Uri.parse(imageUri)); 
     } 
    } 

    @BindingAdapter("android:src") 
    public static void setImageUri(ImageView view, Uri imageUri) { 
     view.setImageURI(imageUri); 
    } 

    @BindingAdapter("android:src") 
    public static void setImageDrawable(ImageView view, Drawable drawable) { 
     view.setImageDrawable(drawable); 
    } 

    @BindingAdapter("android:src") 
    public static void setImageResource(ImageView imageView, int resource){ 
     imageView.setImageResource(resource); 
    } 
} 

Vecchio risposta

Si può sempre tenta di utilizzare un adattatore:

public class DataBindingAdapters { 

    @BindingAdapter("imageResource") 
    public static void setImageResource(ImageView imageView, int resource){ 
     imageView.setImageResource(resource); 
    } 
} 

è possibile utilizzare l'adattatore in XML in questo modo

<ImageView 
    android:id="@+id/recipe_image_view" 
    android:layout_width="match_parent" 
    android:layout_height="200dp" 
    android:scaleType="centerCrop" 
    imageResource="@{recipe.imageResource}" /> 

essere sicuri di si noti che il nome all'interno dell'XML corrisponde all'annotazione BindingAdapter (imageResource)

La classe DataBindingAdapters non ha bisogno di essere dichiarato da nessuna parte in particolare, la meccanica DataBinding troveranno non importa (credo)

+0

Funziona usando '@ BindingAdapter'. Ma il valore dovrebbe essere 'android: src', non' imageResource': '@BindingAdapter (" android: src ")'. Grazie! –

+3

@YuriySeredyuk Nooooo! ahahah per favore. Fare ciò sostituirà ogni singolo uso di "android: src" all'interno dell'XML attraverso la tua ** intera applicazione ** che sicuramente ** NON ** vuoi fare. Per ottenere imageResource per funzionare è necessario modificare l'xml per imageView come ho fatto sopra, il databinding risolverà cosa mettere lì –

+1

OK, ho capito idea. Ora usando '' e '@BindingAdapter (" imageResource ")'. Ho appena perso 'imageResource =" @ {recipe.imageResource} "' parte dal codice snipped :) –

14

definiscono:

@BindingAdapter({"android:src"}) 
public static void setImageViewResource(ImageView imageView, int resource) { 
    imageView.setImageResource(resource); 
} 

uso:

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_centerInParent="true" 
    android:scaleType="center" 
    android:src="@{viewModel.imageRes, [email protected]/guide_1}"/> 
+0

dove aggiungo il metodo di supporto – myatmins

+0

aggiungendolo in qualsiasi classe, forse puoi creare un ImageDataBindingAdapter.class. – qinmiao

0

Utilizzo di Fresco (libreria di immagini di Facebook)

public class YourCustomBindingAdapters { 

    //app:imageUrl="@{data.imgUri}" 
    @BindingAdapter("bind:imageUrl") 
    public static void loadImage(SimpleDraweeView imageView, String url) { 
     if (url == null) { 
      imageView.setImageURI(Uri.EMPTY); 
     } else { 
      if (url.length() == 0) 
       imageView.setImageURI(Uri.EMPTY); 
      else 
       imageView.setImageURI(Uri.parse(url)); 
     } 
    } 
} 
3
public Drawable getImageRes() { 
     return mContext.getResources().getDrawable(R.drawable.icon); 
    } 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:scaleType="center" 
    android:src="@{viewModel.imageRes}"/> 
1

Per Kotlin mettere questo al file di un livello superiore utils, nessun contesto statico/compagno aveva bisogno:

@BindingAdapter("android:src") 
fun setImageViewResource(view: ImageView, resId : Int) { 
    view.setImageResource(resId) 
} 
1

Non escludere gli attributi SDK standard quando si crea il proprio @BindingAdapter!

Questo non è un buon approccio per molte ragioni come: impedirà di ottenere i benefici delle nuove correzioni sull'aggiornamento dell'SDK Android su quell'attributo. Inoltre potrebbe confondere gli sviluppatori e sicuramente difficile per la riusabilità (perché è non-exptected essere overrided)

si può usare namespace diverso, come:

custom:src="@{recipe.imageResource}" 

o

mybind:src="@{recipe.imageResource}" 

Tuttavia, vorrei raccomandare soluzione diversa come:

android:src="@{ContextCompat.getDrawable(context, recipe.imageResource)}" 

vista di contesto è sempre disponibile all'interno dell'espressione di binding @{ ... }

Problemi correlati