Yur*_*yuk 72 android android-layout android-databinding
我正在尝试使用数据绑定将drawable资源ID设置为ImageView的android:src
这是我的对象:
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;
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
这是我的布局:
<?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>
Run Code Online (Sandbox Code Playgroud)
最后,活动类:
// ...
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);
}
// ...
}
Run Code Online (Sandbox Code Playgroud)
它根本不显示图像.我究竟做错了什么?
顺便说一句,它完全符合标准方式:
@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);
}
Run Code Online (Sandbox Code Playgroud)
Joe*_*her 92
截至2016年11月10日的答复
下面的Splash评论强调,没有必要使用自定义属性类型(如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);
}
}
Run Code Online (Sandbox Code Playgroud)
老答案
您可以随时尝试使用适配器:
public class DataBindingAdapters {
@BindingAdapter("imageResource")
public static void setImageResource(ImageView imageView, int resource){
imageView.setImageResource(resource);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以像这样在xml中使用适配器
<ImageView
android:id="@+id/recipe_image_view"
android:layout_width="match_parent"
android:layout_height="200dp"
android:scaleType="centerCrop"
imageResource="@{recipe.imageResource}" />
Run Code Online (Sandbox Code Playgroud)
请务必注意xml中的名称与BindingAdapter注释(imageResource)匹配
DataBindingAdapters类不需要在任何地方声明,DataBinding机制无论如何都会找到它(我相信)
hqz*_*zwb 66
根本不需要定制BindingAdapter
。只需使用
app:imageResource="@{yourResId}"
Run Code Online (Sandbox Code Playgroud)
它会正常工作。
检查这个它是如何工作。
qin*_*iao 22
限定:
@BindingAdapter({"android:src"})
public static void setImageViewResource(ImageView imageView, int resource) {
imageView.setImageResource(resource);
}
Run Code Online (Sandbox Code Playgroud)
使用:
<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}"/>
Run Code Online (Sandbox Code Playgroud)
Mah*_*raa 12
在创建自己的属性时,切勿覆盖标准SDK属性@BindingAdapter
!
这不是一个很好的方法,原因如下:它会阻止在该属性上获得Android SDK更新的新修补程序的好处.此外,它可能会使开发人员感到困惑,并且对于可重用性肯定很棘手(因为它未被覆盖而无法被覆盖)
您可以使用不同的命名空间:
custom:src="@{recipe.imageResource}"
Run Code Online (Sandbox Code Playgroud)
要么
mybind:src="@{recipe.imageResource}"
Run Code Online (Sandbox Code Playgroud)
------开始更新2.Jul.2018
建议不要使用命名空间,因此最好依赖前缀或不同的名称:
app:custom_src="@{recipe.imageResource}"
Run Code Online (Sandbox Code Playgroud)
要么
app:customSrc="@{recipe.imageResource}"
Run Code Online (Sandbox Code Playgroud)
------结束更新2.Jul.2018
但是,我会建议不同的解决方案:
android:src="@{ContextCompat.getDrawable(context, recipe.imageResource)}"
Run Code Online (Sandbox Code Playgroud)
上下文视图始终在绑定表达式中可用 @{ ... }
Tom*_*dek 11
基于 Maher Abuthraa 的回答,这就是我最终在 XML 中使用的内容:
android:src="@{context.getDrawable(recipe.imageResource)}"
Run Code Online (Sandbox Code Playgroud)
该context
变量可在没有任何导入的绑定表达式中使用。此外,不需要定制BindingAdapter
。唯一警告:该方法getDrawable
仅自 API 21 起可用。
###你可以做的越多 DataBindingAdapter
###Set 任何这些类型:
android:src="@{model.profileImage}"
android:src="@{roundIcon ? @drawable/ic_launcher_round : @drawable/ic_launcher_round}"
android:src="@{bitmap}"
android:src="@{model.drawableId}"
android:src="@{@drawable/ic_launcher}"
android:src="@{file}"
android:src="@{`https://placekitten.com/200/200`}"
Run Code Online (Sandbox Code Playgroud)
对于 mipmap 资源
android:src="@{@mipmap/ic_launcher}" <!--This will show Token recognition error at '@mipmap -->
android:src="@{R.mipmap.ic_launcher}" <!-- correct with improt R class -->
Run Code Online (Sandbox Code Playgroud)
设置错误图像/占位符图像
placeholderImage="@{@drawable/img_placeholder}"
errorImage="@{@drawable/img_error}"
<ImageView
placeholderImage="@{@drawable/ic_launcher}"
errorImage="@{@drawable/ic_launcher}"
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@{`https://placekitten.com/2000/2000`}"
/>
Run Code Online (Sandbox Code Playgroud)
###测试了所有类型
因此,使用单个绑定适配器即可实现。只需复制此方法项目。
public class BindingAdapters {
@BindingAdapter(value = {"android:src", "placeholderImage", "errorImage"}, requireAll = false)
public static void loadImageWithGlide(ImageView imageView, Object obj, Object placeholder, Object errorImage) {
RequestOptions options = new RequestOptions();
if (placeholder instanceof Drawable) options.placeholder((Drawable) placeholder);
if (placeholder instanceof Integer) options.placeholder((Integer) placeholder);
if (errorImage instanceof Drawable) options.error((Drawable) errorImage);
if (errorImage instanceof Integer) options.error((Integer) errorImage);
RequestManager manager = Glide.with(App.getInstance()).
applyDefaultRequestOptions(options);
RequestBuilder<Drawable> builder;
if (obj instanceof String) {
builder = manager.load((String) obj);
} else if (obj instanceof Uri)
builder = manager.load((Uri) obj);
else if (obj instanceof Drawable)
builder = manager.load((Drawable) obj);
else if (obj instanceof Bitmap)
builder = manager.load((Bitmap) obj);
else if (obj instanceof Integer)
builder = manager.load((Integer) obj);
else if (obj instanceof File)
builder = manager.load((File) obj);
else if (obj instanceof Byte[])
builder = manager.load((Byte[]) obj);
else builder = manager.load(obj);
builder.into(imageView);
}
}
Run Code Online (Sandbox Code Playgroud)
###Reason 我使用 Glide 加载所有对象
如果你问我为什么使用 Glide 来加载 drawable/resource id,我可以使用 imageView.setImageBitmap();
or imageView.setImageResource();
。所以原因是
如果您使用 Piccaso、Fresso 或任何其他图像加载库,您可以在loadImageWithGlide
method 中进行更改。
小智 7
根本不需要自定义 BindingAdapter。只需使用:
数据:
<data>
<import type="com.example.R"/>
:
</data>
Run Code Online (Sandbox Code Playgroud)
图片视图:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:imageResource="@{gender == 0 ? R.drawable.male : R.drawable.female}" />
Run Code Online (Sandbox Code Playgroud)
对于Kotlin,将其放置在顶层utils文件中,不需要静态/随播上下文:
@BindingAdapter("android:src")
fun setImageViewResource(view: ImageView, resId : Int) {
view.setImageResource(resId)
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
45548 次 |
最近记录: |