问题
I was testing my app on different APIs and it seems to work on API 17 till 23 but I found in API 16, I cannot load my customview. I just want to display a photo in a circle and I have obtained the code for the customview from this thread: How to create a circular ImageView in Android?
My code is pasted here:
public class CircularImageView extends ImageView {
public CircularImageView(Context context) {
super(context);
}
public CircularImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public CircularImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
int w = getWidth();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int) (bmp.getWidth() / factor), (int) (bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
The error occurs in this line:
if (bmp.getWidth() != radius || bmp.getHeight() != radius)
This is the logcat:
01-09 15:09:51.185 2119-2119/? E/AndroidRuntime: FATAL EXCEPTION: main java.lang.NullPointerException at com.example.simon.customshapes.CircularImageView.getCroppedBitmap(CircularImageView.java:59) at com.example.simon.customshapes.CircularImageView.onDraw(CircularImageView.java:51) at android.view.View.draw(View.java:13458) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.draw(View.java:13461) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.support.v7.widget.RecyclerView.drawChild(RecyclerView.java:3588) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.draw(View.java:13461) at android.support.v7.widget.RecyclerView.draw(RecyclerView.java:3097) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2806) at android.view.View.draw(View.java:13461) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.draw(View.java:13461) at android.support.v4.view.ViewPager.draw(ViewPager.java:2262) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.support.design.widget.CoordinatorLayout.drawChild(CoordinatorLayout.java:1077) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.draw(View.java:13461) at android.widget.FrameLayout.draw(FrameLayout.java:467) at android.view.View.getDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) at android.view.View.getDisplayList(View.java:12407) at android.view.View.getDisplayList(View.java:12453) at android.view.View.draw(View.java:13182) at android.view.ViewGroup.drawChild(ViewGroup.java:2929) at a
Is there a reason why I cannot draw a circular imageview in Android API 16?
回答1:
Well since your bitmap is null and the drawable isn't the only place the error can be at is within copy(Bitmap, boolean).
If you look at the documentation
If the conversion is not supported, or the allocator fails, then this returns NULL.
Try using a smaller image, since this can be a sign of Low Memory. You should also add some guard against the possible null value returned, e.g. just drawing the normal bitmap in that case.
回答2:
Use this method to convert your drawable to a bitmap:
public static Bitmap drawableToBitmap (Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
if(bitmapDrawable.getBitmap() != null) {
return bitmapDrawable.getBitmap();
}
}
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
} else {
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
Then instead of using in the original code, the following line:
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Use this instead:
Bitmap b = drawableToBitmap(drawable);
Then it will run without error.
回答3:
You can use MLRoundedImageView for circular imageview. MLRoundedImageView.java
public class MLRoundedImageView extends ImageView {
public MLRoundedImageView(Context context) {
super(context);
}
public MLRoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MLRoundedImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
if (drawable == null) {
return;
}
if (getWidth() == 0 || getHeight() == 0) {
return;
}
Bitmap b = ((BitmapDrawable) drawable).getBitmap();
Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true);
int w = getWidth(), h = getHeight();
Bitmap roundBitmap = getCroppedBitmap(bitmap, w);
canvas.drawBitmap(roundBitmap, 0, 0, null);
}
public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) {
Bitmap sbmp;
if (bmp.getWidth() != radius || bmp.getHeight() != radius) {
float smallest = Math.min(bmp.getWidth(), bmp.getHeight());
float factor = smallest / radius;
sbmp = Bitmap.createScaledBitmap(bmp, (int)(bmp.getWidth() / factor), (int)(bmp.getHeight() / factor), false);
} else {
sbmp = bmp;
}
Bitmap output = Bitmap.createBitmap(radius, radius,
Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xffa19774;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, radius, radius);
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
paint.setDither(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(Color.parseColor("#BAB399"));
canvas.drawCircle(radius / 2 + 0.7f,
radius / 2 + 0.7f, radius / 2 + 0.1f, paint);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(sbmp, rect, rect, paint);
return output;
}
}
Then use like this in layout
<com.yourproject.MLRoundedImagView
Layout properties here />
Then in your activity
MLRoundedImagView imageview = (MLRoundedImagView) findViewbyId(R.id.imageview);
来源:https://stackoverflow.com/questions/34695181/circularimageview-and-api-16-nullpointerexception-error