Як намалювати лінію в android


157

Хтось може сказати, як намалювати лінію в Android, можливо, на прикладі?


4
Ви хочете намалювати лінію в щось або ви хочете намалювати просту лінію в макеті?
Януш

Відповіді:


174

Цей малює 2 лінії, які утворюють хрестик у верхньому лівому куті екрана:

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

}

Діяльність для його початку:

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

    }
}

3
якщо я хочу додати рядок у якійсь іншій діяльності, наприклад R.layout.main Як я можу додати?
mohan

1
макет вашої діяльності повинен містити об’єкт View - тоді це не проблема. Вам просто потрібен об’єкт View, щоб намалювати
DonGru

1
Я хочу провести пряму лінію, як я можу дати значення startx start y stopx stopy?
mohan

насправді ви можете виявити, що у посиланні розробника для android, drawLine () має такі аргументи: drawLine (float startX, float startY, float stopX, float stopY, Paint paint)
DonGru

Я малюю лінію на тлі за допомогою цього методу. Я хочу стерти намальовану лінію. Будь-які пропозиції для мене. Ви можете мені запропонувати?
tientuyen07

240

Якщо ви хочете, щоб у вашій макеті була проста лінія для розділення двох представлень, ви можете використовувати загальний вигляд з висотою та шириною, яку ви хочете, щоб лінія мала і встановлений колір фону.

При такому підході вам не потрібно переосмислювати подання або використовувати Canvas самостійно, просто та чисто додайте рядок у xml.

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

Наведений я приклад код створить рядок, який заповнює екран по ширині і має висоту одного dp.

Якщо у вас є проблеми з нанесенням лінії на маленьких екранах, подумайте про зміну висоти лінії на px. Проблема полягає в тому, що на екрані ldpi лінія буде висотою 0,75 пікселя. Іноді це може призвести до закруглення, яке змушує лінію зникати. Якщо це проблема для вашого макета, визначте ширину рядка файла ресурсу та створіть окремий файл ресурсу для невеликих екранів, який встановить значення 1px замість 1dp.

Цей підхід застосований лише у тому випадку, якщо ви хочете, щоб горизонтальні чи вертикальні лінії використовувались для поділу елементів компонування. Якщо ви хочете досягти чогось на кшталт хреста, який намальований у зображенні, мій підхід не вийде.


Як можна додати однаковий вигляд під час виконання динамічно?
Лакшман

Лакшманан, дайте йому ідентифікатор і встановіть його видимість на View.GONE або VISIBLE під час роботи
Хатим

Хрест також може бути зроблений за допомогою цього рішення, просто додайте в нього атрибут "обертання" відповідно до потрібного хреста та використовуйте два подання.
Арпіт Дж

62

Є два основні способи провести лінію, використовуючи a Canvasабо за допомогою View.

Нанесення лінії полотном

З документації ми бачимо, що нам потрібно використовувати наступний метод:

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

Ось малюнок:

canvas.drawLine

PaintОб'єкт просто говорить , Canvasщо колір , щоб намалювати лінію, наскільки широко вона повинна бути, і так далі.

Ось приклад коду:

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

Нанесення лінії з видом

Якщо вам потрібна лише пряма горизонтальна або вертикальна лінія, то найпростішим способом може бути просто використання Viewу вашому файлі макета xml. Ви зробите щось подібне:

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

Ось малюнок з двома лініями (одна горизонтальна та одна вертикальна), щоб показати, як воно виглядатиме:

малювання лінії з видом у форматі xml

І ось повний макет xml для цього:

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

ти геніальний брате ... Я намагався розібратися, як вони отримують координати, малюючи подання за допомогою фарби ... але малюнок, який ти опублікував, допоміг мені це зрозуміти .... будь-який онлайн-інструмент для імітації такого графіка, щоб я використовував його під час кодування?

чи можна отримати зворотний дзвінок, щоб знати, що перегляд закінчено малювати

Я намагаюся намалювати дві різні лінії. Раз, якщо перший рядок був намальований, я повинен намалювати другий ...

Чому ви не намалюєте обидва рядки в одному і тому ж onDraw?
Сурагч

1
@ tientuyen07, Якщо ви використовуєте, onDraw()тоді оточіть свій креслення код if (someCondition) { draw... }, зробіть someCondition = false, а потім зателефонуйте invalidate()на свій погляд. Це перемальовує погляд без лінії.
Сурагч

22

Ви можете намалювати декілька прямих ліній на зображенні, використовуючи приклад фарби Finger, який знаходиться в Android Developer. Приклад посилання

Просто коментар: mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); Ви зможете намалювати прямі лінії.

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

}

2
Чи може мені хтось допомогти, як я можу бачити мої елементи XML на своєму погляді, які знаходяться на відносному макеті ?? Ви можете просто пройти вищенаведений приклад і запропонувати мені.
Хема

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

        }
}
}

8

для горизонтальної лінії на макеті:

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

для вертикальної лінії на макеті:

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

вони обоє однакові. у чому полягає різниця між вертикальним і горизонтальним?
Burhan ARAS

@ Burhan ARAS - вони не збігаються з шириною і висотою в двох видах.
Mohanraj

7

Простий

 <TextView
    android:layout_width="match_parent"
    android:layout_height="1dp"
    android:background="#c0c0c0"
    android:id="@+id/your_id"
    android:layout_marginTop="160dp" />

5
canvas.drawLine(10, 10, 90, 10, paint);
canvas.drawLine(10, 20, 90, 20, paint);

Це створить пряму горизонтальну лінію, сподіваємось, що це допоможе !.


3

Ви можете зробити такий рисунок, як коло, лінія, прямокутник тощо, за допомогою фігур у форматі xml, як описано нижче:

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

3

цей код додає горизонтальну лінію до лінійного макета

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

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

1

Щоб покращити відповіді, надані @Janusz

Я додав це до своїх стилів:

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

Тоді в моїх макетів менше коду і простіше читати.

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

якщо ви хочете зробити горизонтальний інтервал між лініями, то зробіть вище.


А для вертикальної лінії між двома видами ви повинні замінити android: параметри layout_width (атрибути) на android: layout_height


1

Ще один підхід до того, щоб намалювати лінію програмно, використовуючи 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);

  }
}

1

Якщо ви працюєте з ConstraintLayoutвами, вам потрібно визначити щонайменше два обмеження для відображення рядка. Подобається це:

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

Хоча я визначив 3 обмеження.


-1

або якщо ви просто хочете лінію

TextView line = new TextView(this);
            line.setBackgroundResource(android.R.color.holo_red_dark);
            line.setHeight((int) Utility.convertDpToPixel(1,this));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.