2016-01-09 55 views
3

我在不同的API测试我的应用程序,它似乎在API 17工作到23,但我在API 16发现,我无法载入我的customview。我只是想显示在一个圈子中的照片,我已经获得的代码从这个线程customview:How to create a circular ImageView in Android?CircularImageView和API 16:NullPointerException异常错误

我的代码粘贴在这里:

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; 
    } 
} 

在此行中出现的错误:

if (bmp.getWidth() != radius || bmp.getHeight() != radius) 

这是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) 在android.view.View.draw(View.java:13458) 在android.view.View.getDisplayList(View.java:12409) 在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) 在android.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) 在android.support.v7.wi droid.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.draw.View(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) 在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) 在android.view.View.draw(查看。的java:13182) 在android.view.ViewGroup.drawChild(ViewGroup.java:2929) 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) 在android.view.View.draw(View.java: (View.java:12409) 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.Vie在android.view.View.getDisplayList(View.java:12453) 上的android.view.View.getDisplayList(View.java:12407) 上的wGroup.dispatchDraw(ViewGroup.java:2799) 。绘制(View.java:13182) 在android.view.ViewGroup.drawChild(ViewGroup.java:2929) 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) 在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) 在android.view.ViewGroup.dispatchDra w(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) 在android.view.ViewGroup.drawChild(ViewGroup.java:2929) 在android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799) 在android.view.View.draw(查看。 (View.java:12409) at android.view.View.getDisplayList(View.java:java:13461) at android.widget.FrameLayout.draw(FrameLayout.java:467) at android.view.ViewDisplayList(View.java:12409) at android.view.View.getDisplayList(View.java: 12453) 在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的API 16圆形ImageView的?

+0

Plz使用CircleImageView https://github.com/hdodenhof/CircleImageView。 –

回答

1

使用此方法来绘制你转换为位图:

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; 
} 

然后,而不是使用的原代码,下面一行:

Bitmap b = ((BitmapDrawable) drawable).getBitmap(); 

使用这个代替:

Bitmap b = drawableToBitmap(drawable); 

然后,它会运行没有错误。

1

好,因为你的位图是零和绘制不仅可以将误差范围内copy(Bitmap, boolean)的是地方。

如果你看一下文档

如果不支持转换,或分配器失败,那么这将返回NULL。

尝试使用较小的图像,因为这可能是低内存的标志。您还应该添加一些防范措施,以防止返回的可能的空值只是在这种情况下绘制正常的位图。

+0

我加载的位图确实很小。没有大于100kb,大部分都在50kb以下。 – Simon

+0

从我看到的错误来自该行。它可能仍然是位图转换失败,但我不知道为什么:/ –

0

您可以将MLRoundedImageView用于圆形图像视图。 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; 
} 
} 

然后在布局中使用这样的

<com.yourproject.MLRoundedImagView 
    Layout properties here /> 

然后在你的活动

MLRoundedImagView imageview = (MLRoundedImagView) findViewbyId(R.id.imageview); 
+0

对不起 - 不知道这是如何回答我的问题,因为你班里的代码和我班的代码是一样的。我可以创建圈子 - 我只是不能在API 16中创建圈子。 – Simon

相关问题