画布上的画线不跟随我的手指触摸



我尝试从文件资源中绘制ImageView。这是我的代码:

private Bitmap myBitmap;
private Bitmap mutableBitmap;
private Canvas canvas;
private Paint paint;
private ImageView img;
@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate (savedInstanceState);
    setContentView (R.layout.layout_imagefullscreen);
    paint = new Paint();
    paint.setStrokeWidth(11);
    paint.setColor(Color.YELLOW);
    paint.setStrokeJoin(Paint.Join.ROUND);   
    paint.setStrokeCap(Paint.Cap.ROUND); 
    View decorView = getWindow().getDecorView();
    int uiOptions = View.SYSTEM_UI_FLAG_LOW_PROFILE;
    decorView.setSystemUiVisibility(uiOptions);
...
    if (imageFileFullPathName != null) {
        try {
            File imgFile = new File (imageFileFullPathName);
            if (imgFile.exists ()) {
                myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
                mutableBitmap = myBitmap.copy(Bitmap.Config.ARGB_8888, true);
                canvas = new Canvas(mutableBitmap);
                img.setImageBitmap(mutableBitmap);
                Matrix m = img.getImageMatrix();
                canvas.setMatrix(m);
            }
        } catch (Exception e) {
            e.printStackTrace ();
        }
    }

    img.setOnTouchListener (new OnTouchListener() {
        float startX, startY;
        float stopX, stopY;
        @Override
        public boolean onTouch (View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = event.getX();
                startY = event.getY();
                Log.i("---> DOWN X", String.valueOf(startX));
                Log.i("---> DOWN Y", String.valueOf(startY));
                break;
            case MotionEvent.ACTION_MOVE:
                stopX = event.getRawX();
                stopY = event.getRawY();
                Log.i("---> MOVE X", String.valueOf(stopX));
                Log.i("---> MOVE Y", String.valueOf(stopY));        
                canvas.drawLine(startX, startY, stopX, stopY, paint);
                img.invalidate();     
                startX = event.getRawX();
                startY = event.getRawY();
                img.setImageBitmap(mutableBitmap);
                break;
            case MotionEvent.ACTION_UP:
                stopX = event.getRawX();
                stopY = event.getRawY();
                Log.i("---> UP X", String.valueOf(stopX));
                Log.i("---> UP Y", String.valueOf(stopY));        
                canvas.drawLine(startX, startY, stopX, stopY, paint);
                img.invalidate();     
                break;
            default:
                break;
            }
            v.performClick();
            return true;
        }
    });
}
}'

但是当我在ImageView上移动手指时,线条不会跟随我的手指,而是只限制在屏幕的左上角。我也尝试将getRawX()更改为getX(),但此问题仍然存在。我相信问题与坐标变换有关,但无法弄清楚如何解决它。请帮忙,谢谢!

布局 xml 文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:background="@color/Black">
<ImageView
    android:id="@+id/imagefullscreenview"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:adjustViewBounds="true"
    android:src="@drawable/ic_launcher"/>
</LinearLayout>

从您的代码来看,您似乎正在尝试按照触摸的手指进行绘制。所以这是你画画的方式...

public class MainActivity extends Activity implements SurfaceHolder.Callback, OnClickListener, OnTouchListener {
    SurfaceView sv;
    SurfaceHolder sh;
    RenderingThread thread;
    Canvas canvas = null;
    int Width = 0, Height = 0;
    Button btnClear;
    Path path = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        try{
            super.onCreate(savedInstanceState);
            requestWindowFeature(Window.FEATURE_NO_TITLE);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
            getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            setContentView(R.layout.activity_main);
            sv = (SurfaceView)findViewById(R.id.sv);
            sv.setOnTouchListener(this);
            btnClear = (Button)findViewById(R.id.btnClear);
            path = new Path();
            sh = sv.getHolder();
            if(sh != null)
            {
                sh.addCallback(this);
            }
            else
            {
                Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
                finish();
            }
        }catch(Throwable ex)
        {
            ex.printStackTrace();
            Toast.makeText(getApplicationContext(), "Failed to start", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        try{
            Width = width;
            Height = height;
            thread = new RenderingThread(holder, width, height);
            canvas = new Canvas(thread.drawingBitmap);
            thread.start();
        }catch(Throwable ex) {
            ex.printStackTrace();
            Toast.makeText(getApplicationContext(), "Failed to initialize", Toast.LENGTH_SHORT).show();
            finish();
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        sv.setWillNotDraw(false);
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        thread.RequestStop();
    }
    public boolean onTouch(View v, MotionEvent event) {
        switch(event.getAction())
        {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(event.getRawX(), event.getRawY());
            break;
        case MotionEvent.ACTION_MOVE:
            Paint paint = new Paint();
            paint.setColor(Color.RED);
            paint.setAntiAlias(true);
            paint.setColor(Color.BLUE);
            paint.setStyle(Paint.Style.STROKE);
            paint.setStrokeJoin(Paint.Join.ROUND);
            paint.setStrokeWidth(5);
            CornerPathEffect pathEffect = new CornerPathEffect(45);
            paint.setPathEffect(pathEffect);
            path.lineTo(event.getRawX(), event.getRawY());
            canvas.drawPath(path, paint);
            //
            Log.i("minor",""+event.getTouchMinor());
            Log.i("major",""+event.getTouchMajor());
            break;
        case MotionEvent.ACTION_UP:
            path.reset();
            break;
        }
        return true;
    }

    @Override
    public void onClick(View v) {
        switch(v.getId())
        {
        case R.id.btnClear:
            canvas.drawColor(Color.WHITE);
            break;
        }
    }
}

在这里,btnClear 是 XML 中的一个按钮,您可以从中清除画布。这是 XML

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >
    <SurfaceView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <Button
        android:id="@+id/btnClear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Clear"
        android:textSize="18sp"
        android:textColor="#ffffff"
        android:background="#555555"
        android:layout_alignParentRight="true"
        android:layout_alignParentBottom="true"
        android:onClick="onClick" />
</RelativeLayout>

这是渲染线程...

public class RenderingThread extends Thread {
    private boolean keepRunning = true;
    private SurfaceHolder holder = null;
    public Bitmap drawingBitmap = null;
    private int width = 0, height = 0;
    public RenderingThread(SurfaceHolder holder, int width, int height)
    {
        this.holder = holder;
        this.width = width;
        this.height = height;
        drawingBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
    }
    public void RequestStop()
    {
        keepRunning = false;
        interrupt();
    }
    @Override
    public void run() {
        while(keepRunning)
        {
            try{
                Thread.sleep(30);
                //
                if(holder != null && drawingBitmap != null)
                {
                    Canvas canvas = holder.lockCanvas();
                    if(canvas != null)
                    {
                        canvas.drawColor(Color.WHITE);
                        Rect src = new Rect(0, 0, drawingBitmap.getWidth(), drawingBitmap.getHeight());
                        Rect dst = new Rect(0, 0, width, height);
                        canvas.drawBitmap(drawingBitmap, src, dst, new Paint());
                        //
                        holder.unlockCanvasAndPost(canvas);
                    }
                }
            }catch(Throwable ex) {
                ex.printStackTrace();
            }
        }
    }
}

祝你好运。:)

最新更新