2016-03-05 3 views
40

Я пытаюсь установить Drawable идентификатор ресурса для Android: ГКЗ данных ImageView с помощью связыванияУстановите вытяжку идентификатора ресурса в андроиде: ЦСИ для ImageView с помощью связывания данных в Android

Вот мой объект:

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

    // ... 
} 

Вот мой макет:

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

И, наконец, класс активность:

// ... 

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

    // ... 

} 

Это изображение не отображается. Что я делаю не так?

BTV, он отлично работает со стандартным способом:

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

} 

ответ

45

Ответ от 10 ноября 2016

комментарий подавать материал под кричащими заголовками в ниже подчеркнул, что не нужно использовать тип пользовательского свойства (как imageResource), мы можем вместо этого создать несколько методов для android:src как так:

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

Старый Ответ

Вы всегда можете попробовать использовать адаптер:

public class DataBindingAdapters { 

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

Вы можете использовать адаптер в вашем XML, как так

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

Обязательно обратите внимание, что имя внутри xml соответствует аннотации BindingAdapter (imageResource)

Класс DataBindingAdapters не должен быть объявлен в любом месте, в частности, механики Databinding не найдут его, независимо от того (я считаю)

+0

Работает с использованием '@ BindingAdapter'. Но значение должно быть 'android: src', а не' imageResource': '@BindingAdapter (" android: src ")'. Спасибо! –

+3

@YuriySeredyuk Nooooo! ха-ха пожалуйста. Выполнение этого будет отменять каждое использование «android: src» внутри xml в вашем ** полном приложении **, которое вы определенно ** НЕ хотите делать **. Чтобы заставить imageResource работать, вам нужно изменить xml для ImageView, как я сделал выше, привязка данных будет работать, что положить там –

+1

ОК, я понял идею. Теперь используйте '' и '@BindingAdapter (" imageResource ")'. Я просто пропустил 'imageResource =" @ {recipe.imageResource} "' часть из вашего кода, сжатого :) –

14

определяет:

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

использование:

<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

Где я могу добавить этот метод? – myatmins

+0

поддержка добавить его в любой класс, возможно, вы можете создать ImageDataBindingAdapter.class. – qinmiao

0

Использование Fresco (библиотека изображений 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

Для Котлин поставить это на высшем уровне Utils файла, никакого контекста статический/спутник не нужен:

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

Никогда не обходите стандартный SDK атрибуты, когда вы создаете свой собственный @BindingAdapter!

Это не очень хороший подход по многим причинам, таким как: . Это предотвратит получение преимуществ новых исправлений при обновлении Android SDK по этому атрибуту. Кроме того, это может запутать разработчик и, конечно, сложно для многократного использования (потому что это не-exptected быть перекрытым)

вы можете использовать другое пространство имен, как:

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

или

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

Однако я рекомендуют другое решение в качестве:

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

вид контекста всегда имеется внутри обязательного выражения @{ ... }

 Смежные вопросы

  • Нет связанных вопросов^_^