ITKeyword,专注技术干货聚合推荐

注册 | 登录

解决android - How to draw line during runtime in a custom view?

itPublisher 分享于

2021腾讯云限时秒杀,爆款1核2G云服务器298元/3年!(领取2860元代金券),
地址https://cloud.tencent.com/act/cps/redirect?redirect=1062

2021阿里云最低价产品入口+领取代金券(老用户3折起),
入口地址https://www.aliyun.com/minisite/goods

推荐:Android View框架的draw机制

概述         Android中View框架的工作机制中,主要有三个过程:                 1、View树的测量(measure) Android View框架的measure机制                

I am trying to draw a line using on touch method.

I want that when user touches a particular point and then drags the finger, the line should be drawn.

using canvas.drawLine(_,_,_,_,_ ); is not drawing lines. as onDraw works only once.

my main question is "how to draw a line during runtime without using onDraw()? "

edit :

推荐:android view 相关方法 layout draw 布局 重绘

ViewGroup用onLayout实现view的自由移动 http://qq187155685.iteye.com/blog/1442778 Android屏幕元素层次结构 http://www.cnblogs.com/xingmeng/archive/2012/0

public class DrawView  extends View {
    int radius=30;
    int initialX =0;
    int initialY=0;
    int finalX=0;
    int finalY=0;
    private Point currentPoint;
    private int index;
    static ArrayList<Point> pointListDrawView = new ArrayList<Point>();

    public DrawView(Context context, ArrayList<Point> pointList) {
        super(context);
        // TODO Auto-generated constructor stub
        this.setBackgroundColor(Color.WHITE);
        //pointListDrawView = pointList;


        pointListDrawView.add(pt(600,200));

        pointListDrawView.add(pt(500,200));
        pointListDrawView.add(pt(400,200));
        pointListDrawView.add(pt(400,300));

        pointListDrawView.add(pt(400,400));
        pointListDrawView.add(pt(500,400));
        pointListDrawView.add(pt(400,400));

        pointListDrawView.add(pt(400,500));
        pointListDrawView.add(pt(400,600));
        pointListDrawView.add(pt(500,600));
        pointListDrawView.add(pt(600,600));

    }
    private Point pt(int i, int j) {
        // TODO Auto-generated method stub
        Point P = new Point(i, j);
        return P ;
    }
    Paint paint= new Paint();
    Canvas universalCanvas;
    @Override 
    protected void onDraw(final Canvas canvas) {

            paint.setColor(Color.GREEN);
            paint.setStrokeWidth(10);
            for(int i=0; i<pointListDrawView.size();i++){
            canvas.drawCircle(pointListDrawView.get(i).x, pointListDrawView.get(i).y, 15, paint);
            }
            universalCanvas = canvas;
    //      drawLines(canvas);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub

        int i =0;

        switch (event.getAction()){

        case MotionEvent.ACTION_DOWN:
                if(((event.getX()>pointListDrawView.get(i).x-radius) && (event.getX()<pointListDrawView.get(i).x+radius) && (event.getY()>pointListDrawView.get(i).y-radius) && (event.getY()<pointListDrawView.get(i).y+radius)))

                {
                    Log.d("touch", "touched correct point");
                    initialX=pointListDrawView.get(i).x;
                    initialY=pointListDrawView.get(i).y;

                } 

                else{
                    Log.d("touch", "touch discarded");
                return false;
                }
        break;

        case MotionEvent.ACTION_MOVE:
                universalCanvas.drawLine(initialX, initialY, event.getX(), event.getY(), paint);

                break;

        case MotionEvent.ACTION_UP:
                if(((event.getX()>pointListDrawView.get(i+1).x-radius) && (event.getX()<pointListDrawView.get(i+1).x+radius) && (event.getY()>pointListDrawView.get(i+1).y-radius) && (event.getY()<pointListDrawView.get(i+1).y+radius)))
                {
                    finalX=pointListDrawView.get(i+1).x;
                    finalY=pointListDrawView.get(i+1).y;
                    universalCanvas.drawLine(initialX,initialY, finalX,finalY, paint);
                    Log.d("touch", "line drawn");
                    return true;
                }
                else
                {
                    Log.d("touch", "correct point touched and discarded");
                    return false;
                }


        default:
            break;

        }
        invalidate();
        return true;

    }

}
android line draw
|
  this question
edited May 28 '12 at 7:57 MBMJ 2,116 6 20 48 asked May 28 '12 at 7:18 jeet.chanchawat 2,815 3 17 43 1   Just call invalidate() after updating the new points of line. If you call invalidate() then onDraw() will call again. –  Shaiful May 28 '12 at 7:40      please chk source code –  jeet.chanchawat May 28 '12 at 7:45      Post my answer. Check if it helps. –  Shaiful May 28 '12 at 8:02

 | 

2 Answers
2

解决方法

I just write this code for you. Check if it helps.

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.PointF;
import android.view.MotionEvent;
import android.view.View;

public class TestView extends View
{

    private Paint paint;
    private PointF startPoint, endPoint;
    private boolean isDrawing;

    public TestView(Context context)
    {
        super(context);
        init();
    }

    private void init()
    {
        paint = new Paint();
        paint.setColor(Color.RED);
        paint.setStyle(Style.STROKE);
        paint.setStrokeWidth(2);
        paint.setAntiAlias(true);
    }

    @Override
    protected void onDraw(Canvas canvas)
    {
        if(isDrawing)
        {
            canvas.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, paint);
        }
    }


    @Override
    public boolean onTouchEvent(MotionEvent event)
    {
        switch (event.getAction())
        {
            case MotionEvent.ACTION_DOWN:
                startPoint = new PointF(event.getX(), event.getY());
                endPoint = new PointF();
                isDrawing = true;
                break;
            case MotionEvent.ACTION_MOVE:
                if(isDrawing)
                {
                    endPoint.x = event.getX();
                    endPoint.y = event.getY();
                    invalidate();
                }
                break;
            case MotionEvent.ACTION_UP:
                if(isDrawing)
                {
                    endPoint.x = event.getX();
                    endPoint.y = event.getY();
                    isDrawing = false;
                    invalidate();
                }
                break;
            default:
                break;
        }
        return true;
    }
}

|
  this answer
answered May 28 '12 at 8:01 Shaiful 3,914 2 30 39      thank you, thanks a lot :) –  jeet.chanchawat May 28 '12 at 8:38

 | 

There are two solution:

  1. bad and easy (this is answer for you question: "how to draw a line during runtime without using onDraw()?") - subclass ImageView and do drawing on on bitmap then update ImageView
  2. good and with more work - store history of touches in onTouchEvent don't draw there, I mean store every ACTION_DOWN ACTION_MOVE (remember about multitouch so store id of the touch in ACTION_DOWN and verify it in ACTION_MOVE/ACTION_UP)! Call invalidate only for DOWN UP and MOVE. In method onDraw draw this history. In edit you have made a good step but you did drawing there.

|
  this answer
edited May 28 '12 at 8:08 answered May 28 '12 at 7:54 Marek R 7,979 1 18 52

 | 

推荐:Android视图的绘制流程(下)——View的Layout与Draw过程

综述   在上篇文章中Android视图的绘制流程(上)——View的测量对View的Measure过程进行了详细的说明。对于在View的绘制的整个过程中,在对View的大小进行测量


相关阅读排行


相关内容推荐

最新文章

×

×

请激活账号

为了能正常使用评论、编辑功能及以后陆续为用户提供的其他产品,请激活账号。

您的注册邮箱: 修改

重新发送激活邮件 进入我的邮箱

如果您没有收到激活邮件,请注意检查垃圾箱。