Android: cách vẽ đường viền cho linearLayout


197

Tôi có ba tập tin. XML, hàm vẽ và Hoạt động chính. Tôi có một số LinearLayouttrong tệp XML của mình.

<LinearLayout android:orientation="horizontal"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:layout_weight="1">
    <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_weight="1"
                  android:background="#ef3"
                  android:id="@+id/img01"/>
    <LinearLayout android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:layout_weight="1"
                  android:background="#E8A2B4"
                  android:id="@+id/img02"/>
</LinearLayout>

Đây là chức năng vẽ:

public class getBorder extends TextView {
    public getBorder(Context context) {
        super(context);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Paint paint = new Paint();

        paint.setColor(android.graphics.Color.RED);

        canvas.drawLine(0, 0, this.getWidth() - 1, 0, paint);
        canvas.drawLine(0, 0, 0, this.getHeight() - 1, paint);
        canvas.drawLine(this.getWidth() - 1, 0, this.getWidth() - 1,
            this.getHeight() - 1, paint);
        canvas.drawLine(0, this.getHeight() - 1, this.getWidth() - 1,
            this.getHeight() - 1, paint);
    }
}

Và đây là Hoạt động chính:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    final getBorder getBorder = new getBorder(this);
    final LinearLayout img01 = (LinearLayout) findViewById(R.id.img01);
    img01.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            getBorder.setWidth(100);
            getBorder.setHeight(100);
            img01.addView(getBorder);
        }
    });       
}

Chương trình có thể vẽ đường viền nhưng kích thước không vừa LinearLayout. Và khi tôi nhấp LinearLayoutlại, chương trình gặp sự cố.

Một điều nữa, tôi muốn vẽ hai vòng tròn ở trung tâm LinearLayout, nhưng làm thế nào tôi có thể tìm ra tọa độ trung tâm?

Câu trả lời:


460

Bạn có thực sự cần phải làm điều đó theo chương trình?

Chỉ cần xem xét tiêu đề: Bạn có thể sử dụng ShapeDrawable như android: nền

Ví dụ: hãy xác định res/drawable/my_custom_background.xmllà:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
  <corners
      android:radius="2dp"
      android:topRightRadius="0dp"
      android:bottomRightRadius="0dp"
      android:bottomLeftRadius="0dp" />
  <stroke
      android:width="1dp"
      android:color="@android:color/white" />
</shape>

và xác định android: background = "@ drawable / my_custom_background".

Tôi đã không thử nghiệm nhưng nó sẽ hoạt động.

Cập nhật:

Tôi nghĩ rằng tốt hơn là tận dụng sức mạnh tài nguyên có thể rút ra của hình dạng xml nếu phù hợp với nhu cầu của bạn. Với dự án "từ đầu" (dành cho Android-8), hãy xác định res / layout / main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/border"
    android:padding="10dip" >
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, SOnich"
        />
    [... more TextView ...]
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Hello World, SOnich"
        />
</LinearLayout>

và một res/drawable/border.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
   <stroke
        android:width="5dip"
        android:color="@android:color/white" />
</shape>

Báo cáo để làm việc trên một thiết bị bánh gừng. Lưu ý rằng bạn sẽ cần liên quan đến android:paddinglinearLayout với android:widthgiá trị của hình dạng / nét. Xin vui lòng, không sử dụng @android:color/whitetrong ứng dụng cuối cùng của bạn mà thay vào đó là một màu xác định dự án.

Bạn có thể áp dụng android:background="@drawable/border" android:padding="10dip"cho từng Tuyến tính từ mẫu được cung cấp của bạn.

Đối với các bài đăng khác của bạn liên quan đến việc hiển thị một số vòng tròn dưới dạng nền của linearLayout, tôi đang chơi với các tài nguyên có thể vẽ Inset / Scale / Layer ( xem Tài nguyên có thể vẽ để biết thêm thông tin) để có được thứ gì đó hoạt động để hiển thị các vòng tròn hoàn hảo trong nền của linearLayout nhưng không thành công tại thời điểm này…

Vấn đề của bạn nằm rõ ràng trong việc sử dụng getBorder.set{Width,Height}(100);. Tại sao bạn làm điều đó trong một phương pháp onClick?

Tôi cần thêm thông tin để không bỏ lỡ vấn đề: tại sao bạn làm điều đó theo chương trình? Bạn có cần một hành vi năng động? Drawables đầu vào của bạn là png hoặc ShapeDrawable được chấp nhận? Vân vân.

Sẽ được tiếp tục (có thể vào ngày mai và ngay khi bạn cung cấp thêm các quy định về những gì bạn muốn đạt được)



@Renaud có cách nào thay đổi màu đường viền một cách có vấn đề không?
dùng1940676

12
Không chắc tại sao lại như vậy, nhưng khi tôi sử dụng cái này trên một cái LinearLayouttôi có một khối màu đặc từ màu viền, trừ khi tôi thêm đứa con sau vào shapephần tử:<solid android:color="@android:color/transparent" />
dahvyd 31/12/13

2
Đối với tôi cũng giống như tôi phải thêm một, <solid android:color="@color/lighter_gray" />nếu không tôi có nền đen
Panciz

1
Phương pháp này hoạt động hoàn hảo; tuy nhiên, nó tạo ra hai lớp "Rút tiền" thực sự không tốt cho hiệu suất, ngay cả khi bạn đặt nền là "null" hoặc "trong suốt". Bất cứ ai có thể đề nghị một cách để khắc phục vấn đề này?
Sam Ramezanli

16

Mở rộng tuyến tính / RelativeLayout và sử dụng trực tiếp trên XML

package com.pkg_name ;
...imports...
public class LinearLayoutOutlined extends LinearLayout {
    Paint paint;    

    public LinearLayoutOutlined(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        setWillNotDraw(false) ;
        paint = new Paint();
    }
    public LinearLayoutOutlined(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        setWillNotDraw(false) ;
        paint = new Paint();
    }
    @Override
    protected void onDraw(Canvas canvas) {
        /*
        Paint fillPaint = paint;
        fillPaint.setARGB(255, 0, 255, 0);
        fillPaint.setStyle(Paint.Style.FILL);
        canvas.drawPaint(fillPaint) ;
        */

        Paint strokePaint = paint;
        strokePaint.setARGB(255, 255, 0, 0);
        strokePaint.setStyle(Paint.Style.STROKE);
        strokePaint.setStrokeWidth(2);  
        Rect r = canvas.getClipBounds() ;
        Rect outline = new Rect( 1,1,r.right-1, r.bottom-1) ;
        canvas.drawRect(outline, strokePaint) ;
    }

}

<?xml version="1.0" encoding="utf-8"?>

<com.pkg_name.LinearLayoutOutlined
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
    android:layout_width=...
    android:layout_height=...
   >
   ... your widgets here ...

</com.pkg_name.LinearLayoutOutlined>

34
Xin vui lòng, không phân bổ bộ nhớ trong onDraw()phương thức, tạo các đối tượng của bạn trong một init()phương thức, được gọi bởi hàm tạo và sử dụng lại chúng trong onDraw()phương thức. Phân bổ onDraw()(được gọi là 60 lần mỗi giây) dẫn đến hiệu suất kém, hao pin, v.v.
Louis CAD
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.