在现有视图上绘制形状

时间:2014-08-08 12:06:26

标签: android view drawing android-canvas

我有一个视图,我想在点击后在其上绘制一个形状(例如圆圈)。 enter image description here

我试图这样做,但有两个问题 -

    永远不会调用
  1. onDraw。
  2. 不确定setLayoutParams(v.getLayoutParams)会给我我想要的结果。

        @Override
        public void onClick(View v) {
            CircleView circle = new CircleView(GameXoActivity.this, v.getWidth(), v.getHeight());
            circle.setLayoutParams(v.getLayoutParams());
            circle.startDrawing();
        }
    
  3. CircleView:

        public CircleView(Context context, int width, int height) {
            super(context);
            this.width = width;
            this.height = height;
        }
    
        protected void startDrawing() {
            this.postInvalidate(); 
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            Log.d("TAG", "onDraw");
            // draw circle
            }
        }
    
    }
    

    更新

    形状不是图像,我想用动画绘制它(我没有写完整个代码)。 此外,形状并不总是圆形,因此使用可绘制状态不是一种选择。 因为不仅有一个视图,而是9个,我不认为在它们之上制作9个视图是正确的。

3 个答案:

答案 0 :(得分:1)

由于我确定您需要对此进行相当多的定制,因此我保留了相当通用的内容。下面的示例将动画一个正方形绘制的蓝色圆圈,从东方(0度)开始,在单击视图时在视图内容的顶部。

public class CircleView extends View
{
    private static final int MARGIN = 50;

    Handler handler = new Handler();
    Paint paint = new Paint();
    RectF rect = new RectF();

    boolean drawing = false;
    float sweep = 0;

    public CircleView(Context context)
    {
        this(context, null);
    }

    public CircleView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(15);
        paint.setColor(Color.BLUE);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        canvas.drawArc(rect, 0, sweep, false, paint);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh)
    {
        super.onSizeChanged(w, h, oldw, oldh);
        rect.set(MARGIN, MARGIN, w - MARGIN, h - MARGIN);
    }

    public void startAnimation()
    {
        drawing = true;
        handler.post(runnable);
    }

    Runnable runnable = new Runnable()
    {
        @Override
        public void run()
        {
            sweep += 10;
            if (!(sweep > 360))
            {
                invalidate();
                handler.postDelayed(this, 20);
            }
            else
            {
                drawing = false;
                sweep = 0;
            }
        }   
    };
}

在这个Activity示例中,我使用了大多数开发人员已经在他们的项目中拥有的图像,但显然可以将其更改为自定义图像。此外,为了简单和简洁起见,CircleView被设置为Activity的整个内容,但它也可以很容易地以xml布局列出。

public class MainActivity extends Activity
{
    CircleView circle;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        circle = new CircleView(this);
        circle.setBackgroundResource(R.drawable.ic_launcher);
        circle.setOnClickListener(new OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    circle.startAnimation();
                }
            }
        );      

        setContentView(circle);
    }
}

答案 1 :(得分:0)

如果你想弄乱对象的绘图,你应该覆盖public void draw(Canvas canvas)而不是protected void onDraw(Canvas canvas) 编辑:请阅读评论,我的回答的第一个陈述可能是错误的

但我会使用FrameLayout或RelativeLayout并将图像放在另一个上面。 然后,您可以播放覆盖图像的可见性,以隐藏/显示它。

编辑: 如果您的圆圈不是图像并且需要绘制,请创建自己的圆形类扩展视图并将其用作FrameLayout或RelativeLayout中的组件,就像它是图像一样

答案 2 :(得分:0)

我建议,创建两个尺寸相同的imageView,设置要在图像视图上显示的图像,然后使第二个图像不可见。 例如:

circleimage.setVisibility(View.INVISIBLE);//now its hidden(do it OnCreate)

然后在单击1stimage时显示2ndimage(在第1张图像的onclick中执行)

circleimage.setVisibility(View.VISIBLE);