Jak narysować linię w Androidzie

157

Czy ktoś może powiedzieć, jak narysować linię w systemie Android, może na przykładzie?

mohan
źródło
4
Czy chcesz narysować na czymś linię, czy chcesz narysować prostą linię w układzie?
Janusz

Odpowiedzi:

174

Ten rysuje 2 linie, które tworzą krzyż w lewym górnym rogu ekranu:

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);
    }

}

Czynność, aby ją rozpocząć:

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
źródło
3
jeśli chcę dodać wiersz w innej aktywności, takiej jak R.layout.main Jak mogę dodać?
mohan
1
układ Twojej aktywności musi zawierać obiekt View - wtedy nie ma problemu. Potrzebujesz tylko obiektu widoku do rysowania
DonGru
1
Chcę narysować prostą linię. Jak mogę podać wartość startx start y stopx stopy?
mohan,
w rzeczywistości możesz stwierdzić, że w dokumentacji programisty Androida funkcja drawLine () ma następujące argumenty: drawLine (float startX, float startY, float stopX, float stopY, Paint paint)
DonGru
Tą metodą rysuję linię na tle. Chcę wymazać narysowaną linię. Wszelkie sugestie dla mnie. Czy możesz mi zasugerować?
tientuyen07
240

Jeśli chcesz mieć prostą linię w swoim układzie, aby oddzielić dwa widoki, możesz użyć ogólnego widoku z wysokością i szerokością, jaką ma mieć linia oraz ustawionym kolorem tła.

Dzięki takiemu podejściu nie musisz samodzielnie zastępować widoku ani używać płótna, po prostu w prosty i czysty sposób dodaj wiersz w xml.

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

Przykładowy kod, który podałem, wygeneruje linię, która wypełni ekran na szerokość i będzie miała wysokość jednego dp.

Jeśli masz problemy z rysowaniem linii na małych ekranach, rozważ zmianę wysokości linii na px. Problem polega na tym, że na ekranie ldpi linia będzie miała wysokość 0,75 piksela. Czasami może to spowodować zaokrąglenie, które powoduje zniknięcie linii. Jeśli jest to problem z układem, zdefiniuj szerokość linii w pliku zasobów i utwórz oddzielny plik zasobów dla małych ekranów, który ustawi wartość na 1 piksel zamiast 1 dp.

To podejście jest użyteczne tylko wtedy, gdy potrzebujesz poziomych lub pionowych linii, które są używane do dzielenia elementów układu. Jeśli chcesz osiągnąć coś w rodzaju krzyża, który jest narysowany na obrazie, moje podejście nie zadziała.

Janusz
źródło
Jak można dodać dynamicznie ten sam widok w czasie wykonywania?
Lakshmanan,
Lakshmanan, nadaj mu identyfikator i ustaw jego widoczność na View.GONE lub VISIBLE w czasie wykonywania
Hatim
Dzięki temu rozwiązaniu można również wykonać krzyż, wystarczy dodać w nim atrybut „rotacja” zgodnie z żądanym krzyżem i użyć dwóch widoków.
Arpit J.
62

Istnieją dwa główne sposoby narysowania linii, używając Canvaslub używając View.

Rysowanie linii na płótnie

Z dokumentacji widzimy, że musimy skorzystać z następującej metody:

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

Oto zdjęcie:

canvas.drawLine

PaintObiekt tylko powie Canvasjaki kolor pomalować linię, jak szeroki powinien być, i tak dalej.

Oto przykładowy kod:

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);
}

Rysowanie linii z widokiem

Jeśli potrzebujesz tylko prostej linii poziomej lub pionowej, najłatwiejszym sposobem może być użycie Vieww pliku układu xml. Zrobiłbyś coś takiego:

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

Oto zdjęcie z dwiema liniami (jedną poziomą i jedną pionową), aby pokazać, jak by to wyglądało:

rysowanie linii z widokiem w układzie xml

A oto kompletny układ XML do tego:

<?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
źródło
jesteś genialnym bratem ... Próbowałem dowiedzieć się, w jaki sposób uzyskują współrzędne podczas rysowania widoku za pomocą farby ... ale zdjęcie, które opublikowałeś, pomogło mi to zrozumieć ... jakieś narzędzie online do symulacji takiego wykresu, więc używam go podczas kodowania?
czy można uzyskać oddzwonienie, aby wiedzieć, że widok został zakończony rysowaniem
Próbuję narysować dwie różne linie. Kiedyś, jeśli pierwsza linia została narysowana, muszę narysować drugą ...
Dlaczego nie narysujesz obu linii w tym samym onDraw?
Suragch
1
@ tientuyen07, Jeśli używasz, otocz onDraw()kod rysowania za pomocą if (someCondition) { draw... }, wykonaj someCondition = false, a następnie przywołaj invalidate()swój widok. Przerysuje widok bez linii.
Suragch
22

Możesz narysować wiele linii prostych na widoku, używając przykładu malowania palcem, który jest w Androidzie dla programistów. przykładowy link

Tylko komentarz: mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); będziesz mógł rysować proste linie.

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
źródło
2
Czy ktoś może mi pomóc, jak mogę zobaczyć moje elementy xml w moim widoku, które mają układ względny? możesz po prostu przejść przez powyższy przykład i zasugerować mi.
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
źródło
8

dla linii poziomej na układzie:

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

dla linii pionowej na arkuszu:

<View
        android:id="@+id/View04"
        android:layout_width="5dip"
        android:layout_height="fill_parent"
        android:background="#0f0" />
Mohanraj
źródło
oba są takie same. Jaka jest różnica między pionem a poziomem?
Burhan ARAS,
@ Burhan ARAS - nie są takie same, jak szerokość i wysokość są zmieniane w dwóch widokach. Rysuje tylko pionową i horzową linię.
Mohanraj
7

Prosty

 <TextView
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#c0c0c0"
    android:id="@+id/your_id"
    android:layout_marginTop="160dp" />
shreedhar bhat
źródło
5
canvas.drawLine(10, 10, 90, 10, paint);
canvas.drawLine(10, 20, 90, 20, paint);

Stworzy to prostą poziomą linię, mam nadzieję, że to pomoże!

user712051
źródło
3

Możesz stworzyć rysowalny okrąg, linię, prostokąt itp. Poprzez kształty w xml w następujący sposób:

<?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
źródło
3

ten kod dodaje poziomą linię do układu liniowego

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
źródło
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
źródło
1

Aby poprawić odpowiedzi udzielone przez @Janusz

Dodałem to do moich stylów:

<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>

Wtedy w moich układach jest mniej kodu i prostsze do odczytania.

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

jeśli chcesz zrobić poziome odstępy między wierszami, wykonaj powyższe czynności.


A dla linii pionowej między dwoma widokami musisz zastąpić parametry android: layout_width (atrybuty) android: layout_height

Zar E Ahmer
źródło
1

Inne podejście do programowego rysowania linii przy użyciu 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
źródło
1

Jeśli pracujesz z ConstraintLayout, musisz zdefiniować co najmniej 2 ograniczenia, aby linia się pojawiła. Lubię to:

<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" />

Chociaż zdefiniowałem 3 ograniczenia.

Kashif
źródło
-1

lub jeśli chcesz tylko linię

TextView line = new TextView(this);
            line.setBackgroundResource(android.R.color.holo_red_dark);
            line.setHeight((int) Utility.convertDpToPixel(1,this));
Prajwal Udupa
źródło