[英]Draw a circle onto a view (android)
我开始尝试编写一个Android应用程序。 我想想象pi的Monte-Carlo-Approximation。 因此,我首先想要在视图上绘制一个圆圈,但我不会让它工作! 我试图创建我自己的“CircleView”类,它扩展了“View”并覆盖了onDraw(..)方法,就像它在这里解释的那样: 如何在Android中用画布绘制圆圈?
这是我的CircleView类
public class CircleView extends View {
public CircleView(Context context) {
super(context);
}
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
Paint paint = new Paint();
paint.setColor(150);
canvas.drawCircle(50,50,20,paint);
}
}
我已使用以下XML代码将CircleView插入到LinearLayout中
<com.tak3r07.montecarlopi.CircleView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/circleView"
android:layout_weight="1"/>
(顺便说一句Android Studio在右侧的XML视图中告诉我:“渲染问题自定义视图CircleView没有使用2或3参数的View构造函数; XML属性不起作用”)
该应用程序崩溃时出现以下日志: http : //pastebin.com/Gv1GaHtX
谁能说出我做错了什么?
我认为这个设置会创建一个带有显示圆圈的视图的活动。
问候
编辑:通过在CircleView中添加2和3参数构造函数来修复崩溃(请参阅https://stackoverflow.com/a/13797457/3248708 )
但是现在我仍然没有在活动中看到任何Circle
几点意见:
在确定圆的中心点和半径时,您需要考虑分配给视图的宽度和高度。
您应该考虑分配给视图的填充,这样就不会绘制该保留部分。
你应该避免在onDraw方法中分配对象,因为这会被调用很多。
为了允许在XML布局中指定视图,您需要提供带有Context和AttributeSet的构造函数。 AttributeSet是将XML属性传递给视图的机制。
尝试一下:
package com.tak3r07.montecarlopi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
public class CircleView extends View
{
private static final int DEFAULT_CIRCLE_COLOR = Color.RED;
private int circleColor = DEFAULT_CIRCLE_COLOR;
private Paint paint;
public CircleView(Context context)
{
super(context);
init(context, null);
}
public CircleView(Context context, AttributeSet attrs)
{
super(context, attrs);
init(context, attrs);
}
private void init(Context context, AttributeSet attrs)
{
paint = new Paint();
paint.setAntiAlias(true);
}
public void setCircleColor(int circleColor)
{
this.circleColor = circleColor;
invalidate();
}
public int getCircleColor()
{
return circleColor;
}
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
int w = getWidth();
int h = getHeight();
int pl = getPaddingLeft();
int pr = getPaddingRight();
int pt = getPaddingTop();
int pb = getPaddingBottom();
int usableWidth = w - (pl + pr);
int usableHeight = h - (pt + pb);
int radius = Math.min(usableWidth, usableHeight) / 2;
int cx = pl + (usableWidth / 2);
int cy = pt + (usableHeight / 2);
paint.setColor(circleColor);
canvas.drawCircle(cx, cy, radius, paint);
}
}
您可以创建一个圆形布局,在此视图中,每个子项都应该向上舍入:
public class CircleView extends FrameLayout {
private Bitmap maskBitmap;
private Paint paint, maskPaint;
public CircleView(Context context) {
super(context);
init();
}
public CircleView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public CircleView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init();
}
private void init() {
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
maskPaint = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
maskPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
setWillNotDraw(false);
}
@Override
public void draw(Canvas canvas) {
Bitmap offscreenBitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas offscreenCanvas = new Canvas(offscreenBitmap);
super.draw(offscreenCanvas);
if (maskBitmap == null) {
maskBitmap = createMask(getWidth(), getHeight());
}
offscreenCanvas.drawBitmap(maskBitmap, 0f, 0f, maskPaint);
canvas.drawBitmap(offscreenBitmap, 0f, 0f, paint);
}
private Bitmap createMask(int width, int height) {
Bitmap mask = Bitmap.createBitmap(width, height, Bitmap.Config.ALPHA_8);
Canvas canvas = new Canvas(mask);
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.WHITE);
canvas.drawRect(0, 0, width, height, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
canvas.drawRoundRect(new RectF(0, 0, width, height), width/2f, height/2f, paint);
return mask;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.