Android:LinearLayoutに境界線を描画する方法


197

3つのファイルがあります。XML、描画機能、メインアクティビティ。LinearLayoutXMLファイルにいくつかあります。

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

プログラムは境界線を描画できましたが、サイズがに適合しませんでしたLinearLayoutLinearLayoutもう一度クリックすると、プログラムがクラッシュします。

もう1つ、2つの円をの中心に描画したいのですLinearLayoutが、中心座標をどのようにして把握できますか?

回答:


460

あなたは本当にそれをプログラムで行う必要がありますか?

タイトルだけを考えると、ShapeDrawableをandroid:background…として使用できます。

たとえば、次のように定義し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形状のドローアブルリソースの力を活用する方が良いと思います。「ゼロから」プロジェクト(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のドローアブルリソース(詳細については、「ドローアブルリソース」を参照)で遊んで、LinearLayoutのバックグラウンドで完全な円を表示するために何かを動作させていますが、失敗しました現時点では…

あなたの問題は明らかにの使用にありgetBorder.set{Width,Height}(100);ます。なぜそれをonClickメソッドで行うのですか?

要点を見逃さないように、さらに情報が必要です。なぜプログラムでそれを行うのですか?動的な動作が必要ですか?入力したドローアブルはpngですか、それともShapeDrawableを使用できますか?等

継続すること(多分明日、達成したいことについてより多くの精度を提供するとすぐに)…



@Renaud境界線の色を問題のある方法で変更する方法はありますか?
user1940676

12
それはそうだった理由を特定の、しかし、ときに私が上でこれを使用していないLinearLayoutI私は以下の子を追加しない限り、境界線の色から塗りつぶしを得たshape要素:<solid android:color="@android:color/transparent" />
dahvyd

2
私にとってそれは私が追加し<solid android:color="@color/lighter_gray" />なければならなかったのと同じでした、そうでなければ私は黒い背景を得ました
Panciz

1
この方法は完全に機能します。ただし、背景を「null」または「透明」に設定した場合でも、パフォーマンスに非常に悪い2つのレイヤー「オーバードロー」が作成されます。誰でもこの問題を修正する方法を提案できますか?
サムラメザンリ2016

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.