SampleView extends Viewを、res/layout/main.xmlの中に組み込んでみました。
ポイントは3つ。
一つ目は、Viewクラスのコンストラクタの引数を(Context context, AttributeSet attrs) にすること。
二つ目は、onMeasure(int widthMeasureSpec, int heightMeasureSpec)を定義すること。
最後に、Viewの名前を付けたXMLタグを専用のレイアウトに放り込むこと。(これは自信ない
SampleView.java
package org.ateliernkzn.InnerLayout; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; public class SampleView extends View { public SampleView(Context context, AttributeSet attrs) { super(context, attrs); } protected void onDraw(Canvas canvas){ super.onDraw(canvas); canvas.drawColor(Color.BLUE); Paint mPaint = new Paint(); mPaint.setStyle(Paint.Style.FILL); mPaint.setARGB(255, 255, 255, 100); canvas.drawRect(20, 50, 40, 70, mPaint); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){ setMeasuredDimension(widthMeasureSpec, heightMeasureSpec); } }
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="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="こんなかんじで" android:layout_weight="1" android:gravity="bottom"/> <LinearLayout android:id="@+id/sampleLinear" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_weight="1"> <org.ateliernkzn.InnerLayout.SampleView android:layout_width="fill_parent" android:layout_height="fill_parent"/> </LinearLayout> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="どうじゃろか" android:gravity="right" android:layout_weight="1"/> </LinearLayout>
問題点
入れ子になってるSampleViewは、実はウィンドウサイズと同じだけの表示域を持っています。
SampleViewに大して馬鹿正直にgetWidthとかgetHeightすると、VGA端末なら640*480がそっくりそのまま取得できるということです。
上のサンプル画像で言うと、黄色い四角の下はTextViewに隠されてるだけで存在はしているってことです。
なので、普通にやってると「ビュー部分の底辺のY座標を取ってきてそこから上へhogeピクセルのところに……」という作業ができません。
解決策として、Activity#onWindowFocusChangedのタイミングで「View用レイアウトの」サイズを取得することができます。
こんな感じ。
@Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); int width = findViewById(R.id.sampleLinear).getWidth(); int height = findViewById(R.id.sampleLinear).getHeight(); }
2015.8.27追記
OnGlobalLayoutListenerっていうのがあるらしいですよ。
@Nkzn これを知ってしまったらもう onWindowFocusChanged() でサイズを取得するとか許されないね!
— zaki50 (@zaki50) 2015, 8月 27
はい(震え声)