Wie zeichnet man eine Linie in Android

157

Kann jemand sagen, wie man in Android eine Linie zieht, vielleicht anhand eines Beispiels?

Mohan
quelle
4
Möchten Sie eine Linie in etwas zeichnen oder möchten Sie eine einfache Linie im Layout zeichnen?
Janusz

Antworten:

174

Dieser zeichnet 2 Linien, die oben links auf dem Bildschirm ein Kreuz bilden:

DrawView.java

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

public class DrawView extends View {
    Paint paint = new Paint();

    private void init() {
        paint.setColor(Color.BLACK);
    }

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

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

    public DrawView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    @Override
    public void onDraw(Canvas canvas) {
            canvas.drawLine(0, 0, 20, 20, paint);
            canvas.drawLine(20, 0, 0, 20, paint);
    }

}

Die Aktivität zum Starten:

StartDraw.java

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;

public class StartDraw extends Activity {
    DrawView drawView;

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

        drawView = new DrawView(this);
        drawView.setBackgroundColor(Color.WHITE);
        setContentView(drawView);

    }
}
DonGru
quelle
3
Wenn ich eine Zeile in einer anderen Aktivität wie R.layout.main hinzufügen möchte Wie kann ich hinzufügen?
Mohan
1
Das Layout Ihrer Aktivität muss ein View-Objekt enthalten - dann ist das kein Problem. Sie brauchen nur ein View-Objekt zum Zeichnen
DonGru
1
Ich möchte eine gerade Linie zeichnen. Wie kann ich den Wert startx start y stopx stopy angeben?
Mohan
Tatsächlich können Sie feststellen, dass in der Android-Entwicklerreferenz drawLine () die folgenden Argumente hat: drawLine (float startX, float startY, float stopX, float stopY, Paint paint)
DonGru
Mit dieser Methode zeichne ich eine Linie auf den Hintergrund. Ich möchte eine gezeichnete Linie löschen. Irgendwelche Vorschläge für mich. Kannst du mich vorschlagen?
tientuyen07
240

Wenn Sie eine einfache Linie in Ihrem Layout haben möchten, um zwei Ansichten zu trennen, können Sie eine generische Ansicht mit der Höhe und Breite der Linie und einer festgelegten Hintergrundfarbe verwenden.

Mit diesem Ansatz müssen Sie eine Ansicht nicht überschreiben oder einen Canvas selbst verwenden. Fügen Sie einfach und sauber die Zeile in XML hinzu.

<View
 android:layout_width="match_parent"
 android:layout_height="1dp"
 android:background="@android:color/black" />

Der von mir bereitgestellte Beispielcode generiert eine Linie, die den Bildschirm in der Breite ausfüllt und eine Höhe von 1 dp hat.

Wenn Sie Probleme mit dem Zeichnen der Linie auf kleinen Bildschirmen haben, sollten Sie die Höhe der Linie in px ändern. Das Problem ist, dass auf einem ldpi-Bildschirm die Linie 0,75 Pixel hoch ist. Manchmal kann dies zu einer Rundung führen, die die Linie verschwinden lässt. Wenn dies ein Problem für Ihr Layout ist, definieren Sie die Breite der Linie als Ressourcendatei und erstellen Sie eine separate Ressourcendatei für kleine Bildschirme, in der der Wert auf 1px anstelle von 1dp festgelegt wird.

Dieser Ansatz ist nur verwendbar, wenn Sie horizontale oder vertikale Linien möchten, die zum Teilen von Layoutelementen verwendet werden. Wenn Sie so etwas wie ein Kreuz erreichen möchten, das in ein Bild gezeichnet wird, funktioniert mein Ansatz nicht.

Janusz
quelle
Wie kann zur Laufzeit dieselbe Ansicht hinzugefügt werden, die dynamisch ist?
Lakshmanan
Lakshmanan, geben Sie ihm eine ID und setzen Sie seine Sichtbarkeit auf View.GONE oder VISIBLE zur Laufzeit
Hatim
Mit dieser Lösung kann auch ein Kreuz erstellt werden. Fügen Sie einfach das Attribut "Rotation" gemäß dem gewünschten Kreuz hinzu und verwenden Sie zwei Ansichten.
Arpit J.
62

Es gibt zwei Möglichkeiten, wie Sie eine Linie zeichnen können, indem Sie a Canvasoder a verwenden View.

Zeichnen einer Linie mit Leinwand

Aus der Dokumentation geht hervor , dass wir die folgende Methode verwenden müssen:

drawLine (float startX, float startY, float stopX, float stopY, Paint paint)

Hier ist ein Bild:

canvas.drawLine

Das PaintObjekt gibt nur an, Canvaswelche Farbe die Linie malen soll, wie breit sie sein soll und so weiter.

Hier ist ein Beispielcode:

private Paint paint = new Paint();
....

private void init() {
    paint.setColor(Color.BLACK);
    paint.setStrokeWidth(1f);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    startX = 20;
    startY = 100;
    stopX = 140;
    stopY = 30;

    canvas.drawLine(startX, startY, stopX, stopY, paint);
}

Zeichnen einer Linie mit Ansicht

Wenn Sie nur eine gerade horizontale oder vertikale Linie benötigen, ist es möglicherweise am einfachsten, eine Viewin Ihrer XML-Layoutdatei zu verwenden. Sie würden so etwas tun:

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@android:color/black" />

Hier ist ein Bild mit zwei Linien (eine horizontale und eine vertikale), um zu zeigen, wie es aussehen würde:

Zeichnen einer Linie mit einer Ansicht im XML-Layout

Und hier ist das komplette XML-Layout dafür:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:text="TextView1 in vertical linear layout" />

<View
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="@android:color/black" />

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:text="TextView2 in vertical linear layout" />

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:padding="10dp"
        android:text="TextView3 in horizontal linear layout" />

    <View
        android:layout_width="1dp"
        android:layout_height="match_parent"
        android:background="@android:color/black" />

    <TextView
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:padding="10dp"
        android:text="TextView4 in horizontal linear layout" />
</LinearLayout>

</LinearLayout>
Suragch
quelle
du bist ein genialer Bruder ... Ich habe versucht herauszufinden, wie sie die Koordinaten erhalten, während ich eine Ansicht mit Farbe zeichne ... aber das Bild, das du gepostet hast, hat mir geholfen, es ziemlich gut zu verstehen ... Ist da Gibt es ein Online-Tool, um ein solches Diagramm zu simulieren, damit ich es beim Codieren verwende?
ist es möglich, einen Rückruf zu erhalten, um zu erfahren, dass die Ansicht fertig gezeichnet wurde
Ich versuche zwei verschiedene Linien zu zeichnen. Einmal, wenn die erste Linie gezeichnet wurde, muss ich die zweite zeichnen ...
Warum zeichnen Sie nicht beide Linien gleichzeitig in onDraw?
Suragch
1
@ tientuyen07, Wenn Sie verwenden, onDraw()umgeben Sie Ihren Zeichnungscode mit if (someCondition) { draw... }, machen Sie someCondition = falseund rufen invalidate()Sie dann Ihre Ansicht auf. Die Ansicht wird ohne die Linie neu gezeichnet.
Suragch
22

Sie können mehrere gerade Linien in der Ansicht zeichnen, indem Sie ein Beispiel für die Fingerfarbe verwenden, das sich in Developer android befindet. Beispiel Link

Kommentar einfach: mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); Sie können gerade Linien zeichnen.

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class JoinPointsActivity extends Activity  {
    /** Called when the activity is first created. */
    Paint mPaint;
    float Mx1,My1;
    float x,y;
    @Override

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
       // setContentView(R.layout.main);
        MyView view1 =new MyView(this);
        view1.setBackgroundResource(R.drawable.image_0031_layer_1);
        setContentView(view1);


        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setColor(0xFFFF0000);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND);
       // mPaint.setStrokeCap(Paint.Cap.ROUND);
        mPaint.setStrokeWidth(10);

    }

    public class MyView extends View {

        private static final float MINP = 0.25f;
        private static final float MAXP = 0.75f;

      private Bitmap  mBitmap;
        private Canvas  mCanvas;
        private Path    mPath;
       private Paint   mBitmapPaint;

        public MyView(Context c) {
            super(c);

            mPath = new Path();
          mBitmapPaint = new Paint(Paint.DITHER_FLAG);
        }

        @Override
       protected void onSizeChanged(int w, int h, int oldw, int oldh) {
            super.onSizeChanged(w, h, oldw, oldh);
            mBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(0xFFAAAAAA);
           // canvas.drawLine(mX, mY, Mx1, My1, mPaint);
           // canvas.drawLine(mX, mY, x, y, mPaint);
            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
            canvas.drawPath(mPath, mPaint);

        }

        private float mX, mY;
        private static final float TOUCH_TOLERANCE = 4;

        private void touch_start(float x, float y) {
            mPath.reset();
            mPath.moveTo(x, y);
            mX = x;
            mY = y;
        }
        private void touch_move(float x, float y) {
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
               // mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;
            }
        }
        private void touch_up() {
            mPath.lineTo(mX, mY);
            // commit the path to our offscreen
            mCanvas.drawPath(mPath, mPaint);
            // kill this so we don't double draw
            mPath.reset();
        }

        @Override
        public boolean onTouchEvent(MotionEvent event) {
            float x = event.getX();
            float y = event.getY();

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    touch_start(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_MOVE:
                    touch_move(x, y);
                    invalidate();
                    break;
                case MotionEvent.ACTION_UP:
                    touch_up();
               //   Mx1=(int) event.getX();
                 //  My1= (int) event.getY();
                   invalidate();
                    break;
            }
            return true;
        }
    }

}
Hema
quelle
2
Kann mir jemand helfen, wie kann ich meine XML-Elemente in meiner Ansicht sehen, die sich im relativen Layout befinden? Sie können einfach das obige Beispiel durchgehen und mich vorschlagen.
Hema
9
package com.example.helloandroid;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;

public class HelloAndroid2Activity extends Activity {
    /** Called when the activity is first created. */
DrawView drawView;

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

    drawView = new DrawView(this);
    drawView.setBackgroundColor(Color.WHITE);
    setContentView(drawView);
}
class DrawView extends View {
        Paint paint = new Paint();

        public DrawView(Context context) {
            super(context);
            paint.setColor(Color.BLUE);
        }
        @Override
        public void onDraw(Canvas canvas) {
             super.onDraw(canvas);
                canvas.drawLine(10, 20, 30, 40, paint);
                canvas.drawLine(20, 10, 50, 20, paint);

        }
}
}
vinay
quelle
8

für horizontale Linie im Layout:

 <View
            android:id="@+id/View03"
            android:layout_width="fill_parent"
            android:layout_height="5dip"
            android:background="#0f0" />

für vertikale Linie im Layout:

<View
        android:id="@+id/View04"
        android:layout_width="5dip"
        android:layout_height="fill_parent"
        android:background="#0f0" />
Mohanraj
quelle
sie sind beide gleich. Was macht den Unterschied zwischen vertikal und horizontal aus?
Burhan ARAS
@ Burhan ARAS - sie sind nicht gleich wie Breite und Höhe werden in zwei Ansichten geändert. Es werden nur vertikale und horizontale Linien gezeichnet.
Mohanraj
7

Einfache Sache

 <TextView
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#c0c0c0"
    android:id="@+id/your_id"
    android:layout_marginTop="160dp" />
Shreedhar Bhat
quelle
5
canvas.drawLine(10, 10, 90, 10, paint);
canvas.drawLine(10, 20, 90, 20, paint);

Dies wird eine gerade horizontale Linie erzeugen, hoffe es hilft!.

user712051
quelle
3

Sie können eine Zeichnung wie Kreis, Linie, Rechteck usw. durch Formen in XML wie folgt erstellen:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="line" >

    <solid android:color="#00000000" />

    <stroke
        android:width="2dp"
        android:color="#808080" />

</shape>
Muhammad Aamir Ali
quelle
3

Dieser Code fügt einem linearen Layout eine horizontale Linie hinzu

View view = new View(this);
LinearLayout.LayoutParams lpView = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 1); // --> horizontal
view.setLayoutParams(lpView);
view.setBackgroundColor(Color.DKGRAY);

linearLayout.addView(view);
user4757345
quelle
2
  final SurfaceView surf = (SurfaceView)findViewById(R.id.surface_home);
                surf.setOnTouchListener( new SurfaceView.OnTouchListener(){
                    private boolean moving = false;//stupid state
                    public boolean onTouch(View v, MotionEvent event) {
                        switch( event.getAction() ){
                        case MotionEvent.ACTION_DOWN:
                            final int x = (int)event.getX();
                            final int y = (int)event.getY();
                            final Rect bounds = mTiles.getBounds();
                            moving = bounds.intersects(x, y, x+1, y+1);
                            return true;
                        case MotionEvent.ACTION_MOVE:
                            if( moving ){
                                final int x_new = (int)event.getX();
                                final int y_new = (int)event.getY();
                                mDrawTiles.draw( new DrawLogic(){
                                    public void draw(Rect _surface) {
                                        mTiles.setBounds(
                                            x_new - mDrawWidth/2,
                                            y_new - mDrawHeight/2,
                                            x_new + mDrawWidth/2,
                                            y_new + mDrawHeight/2);
                                        }
                                    });
Sahil Mahajan Mj
quelle
1

Verbesserung der Antworten von @Janusz

Ich habe dies zu meinen Stilen hinzugefügt:

<style name="Divider">
    <item name="android:layout_width">match_parent</item>
    <item name="android:layout_height">1dp</item>
    <item name="android:background">?android:attr/listDivider</item>
</style>

Dann ist in meinen Layouts weniger Code und einfacher zu lesen.

<View style="@style/Divider"/>

Wenn Sie einen horizontalen Zeilenabstand ausführen möchten, gehen Sie wie oben beschrieben vor.


Und für eine vertikale Linie zwischen zwei Ansichten müssen Sie die Parameter (Attribute) von android: layout_width durch android: layout_height ersetzen

Zar E Ahmer
quelle
1

Ein weiterer Ansatz zum programmgesteuerten Zeichnen einer Linie mit ImageView

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.os.Bundle;
import android.widget.ImageView;

public class Test extends Activity {
  ImageView drawingImageView;

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    drawingImageView = (ImageView) this.findViewById(R.id.DrawingImageView);
    Bitmap bitmap = Bitmap.createBitmap((int) getWindowManager()
        .getDefaultDisplay().getWidth(), (int) getWindowManager()
        .getDefaultDisplay().getHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawingImageView.setImageBitmap(bitmap);

    // Line
    Paint paint = new Paint();
    paint.setColor(Color.GREEN);
    paint.setStrokeWidth(10);
    int startx = 50;
    int starty = 100;
    int endx = 150;
    int endy = 210;
    canvas.drawLine(startx, starty, endx, endy, paint);

  }
}
Zar E Ahmer
quelle
1

Wenn Sie mit arbeiten ConstraintLayout, müssen Sie mindestens zwei Einschränkungen definieren, damit die Zeile angezeigt wird. So was:

<View
        android:layout_width="0dp"
        android:layout_height="1dp"
        android:background="@android:color/black"
        app:layout_constraintEnd_toEndOf="@+id/someView1"
        app:layout_constraintStart_toStartOf="@+id/someView2"
        app:layout_constraintTop_toBottomOf="@+id/someView3" />

Obwohl ich 3 Einschränkungen definiert habe.

Kashif
quelle
-1

oder wenn Sie nur eine Linie wollen

TextView line = new TextView(this);
            line.setBackgroundResource(android.R.color.holo_red_dark);
            line.setHeight((int) Utility.convertDpToPixel(1,this));
Prajwal Udupa
quelle