此示例有两个视图。左边一个是我的自定义视图,右边一个是ImageView。 ImageView似乎在预览屏幕上正确绘制。但是,两个视图都在正在运行的设备上正确绘制。
但我希望它像ImageView一样显示正确的预览。我做错了什么?
预览
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>
CustomView
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";
}
}
}
属性
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="CustomView">
<attr name="src" format="reference" />
</declare-styleable>
</resources>
资源
Sample drawable请把它放在可绘制的文件夹中。
答案 0 :(得分:0)
我设法通过使用宽度和高度形式onSizeChanged来解决我的问题。
@Override
protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld){
super.onSizeChanged(xNew, yNew, xOld, yOld);
mViewWidth = xNew;
mViewHeight = yNew;
}
@Override
protected void onDraw(Canvas canvas) {
bitmapDrawable.setBounds(0, 0, mViewWidth, mViewHeight);
bitmapDrawable.draw(canvas);
}