2016-09-05 7 views
1

私は、キャンバスを持つ2つのビューをプログラムでプログラムで追加しようとしていますが、最初のものだけが追加されているようです(コンソール出力を見ればわかります)。私は間違って何をしていますか?あなたはレイアウトパラメータを指定せずにrootへのあなたの意見を追加しているAndroidはプログラムでキャンバスで2つのビューを追加します

package app.com.example.android.drawtwoviews; 

import android.content.Context; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.LinearLayout; 

public class MainActivity extends AppCompatActivity { 
    DrawView drawView; 
    DrawView2 drawView2; 
    private LinearLayout root; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     root = new LinearLayout(this); 
     root.setOrientation(LinearLayout.VERTICAL); 

     drawView = new DrawView(this); 
     drawView.setBackgroundColor(Color.WHITE); 
     root.addView(drawView); 

     drawView2 = new DrawView2(this); 
     drawView2.setBackgroundColor(Color.WHITE); 
     root.addView(drawView2); 

     setContentView(root); 
    } 

    public class DrawView extends View { 
     Paint paint = new Paint(); 

     public DrawView(Context context) { 
      super(context); 
     } 

     @Override 
     public void onDraw(Canvas canvas) { 
      System.out.println("DrawView1"); 
      paint.setColor(Color.BLACK); 
      //paint.setStrokeWidth(3); 
      canvas.drawRect(30, 30, 80, 80, paint); 


     } 

    } 


    public class DrawView2 extends View { 
     Paint paint = new Paint(); 

     public DrawView2(Context context) { 
      super(context); 
     } 

     @Override 
     public void onDraw(Canvas canvas) { 
      System.out.println("DrawView2"); 
      paint.setColor(Color.BLUE); 
      paint.setStrokeWidth(3); 
      canvas.drawRect(300, 300, 400, 400, paint); 


     } 

    } 
} 

答えて

2

は、ここに私のコードです。つまり、彼らはどちらもdefault layout parameters of LinearLayoutを取得します。これは、垂直レイアウトの場合、(MATCH_PARENT, WRAP_CONTENT)です。

カスタムビューのいずれもonMeasure()をオーバーライドしません。これは、measureと既定の推奨最小サイズ0×0の両方を意味します。

これは、LinearLayoutが要求されたサイズが0×0で、レイアウト仕様が(MATCH_PARENT, WRAP_CONTENT)の2つのビューをレイアウトしていることを意味します。これがうまくいく方法はa bit trickyですが、最初の子は全画面の高さをとり、2番目の子は0pxの高さです。両方の子供はフルスクリーン幅です。 Hierarchy Viewerで簡単に確認できます。

は、問題を修正するには、レイアウトのparamsを指定することも必要があります。

// in onCreate() 
int width = LinearLayout.LayoutParams.MATCH_PARENT; 
int height = 0; 
int weight = 1; 
LinearLayout.LayoutParams params = 
    new LinearLayout.LayoutParams(width, height, weight); 

drawView = new DrawView(this); 
drawView.setBackgroundColor(Color.WHITE); 
root.addView(drawView, params); // note the extra argument 

drawView2 = new DrawView2(this); 
drawView2.setBackgroundColor(Color.WHITE); 
root.addView(drawView2, params); // note the extra argument 

それとも、彼らはいくつかの最小サイズに測るように、あなたはDrawView Sを変更することができます。

public class DrawView extends View { 
    // paint 
    // constructor 
    // onDraw 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     setMeasuredDimension(80, 80); 
    } 
} 


public class DrawView2 extends View { 
    // paint 
    // constructor 
    // onDraw 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     setMeasuredDimension(400, 400); 
    } 
} 
+0

これは素晴らしい動作です!私は、(LayoutParamsの)heightパラメータを0に設定すると、効果的に高さを最小限に設定して、キャンバスが占めることを確認したいと思います。 – Naci

+1

'LayoutParams.height'に0を設定するのは、' LayoutParams.weight'が存在するためです。高さ0は、 "layout_weightのみで行く"という意味です。 DrawViewの最小サイズを設定するには、LinearLayoutが最小サイズを取得できるようにonMeasure()実装を追加し、1つのDrawViewのLayoutParamsで 'height = LayoutParams.WRAP_CONTENT'を使用し、' height = 0、weight =他のDrawViewのLayoutParamsに「1」を追加します。 – Barend

0

がこれを設定してみてくださいあなたのビューのコンストラクタのフラグ:

public DrawView(Context context) { 
     super(context); 
     setWillNotDraw(false); 
} 

これはあなたのビューあなたがカスタム描画をしたいということを知らず、描画するものがないのでonDraw()は呼び出されません。