2016-03-05 19 views
40

Próbuję ustawić rozciągliwej identyfikator zasobu dla Androida: src ImageView użyciu wiązania danychUstaw odkształcalne ID zasobu w Android: src dla ImageView wykorzystaniem powiązania danych w Androidzie

Tu jest mój obiekt:

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; 
    } 

    // ... 
} 

Oto mój plan:

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

I wreszcie, klasa działalność:

// ... 

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); 
    } 

    // ... 

} 

Nie wyświetla obrazu w ogóle. Co ja robię źle?

BTW, to było doskonale pracuje ze standardowym sposób:

@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); 

} 

Odpowiedz

45

odpowiedź, od 10 listopad 2016

komentarz Splash jest poniżej podkreślił, że nie jest niezbędne do korzystania z niestandardowego typu nieruchomości (jak imageResource), możemy zamiast tworzyć wiele sposobów android:src tak:

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); 
    } 
} 

Old Odpowiedź

Zawsze możesz spróbować użyć adaptera:

public class DataBindingAdapters { 

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

Następnie można użyć zasilacza w xml jak tak

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

Koniecznie zauważ, że nazwa w xml pasuje do adnotacji BindingAdapter (imageResource)

Klasa DataBindingAdapters nie muszą być deklarowane gdziekolwiek w szczególności mechanika Databinding znajdzie je bez względu na to (wierzę)

+0

Działa za pomocą '@ BindingAdapter'. Ale wartość powinna być 'android: src', a nie' imageResource': '@BindingAdapter (" android: src ")'. Dziękujemy! –

+3

@YuriySeredyuk Nooooo! haha, proszę. Spowoduje to zastąpienie każdego użycia "android: src" w xml w całej ** aplikacji **, którą zdecydowanie ** NIE chcesz robić. Aby uzyskać imageResource do pracy, musisz zmienić xml dla imageView, tak jak zrobiłem powyżej, databinding będzie pracować, co tam umieścić –

+1

OK, zrozumiałem pomysł. Teraz za pomocą '' i '@BindingAdapter (" imageResource ")'. Właśnie opuściłem fragment 'imageResource =" @ {recipe.imageResource} "" z wyciętego kodu :) –

14

określić:

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

zastosowanie:

<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

gdzie mogę dodać, że obsługa metody – myatmins

+0

dodać ją w dowolnej klasie, może można utworzyć ImageDataBindingAdapter.class. – qinmiao

0

Korzystanie z Fresco (biblioteka obrazów na Facebooku)

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

Dla Kotlin umieścić to na najwyższym poziomie utils pliku, brak kontekstu static/towarzysz potrzebne:

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

Nigdy nie zastępują standardowy SDK atrybutów podczas tworzenia własnego @BindingAdapter!

To nie jest dobre podejście z wielu powodów, takich jak: to zapobiegnie uzyskiwaniu korzyści z nowych poprawek w aktualizacji Android SDK dla tego atrybutu. Także to może mylić deweloperom i na pewno trudne do ponownego użycia (bo to un-exptected być overrided)

można używać różnych nazw, takich jak:

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

lub

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

jednak, że byłoby polecam inne rozwiązanie jako:

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

widok kontekstowy jest zawsze dostępny wewnątrz wyrażenia wiążącego @{ ... }