2016-06-03 5 views
1

Ich verwende Leinwand, um eine einfache Zeichnung App zu machen. Ich verwende onTouchEvent, um Berührungsereignisse zu behandeln. Ich bin mit einem Problem konfrontiert, das auf der vertikalen Achse gezeichnet wurde. Der Punkt unterscheidet sich von der berührten Position. Die vertikale Trennung zwischen der berührten Position und der gezeichneten Position nimmt zu, wenn ich mich nach oben bewege. Um mein Problem zu verdeutlichen, füge ich einen Screenshot meiner App an. screen shot android leinwand nicht zeichnung auf berührte position

Die blaue Linie zeigt die tatsächlich berührte Position und die rot gezeichnete Position.

Hier ist mein Code Mainactivity

public class MainActivity extends AppCompatActivity{ 
    Path mPath; 
    Canvas canvas; 
    Paint paint; 
    float pointX; 
    float pointY; 
    int height; 
    RelativeLayout layout; 
    int layoutHeight; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     layout=(RelativeLayout)findViewById(R.id.main_layout); 
     DisplayMetrics dp=getResources().getDisplayMetrics(); 

     WindowManager windowManager=getWindowManager(); 
     height=windowManager.getDefaultDisplay().getHeight(); 
     int width =windowManager.getDefaultDisplay().getWidth(); 

     Bitmap bg = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); 
     layout.setBackground(new BitmapDrawable(bg)); 
     canvas=new Canvas(bg); 
     paint=new Paint(Paint.ANTI_ALIAS_FLAG); 
     paint.setColor(Color.RED); 
     paint.setStyle(Paint.Style.STROKE); 
     paint.setStrokeWidth(4); 
     mPath=new Path(); 
     canvas.drawPath(mPath,paint); 
     canvas.drawBitmap(bg,0,0,paint); 
    } 

    public void clearCanvas(View v) { 
     mPath.reset(); 
     canvas.drawColor(0, PorterDuff.Mode.CLEAR); 
     layout.invalidate(); 
    } 
    //override the onTouchEvent 
    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     pointX = event.getX(); 
     pointY = event.getY(); 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       Log.v("TAG"," action down x:"+pointX+" y:"+pointY); 
       mPath.moveTo(pointX,pointY); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       Log.v("TAG"," actionmove x:"+pointX+" y:"+pointY); 
       mPath.lineTo(pointX,pointY); 
       canvas.drawPath(mPath,paint); 
       break; 
      case MotionEvent.ACTION_UP: 
       break; 
     } 
     layout.invalidate(); 
     return true; 
    } 
} 

xml Layout

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/main_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.vikash.mydrawingapp.MainActivity"> 

    <Button 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="clear" 
     android:onClick="clearCanvas" 
     android:layout_alignParentBottom="true" 
     android:layout_centerHorizontal="true" /> 
</RelativeLayout> 
+0

schreiben Sie hier Ihren Code –

+0

@DixitPanchal Ich habe Code hinzugefügt. Bitte helfe –

+0

Anstatt die 'View.getX()'/'View.getY()' zu verwenden, hast du 'View.getRawX()'/'View.getRawY()'? Auf diese Weise können Sie den tatsächlichen Pixel berühren und eine Linie mit dieser Koordinate platzieren. Soweit ich das beurteilen kann, besteht das Problem darin, dass die Position (x), auf die mit Ihrem Bildschirm geklickt wurde, eng mit der (x) der Ansicht zusammenhängt, aber die (y) angeklickt wird durch die andere "versetzt" Ansicht, die Titelleiste. – Bonatti

Antwort

2

Gebrauch: event.getRawX()

Gibt den ursprünglichen rohen X dieses Ereignis koordinieren. Bei Berührungsereignissen auf dem Bildschirm ist dies der ursprüngliche Ort des Ereignisses auf dem Bildschirm, bevor es für das enthaltene Fenster und die Ansichten angepasst wurde.

UPD: Ich habe gerade versucht, die App zu wiederholen und alle korrekt funktioniert

activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <com.example.Test 
     android:layout_width="match_parent" 
     android:layout_height="match_parent"/> 

</LinearLayout> 

Test.java

public class Test extends View { 

    private Path path = new Path(); 
    private Paint paint = new Paint(); 
    { 
     paint.setColor(Color.GREEN); 
     paint.setStrokeWidth(4); 
     paint.setStyle(Paint.Style.STROKE); 
    } 

    public Test(Context context) { 
     super(context); 
    } 

    public Test(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    public Test(Context context, AttributeSet attrs, int defStyleAttr) { 
     super(context, attrs, defStyleAttr); 
    } 

    @TargetApi(Build.VERSION_CODES.LOLLIPOP) 
    public Test(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     super.onDraw(canvas); 
     canvas.drawPath(path, paint); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
      case MotionEvent.ACTION_DOWN: 
       path.moveTo(event.getX(), event.getY()); 
       break; 
      case MotionEvent.ACTION_MOVE: 
       path.lineTo(event.getX(), event.getY()); 
       break; 
     } 
     invalidate(); 
     return true; 
    } 

} 
+0

müde, aber es hat nicht geholfen –

+0

ja das funktioniert perfekt. Ich habe das versucht. Ich hatte Probleme, als ich Leinwand in den Hintergrund des Hauptlayouts brachte. Wenn ich diese Leinwand wie in Ihrer Antwort verwende, funktioniert es perfekt. Danke für die Hilfe :) –

0

Ihr Problem ist, dass Ihre Canvas X-Achse die gleiche Position des Bildschirms X-Achse hat, aber Ihr Leinwand-Y -Achse ist Offset von Bildschirm Y-Achse (Die "MyDrawingApp" -Bar setzt den Offset mit seiner Höhe).

Was ist passiert, wenn Sie "getY()" gibt die Position der Berührung als Referenz den gesamten Bildschirm nicht Ihre Leinwand.

Eine Lösung besteht darin, die Position des Canvas auf dem Bildschirm und minus es auf den "GetY()" Wert zu erhalten. Dadurch erhalten Sie eine Berührung in Ihrer Leinwand.

Ich hoffe, Sie werden mich verstehen, ich bin kein Englisch.

Grüße

+0

Ich habe bereits versucht, Offset zu subtrahieren. Aber es hilft nicht. In diesem gerade Gegenteil von oben passiert, dh Unterschied in leinwand Y und axisY ist mehr im unteren und weniger oben –