【问题标题】:Android - User paints lines with their fingerAndroid - 用户用手指画线
【发布时间】:2012-05-17 15:55:30
【问题描述】:

我想在 Android 上构建一个工具,用户可以在其中在图片上绘制一些简单的对象(例如线、圆或箭头)。我先尝试了线条部分,确实可以成功画出来。逻辑是用户点击某一点,然后拖动手指,绘制线条。我使用这样的类(它基于DonGru's answer here):

public class DrawView extends View {
    Paint paint = new Paint();
    float Sx, Sy, Lx, Ly;

    public DrawView(Context context, float x1, float y1, float x2, float y2) {
        super(context);

        paint.setColor(Color.RED);
        Sx=x1;
        Sy=y1;
        Lx=x2;
        Ly=y2;   
    }

    @Override
    public void onDraw(Canvas canvas) {
            canvas.drawLine(Sx, Sy, Lx, Ly, paint);
    }
}

在活动代码中,我像这样使用 onTouch 侦听器:

@Override
public boolean onTouch(View view, MotionEvent event) { 
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            Sx1 = event.getX();
            Sy1 = event.getY();
            return true;

        case MotionEvent.ACTION_MOVE:
            Cx1 = event.getX();
            Cy1 = event.getY();
            drawLine();
            return true;

        case MotionEvent.ACTION_UP:
            Lx1 = event.getX();
            Ly1 = event.getY();
            return true;
        }
    return false;
}

public void drawLine(){

    setContentView(R.layout.show);
    ImageView myImage = (ImageView) findViewById(R.id.lastphoto);
    myImage.setImageBitmap(rotatedPic);

    dv=new DrawView(this, Sx1, Sy1, Cx1, Cy1);

    addContentView(dv, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT,
            ViewGroup.LayoutParams.FILL_PARENT));

    RelativeLayout mRelativeLayout = (RelativeLayout) findViewById(R.id.linear);
    mRelativeLayout.setOnTouchListener((OnTouchListener) this);
    mRelativeLayout.addView(new Drawer(this));   
}

每次移动时,我都会重新创建整个视图,因此从起点到终点只有一条线可见。我首先担心的是我不知道这个实现是否正确。另外,我希望这些行在创建后作为对象处理。用户应该能够移动它们、旋转它们、删除等。我认为我可以通过将每条线的边缘坐标保存在类似于缓冲区的东西中来做到这一点,如果用户非常靠近一个边缘点击我可以处理那个手势。但是所有这些听起来都太复杂了,我不知道这是否不稳定。

我应该使用一些不同的方法来实现我完全缺少的类似的东西吗?

【问题讨论】:

  • 你的实现很奇怪。为了实现这样一个程序,你需要一个View,重写它的onDraw方法,处理用户的拖动动作,并相应地调用View.invalidate()
  • 您的意思是创建一个扩展视图的对象?像我作为绘图类的 DrawView 吗?但是在这个对象的一个​​实例上调用 invalidate 并不会删除之前的行。您是否有某个示例的链接,以便我理解您的意思?

标签: android android-canvas draw touch-event ontouchlistener


【解决方案1】:

在我看来,存储绘制的线条并让用户能够操纵它们只是适度复杂。

创建一个 Line 类。包括开始和结束坐标、颜色等作为类的字段和删除、移动等方法。还添加一个采用 MotionEvent 参数的方法。在此方法中,您使用 MotionEvent 确定是否已触摸此线并根据需要调整其位置。

将绘制的每条线(作为 Line 类的实例创建)的引用存储在扩展 View 类中的某种集合或列表中,ArrayList 应该这样做。然后,在 onTouch 事件中,调用每一行的触摸检测方法,并将 MotionEvent 传递给方法。

最后,通过遍历对 Line 实例的引用集合来覆盖 View 的 onDraw 回调以绘制每条线。

您还可以添加更多手势,例如长按删除等。这是这种方法的一个(完全未经测试,凭记忆编写)框架。

class Line

    public float x1, x2, y1, y2;

    public void detectTouch(MotionEvent motionEvent){

         // code to detect a touch and adjust the x and ys accordingly

    }

class DrawView extends View{

    private ArrayList<Line> lines = new ArrayList<Lines>();

    ....
    ....

@Override
public void onDraw(Canvas canvas) {

    super.onDraw();

    for (Line line : lines){
         canvas.drawLine(line.x1,line.y1,line.x2,line.y2);
    }
}

@Override
public boolean onTouch(View view, MotionEvent event) {

    ....
    ....

    for (Line line : lines){
        line.detectTouch(MotionEvent);
    }


}

玩得开心!

【讨论】:

  • 这看起来很有希望,谢谢!我会尝试并告诉你
  • 根据您的建议,我设法让它工作得非常好,直到现在!非常感谢!
  • 嘿乔治。很高兴听到它有帮助。祝你好运,,,
  • 嘿,你能提供完整的演示代码吗?要将动画从左向右移动,请在左侧添加新行。
  • 我想这样发展 :: Follow This Link
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-17
  • 1970-01-01
相关资源
最近更新 更多