Es gibt zwei Ansichten in diesem Beispiel. Links ist meine benutzerdefinierte Ansicht und die richtige ist ImageView. ImageView scheint auf dem Vorschaubildschirm korrekt zu zeichnen. Beide Ansichten werden jedoch auf dem laufenden Gerät korrekt gezeichnet.Android benutzerdefinierte Ansicht zeichnen BitmapDrawable im Vorschaubereich falsch rendern
Aber ich möchte es korrekte Vorschau wie ImageView zeigt. Was habe ich falsch gemacht ?
PREVIEW
RUNNING DEVICE
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.apg.mobile.repeatlayout.MainActivity">
<com.my.CustomView
android:id="@+id/aa"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/colorPrimary"
app:src="@drawable/samplebg" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="10dp"
android:layout_toEndOf="@+id/aa"
android:background="@color/colorPrimary"
android:src="@drawable/samplebg" />
</RelativeLayout>
Custom
public class CustomView extends View {
private BitmapDrawable bitmapDrawable;
public CustomView(Context context) {
super(context);
}
public CustomView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
readAttribute(context, attrs, 0);
}
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
readAttribute(context, attrs, defStyleAttr);
}
@TargetApi(23)
public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
readAttribute(context, attrs, defStyleAttr);
}
private void readAttribute(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomView);
Drawable drawable = a.getDrawable(R.styleable.CustomView_src);
if (drawable == null)
throw new NullPointerException("You have to set src first..");
bitmapDrawable = drawableToBitmapDrawable(drawable);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int wm, hm;
int viewHeightMode = MeasureSpec.getMode(heightMeasureSpec);
int viewWidthMode = MeasureSpec.getMode(widthMeasureSpec);
Log.d("VIEW WIDTH-MODE", getMode(viewWidthMode));
Log.d("VIEW HEIGHT-MODE", getMode(viewHeightMode));
// 1: find user desired dimension
int desiredWidth = measureDesiredSize(widthMeasureSpec, bitmapDrawable.getIntrinsicWidth());
int desiredHeight = measureDesiredSize(heightMeasureSpec, bitmapDrawable.getIntrinsicHeight());
wm = MeasureSpec.makeMeasureSpec(desiredWidth, viewWidthMode);
hm = MeasureSpec.makeMeasureSpec(desiredHeight, viewHeightMode);
setMeasuredDimension(wm, hm);
}
@Override
protected void onDraw(Canvas canvas) {
bitmapDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
bitmapDrawable.draw(canvas);
}
private int measureDesiredSize(int measureSpec, int imageSize) {
int mode = MeasureSpec.getMode(measureSpec);
int size = MeasureSpec.getSize(measureSpec);
if (mode == MeasureSpec.EXACTLY) {
return size;
} else if (mode == MeasureSpec.AT_MOST) {
return Math.min(size, imageSize);
} else {
return imageSize;
}
}
public BitmapDrawable drawableToBitmapDrawable(Drawable drawable) {
if (drawable instanceof BitmapDrawable) {
return (BitmapDrawable) drawable;
} else if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
// Single color bitmap will be created of 1x1 pixel
Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
return new BitmapDrawable(getResources(), bitmap);
} else {
Bitmap bitmap = Bitmap.createBitmap(
drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(),
Bitmap.Config.ARGB_8888);
return new BitmapDrawable(getResources(), bitmap);
}
}
private String getMode(int mode) {
if (MeasureSpec.AT_MOST == mode) {
return "AT_MOST";
} else if (MeasureSpec.EXACTLY == mode) {
return "EXACTLY";
} else {
return "UNSPECIFIED";
}
}
}
Attribut
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="src" format="reference" />
</declare-styleable>
</resources>
Ressourcen
Sample drawable Sie es bitte in ziehbar Ordner.