Android: LinearLayout'a nasıl sınır çizilir


197

Üç dosyam var. XML, çizim işlevi ve ana Etkinlik. LinearLayoutXML dosyamda bazı var .

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

Bu çizim işlevidir:

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

Ve bu ana Faaliyet:

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

Program kenarlık çizebilir ancak boyutu LinearLayout. LinearLayoutTekrar tıkladığımda program çöktü.

Ayrıca, ortasına iki daire çizmek istiyorum LinearLayout, ancak merkez koordinatlarını nasıl bulabilirim?

Yanıtlar:


461

Bunu gerçekten programlı bir şekilde yapmanız gerekiyor mu?

Sadece başlık dikkate alındığında: android gibi bir ShapeDrawable kullanabilirsiniz: background…

Örneğin, şöyle tanımlayalım 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>

ve android'i tanımlayın: background = "@ drawable / my_custom_background".

Test etmedim ama işe yaramalı.

Güncelleme:

İhtiyaçlarınıza uygunsa xml şekli çekilebilir kaynak gücünden faydalanmak daha iyi olduğunu düşünüyorum. "Sıfırdan" projesiyle (android-8 için) res / layout / main.xml dosyasını tanımlayın

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

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

Bir zencefilli kurabiye cihazı üzerinde çalıştığı bildirildi. android:paddingLinearLayout öğesinin android:widthşekil / kontur değeri ile ilgili olması gerektiğini unutmayın . Lütfen @android:color/whiteson uygulamanızda değil, proje tanımlı renkte kullanın.

android:background="@drawable/border" android:padding="10dip"Sağladığınız örnekten LinearLayout ürününün her birine başvurabilirsiniz .

Bazı çevreleri LinearLayout'un arka planı olarak görüntülemekle ilgili diğer yayınlarınızda, LinearLayout'un arka planında mükemmel daireler görüntülemek için çalışan bir şey elde etmek için Inset / Scale / Layer çekilebilir kaynaklarıyla oynuyorum ( daha fazla bilgi için bkz. Çekilebilir Kaynaklar ). Şu an…

Sorununuz kullanımında açıkça yer alıyor getBorder.set{Width,Height}(100);. Bunu neden bir onClick yönteminde yapıyorsunuz?

Konuyu kaçırmamak için daha fazla bilgiye ihtiyacım var: bunu neden programlı olarak yapıyorsunuz? Dinamik bir davranışa mı ihtiyacınız var? Giriş çekmeceleriniz png veya ShapeDrawable kabul edilebilir mi? vb.

Devam etmek için (belki yarın ve ne elde etmek istediğinize dair daha fazla hassasiyet sağladığınız anda)…



@Renaud, kenarlık rengini sorunlu bir şekilde değiştirmenin bir yolu var mı?
user1940676

12
Neden böyle olduğundan emin değilim, ancak bunu bir a kullandığımda LinearLayout, shapeöğeye aşağıdaki çocuğu <solid android:color="@android:color/transparent" />
eklemezsem

2
Benim için eklemek zorunda olduğum şey aynıydı, <solid android:color="@color/lighter_gray" />aksi halde siyah bir arka
planım

1
Bu yöntem mükemmel çalışır; ancak, arka planı "boş" veya "saydam" olarak ayarlasanız bile, performans için gerçekten kötü olan iki katman "Overdraw" oluşturur. Herkes bu sorunu çözmek için bir yol önerebilir?
Sam Ramezanli

16

LinearLayout / RelativeLayout'u genişletin ve doğrudan XML'de kullanın

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
Lütfen, onDraw()yöntemi yöntemle ayırmayın , nesneleriniziinit() yapıcı tarafından çağrılan yöntemde oluşturun ve onDraw()yöntemde yeniden kullanın . Ayırma onDraw()(saniyede 60 kez denir) düşük performansa, pil tüketimine vb. Neden olur
Louis CAD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.