데이터 바인딩을 사용하여 드로어 블 리소스 ID를 android : src of ImageView로 설정하려고합니다.
내 물건은 다음과 같습니다.
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);
}
// ...
}
이미지를 전혀 표시하지 않습니다. 내가 도대체 뭘 잘못하고있는 겁니까?
BTW, 표준 방식으로 완벽하게 작동했습니다.
@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);
}
답변
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);
}
}
이전 답변
항상 어댑터를 사용할 수 있습니다.
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 역학은 상관없이 찾을 수 있습니다.
답변
관습이 전혀 필요하지 않습니다 BindingAdapter
. 그냥 사용
app:imageResource="@{yourResId}"
잘 작동합니다.
확인 이 어떻게 작동하는지에 대해.
답변
밝히다:
@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, default=@drawable/guide_1}"/>
답변
당신이 직접 만들 때 표준 SDK 속성을 재정의하지 마십시오 @BindingAdapter
!
이는 다음과 같은 여러 가지 이유로 좋은 접근 방식이 아닙니다. 해당 속성에 대한 Android SDK 업데이트에 대한 새로운 수정 사항의 이점을 얻지 못하게됩니다. 또한 개발자를 혼란스럽게 할 수 있으며 재사용 가능성을 위해 확실히 까다로울 수 있습니다 (재정의 될 것으로 예상되지 않기 때문에)
다음과 같은 다른 네임 스페이스를 사용할 수 있습니다.
custom:src="@{recipe.imageResource}"
또는
mybind:src="@{recipe.imageResource}"
—— 업데이트 2 시작 2018 년 7 월
네임 스페이스는 사용하지 않는 것이 좋으므로 다음과 같이 접두사 또는 다른 이름을 사용하는 것이 좋습니다.
app:custom_src="@{recipe.imageResource}"
또는
app:customSrc="@{recipe.imageResource}"
—— 2018 년 7 월 2 일 업데이트 종료
그러나 다음과 같이 다른 솔루션을 권장합니다.
android:src="@{ContextCompat.getDrawable(context, recipe.imageResource)}"
컨텍스트보기는 항상 바인딩 표현식 내에서 사용할 수 있습니다. @{ ... }
답변
Maher Abuthraa의 답변을 바탕으로 XML에서 다음을 사용하게되었습니다.
android:src="@{context.getDrawable(recipe.imageResource)}"
context
변수를 볼 수 있는 수입하지 않고 표현을 결합한다. 또한 사용자 정의가 BindingAdapter
필요 하지 않습니다. 주의 사항 :이 메서드 getDrawable
는 API 21 이후에만 사용할 수 있습니다.
답변
들어 코 틀린는 최고 수준의 유틸 파일이 넣어 정적 / 동반자 컨텍스트는 필요하지 않습니다 :
@BindingAdapter("android:src")
fun setImageViewResource(view: ImageView, resId : Int) {
view.setImageResource(resId)
}
답변
할 수있는 일이 많을수록 DataBindingAdapter
- 데이터 바인딩을 통해 Image Url , File , Bitmap , Byte Array , Drawable , Drawable Id 무엇이든 설정할 수 있습니다 .
- 바인딩 어댑터에 여러 매개 변수를 전달 하여 오류 이미지 / 자리 표시 자 이미지도 설정할 수 있습니다 .
다음 유형 중 하나를 설정하십시오.
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`}"
오류 이미지 / 자리 표시 자 이미지 설정
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`}"
/>
모든 유형을 테스트했습니다.
단일 바인딩 어댑터로 가능합니다. 이 메소드 프로젝트를 복사하십시오.
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);
}
}
Glide를 사용하여 모든 개체를로드 한 이유
드로어 블 / 리소스 ID를로드하기 위해 Glide를 사용하는 이유를 묻는다면 대신 imageView.setImageBitmap();
또는 imageView.setImageResource();
. 그래서 그 이유는
- Glide는 미디어 디코딩, 메모리 및 디스크 캐싱을 래핑하는 효율적인 이미지 로딩 프레임 워크입니다. 따라서 큰 크기의 이미지와 캐시에 대해 걱정할 필요가 없습니다.
- 이미지를로드하는 동안 일관성을 유지합니다. 이제 모든 유형의 이미지 리소스가 Glide에 의해로드됩니다.
Piccaso, Fresso 또는 기타 이미지 로딩 라이브러리를 사용하는 경우 loadImageWithGlide
방법 을 변경할 수 있습니다 .