Làm thế nào để vẽ một đường trong Android


157

Bất cứ ai cũng có thể cho biết làm thế nào để vẽ một dòng trong Android, có lẽ với một ví dụ?


4
Bạn có muốn vẽ một đường thẳng vào một cái gì đó hoặc bạn muốn vẽ một đường đơn giản trong bố cục?
Janusz

Câu trả lời:


174

Cái này vẽ 2 dòng tạo thành hình chữ thập ở phía trên bên trái màn hình:

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

}

Các hoạt động để bắt đầu nó:

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
nếu tôi muốn thêm một dòng trong một số hoạt động khác như R.layout.main Làm thế nào tôi có thể thêm?
mohan

1
bố cục hoạt động của bạn phải chứa đối tượng Xem - thì không vấn đề gì. Bạn chỉ cần một đối tượng View để vẽ
DonGru

1
Tôi muốn vẽ một đường thẳng làm thế nào tôi có thể đưa ra giá trị startx start y stopx stopy?
mohan

thực tế bạn có thể thấy rằng trong tài liệu tham khảo dành cho nhà phát triển Android, drawLine () có các đối số sau: drawLine (float startX, float startY, float stopX, float stopY, Paint paint)
DonGru

Tôi vẽ đường trên nền bằng phương pháp này. Tôi muốn xóa một đường vẽ. Mọi góp ý cho tôi. Bạn có thể gợi ý cho tôi?
tientuyen07

240

Nếu bạn muốn có một Dòng đơn giản trong Bố cục của mình để tách hai chế độ xem, bạn có thể sử dụng Chế độ xem chung với chiều cao và chiều rộng mà bạn muốn dòng có và màu nền được đặt.

Với phương pháp này, bạn không cần phải ghi đè Chế độ xem hoặc sử dụng Canvas một cách đơn giản và gọn gàng thêm dòng trong xml.

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

Mã ví dụ tôi cung cấp sẽ tạo ra một dòng lấp đầy màn hình theo chiều rộng và có chiều cao là một dp.

Nếu bạn gặp vấn đề với bản vẽ của dòng trên màn hình nhỏ, hãy cân nhắc thay đổi chiều cao của dòng thành px. Vấn đề là trên màn hình ldpi, dòng sẽ cao 0,75 pixel. Đôi khi điều này có thể dẫn đến một làm tròn làm cho dòng biến mất. Nếu đây là vấn đề đối với bố cục của bạn, hãy xác định độ rộng của dòng tệp ressource và tạo tệp ressource riêng cho màn hình nhỏ đặt giá trị thành 1px thay vì 1dp.

Cách tiếp cận này chỉ có thể sử dụng được nếu bạn muốn các đường ngang hoặc dọc được sử dụng để phân chia các thành phần bố cục. Nếu bạn muốn đạt được một cái gì đó giống như hình chữ thập được vẽ thành hình ảnh thì phương pháp của tôi sẽ không hiệu quả.


Làm thế nào có thể thêm cùng một chế độ xem trong thời gian chạy đó là động?
Lakshmanan

Lakshmanan, cung cấp cho nó một id và đặt mức độ hiển thị của nó thành View.GONE hoặc VISIBLE vào thời gian chạy
Hatim

Một chữ thập cũng có thể được thực hiện với giải pháp này, chỉ cần thêm thuộc tính "xoay" trong đó theo chữ thập bạn muốn và sử dụng hai chế độ xem.
Arpit J.

62

Có hai cách chính bạn có thể vẽ một đường, bằng cách sử dụng một Canvashoặc bằng cách sử dụng mộtView .

Vẽ một đường thẳng với Canvas

Từ tài liệu chúng tôi thấy rằng chúng tôi cần sử dụng phương pháp sau:

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

Đây là một hình ảnh:

canvas.drawLine

Đối Painttượng chỉ cho Canvasbiết màu gì để vẽ đường kẻ, nó nên rộng bao nhiêu, v.v.

Đây là một số mã mẫu:

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

Vẽ một đường thẳng với chế độ xem

Nếu bạn chỉ cần một đường thẳng hoặc ngang thẳng, thì cách dễ nhất có thể là chỉ sử dụng một Viewtrong tệp bố cục xml của bạn. Bạn sẽ làm một cái gì đó như thế này:

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

Dưới đây là một hình ảnh với hai dòng (một ngang và một dọc) để hiển thị nó sẽ trông như thế nào:

vẽ một dòng với chế độ xem theo bố cục xml

Và đây là cách bố trí xml hoàn chỉnh cho điều đó:

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

bạn là một thiên tài ... Tôi đã cố gắng tìm hiểu làm thế nào họ có được tọa độ trong khi vẽ một khung nhìn bằng cách sử dụng sơn ... nhưng bức ảnh mà bạn đã đăng đã giúp tôi hiểu về nó khá nhiều .... bất kỳ công cụ trực tuyến để mô phỏng đồ thị như vậy để tôi sử dụng nó trong khi mã hóa?

có thể nhận được một cuộc gọi lại để biết rằng chế độ xem đã được vẽ xong

Tôi đang cố vẽ hai đường khác nhau. Một lần nếu dòng đầu tiên được vẽ, tôi phải vẽ dòng thứ hai ...

Tại sao bạn không vẽ cả hai dòng trong cùng một onDraw?
Suragch

1
@ tientuyen07, Nếu bạn đang sử dụng onDraw()thì hãy bao quanh mã bản vẽ của bạn với if (someCondition) { draw... }, thực hiện someCondition = falsevà sau đó gọi invalidate()vào chế độ xem của bạn. Nó sẽ vẽ lại khung nhìn mà không cần đường kẻ.
Suragch

22

Bạn có thể vẽ nhiều đường thẳng trên chế độ xem bằng ví dụ Vẽ bằng ngón tay trong Nhà phát triển Android. liên kết ví dụ

Chỉ cần nhận xét: mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2); Bạn sẽ có thể vẽ các đường thẳng.

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
Ai đó có thể giúp tôi làm thế nào tôi có thể thấy các yếu tố xml của tôi trên chế độ xem của tôi trên bố cục tương đối không ?? bạn chỉ có thể đi qua ví dụ trên và đề nghị tôi.
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);

        }
}
}

8

cho đường ngang trên bố cục:

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

cho đường thẳng đứng trên bố cục:

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

cả hai đều giống nhau Điều gì làm nên sự khác biệt giữa chiều dọc và chiều ngang?
Burhan ARAS

@ Burhan ARAS-chúng không giống nhau về chiều rộng và chiều cao được thay đổi trong hai khung nhìn. Nó chỉ vẽ đường thẳng đứng và đường horz.
Mohanraj

7

Đơn giản

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

Điều này sẽ tạo ra một đường thẳng ngang, hy vọng nó sẽ giúp!.


3

Bạn có thể tạo một hình vẽ như hình tròn, đường thẳng, hình chữ nhật, vv thông qua các hình dạng trong xml như sau:

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

mã này thêm đường ngang vào bố cục tuyến tính

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

Để cải thiện các câu trả lời được cung cấp bởi @Janusz

Tôi đã thêm nó vào phong cách của tôi:

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

Sau đó, trong bố trí của tôi là ít mã hơn và đơn giản hơn để đọc.

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

Nếu bạn muốn làm khoảng cách dòng ngang thì làm như trên.


Và đối với đường thẳng đứng giữa hai Chế độ xem, bạn phải thay thế tham số android: layout_creen (thuộc tính) bằng android: layout_height


1

Một cách tiếp cận khác để vẽ một dòng lập trình bằng 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

Nếu bạn đang làm việc với ConstraintLayoutbạn, cần xác định ít nhất 2 ràng buộc để dòng hiển thị. Như thế này:

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

Mặc dù tôi đã xác định 3 ràng buộc.


-1

hoặc nếu bạn chỉ muốn một dòng

TextView line = new TextView(this);
            line.setBackgroundResource(android.R.color.holo_red_dark);
            line.setHeight((int) Utility.convertDpToPixel(1,this));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.