Android: วิธีการวาดเส้นขอบให้เป็น LinearLayout


197

ฉันมีสามไฟล์ XML, ฟังก์ชั่นการวาดและกิจกรรมหลัก ฉันมีบางอย่างLinearLayoutในไฟล์ XML ของฉัน

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

นี่คือฟังก์ชั่นการวาด:

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

และนี่คือกิจกรรมหลัก:

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

โปรแกรมที่สามารถวาดเส้นขอบ LinearLayoutแต่ขนาดไม่พอดี และเมื่อฉันคลิกLinearLayoutอีกครั้งโปรแกรมก็จะขัดข้อง

อีกอย่างฉันอยากวาดวงกลมสองวงที่กึ่งกลางLinearLayoutแต่จะหาพิกัดศูนย์กลางได้อย่างไร

คำตอบ:


459

คุณต้องการทำสิ่งนั้นด้วยโปรแกรมหรือไม่?

เพียงแค่พิจารณาชื่อ: คุณสามารถใช้ ShapeDrawable เป็น android: พื้นหลัง ...

ตัวอย่างเช่นให้นิยามres/drawable/my_custom_background.xmlดังนี้:

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

และกำหนด android: background = "@ drawable / my_custom_background"

ฉันไม่ได้ทดสอบ แต่ควรใช้งานได้

ปรับปรุง:

ฉันคิดว่าดีกว่าที่จะใช้ประโยชน์จากทรัพยากรรูปทรง xml ที่สามารถดึงได้ถ้ามันเหมาะกับความต้องการของคุณ ด้วยโปรเจ็กต์ "from scratch" (สำหรับ android-8) ให้กำหนด 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>

และ 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>

แจ้งว่าทำงานกับอุปกรณ์ขนมปังขิง โปรดทราบว่าคุณจะต้องเกี่ยวข้องกับandroid:paddingLinearLayout กับค่าของandroid:widthรูปร่าง / จังหวะ กรุณาอย่าใช้@android:color/whiteในใบสมัครสุดท้ายของคุณ แต่เป็นสีที่กำหนดไว้ในโครงการ

คุณสามารถนำandroid:background="@drawable/border" android:padding="10dip"ไปใช้กับ LinearLayout แต่ละรายการได้จากตัวอย่างที่คุณให้

สำหรับโพสต์อื่น ๆ ของคุณที่เกี่ยวข้องกับการแสดงวงกลมบางส่วนเป็นพื้นหลังของ LinearLayout ฉันกำลังเล่นกับทรัพยากรที่วาดได้ของ Inset / Scale / Layer ( ดูทรัพยากร Drawableสำหรับข้อมูลเพิ่มเติม) เพื่อให้สิ่งที่ทำงานแสดงวงกลมที่สมบูรณ์แบบในเบื้องหลังของ LinearLayout แต่ล้มเหลว ในขณะนี้ ...

getBorder.set{Width,Height}(100);ปัญหาของคุณอยู่อย่างชัดเจนในการใช้งานของ ทำไมคุณทำเช่นนั้นในวิธีการ onClick?

ฉันต้องการข้อมูลเพิ่มเติมเพื่อไม่พลาดประเด็น: ทำไมคุณถึงทำแบบนั้นโดยทางโปรแกรม? คุณต้องการพฤติกรรมแบบไดนามิกหรือไม่? drawable อินพุตของคุณคือ png หรือ ShapeDrawable นั้นยอมรับได้ เป็นต้น

จะดำเนินการต่อไป (อาจจะในวันพรุ่งนี้และทันทีที่คุณให้ความสำคัญกับสิ่งที่คุณต้องการบรรลุมากขึ้น) ...



@ เรโนลต์มีวิธีในการเปลี่ยนสีของเส้นขอบอย่างมีปัญหาหรือไม่?
user1940676

12
ไม่แน่ใจว่าทำไมมันเป็นกรณีที่ แต่เมื่อฉันใช้นี้บนLinearLayoutผมได้เติมของแข็งจากสีของเส้นขอบเว้นแต่ฉันเพิ่มเด็กต่อไปนี้เป็นshapeองค์ประกอบ:<solid android:color="@android:color/transparent" />
dahvyd

2
สำหรับฉันมันเหมือนกันฉันต้องเพิ่ม<solid android:color="@color/lighter_gray" />มิฉะนั้นฉันก็มีพื้นหลังสีดำ
Panciz

1
วิธีนี้ใช้ได้ผลอย่างสมบูรณ์ อย่างไรก็ตามมันสร้างสองชั้น "Overdraw" ซึ่งไม่ดีต่อประสิทธิภาพแม้ว่าคุณจะตั้งค่าพื้นหลังเป็น "null" หรือ "โปร่งใส" ใครช่วยแนะนำวิธีแก้ปัญหานี้ได้บ้าง
Sam Ramezanli

16

ขยาย LinearLayout / RelativeLayout และใช้โดยตรงบน 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
กรุณาอย่าจัดสรรหน่วยความจำในonDraw()วิธีการสร้างวัตถุของคุณในinit()วิธีการที่เรียกโดยนวกรรมิกและนำมาใช้ใหม่ในonDraw()วิธีการ การจัดสรรในonDraw()(เรียกว่า 60 ครั้งต่อวินาที) นำไปสู่ประสิทธิภาพที่ไม่ดีท่อระบายน้ำแบตเตอรี่ ฯลฯ
Louis CAD
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.