ViewStubを使ったロゴ表示テスト

 ViewStubをつかった例として、スタートロゴをだす例で使えるか試してみた。
ただ正直なところあんまり差分が解らないな・・・。というのが正直なところです
若干起動は速くみえる気がしますが。..

レイアウト側)

  • A)画像が大きい場合
    • 画面一杯をイメージ
    • res/layout/start.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewStub
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/start"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
 />
    • res/layout/start_img.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
		android:layout_width="warp_content"
		android:layout_height="warp_content"
		android:scaleType="fitXY"
		android:src="@drawable/logo_full"
/>
  • B)画像が小さい場合
    • 広告バナーみたいなの中央とか(//☆が差分)
    • res/layout/start.xml
<?xml version="1.0" encoding="utf-8"?>
<ViewStub
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/start"
	android:layout_width="wrap_content"  //☆
	android:layout_height="wrap_content" //☆
/>
    • res/layout/start_img.xml
<?xml version="1.0" encoding="utf-8"?>
<ImageView
	android:layout_width="warp_content"
	android:layout_height="warp_content"
	android:scaleType="fitXY"
	android:src="@drawable/logo"
/>

 
呼び出しコード側)

setContentView(R.layout.start);
new Handler(getMainLooper()).post(new Runnable(){
	@Override
	public void run() {
		try{
			ViewStub stub = (ViewStub)findViewById(R.id.start);
			if(stub==null)return; //☆ たまにぬるぽが。。。
			stub.setLayoutResource(R.layout.start_img); //☆ Resource参照もコケることも。。。<汗
			stub.inflate();
		}catch(Exception ex){}
	}
});

備考)
☆で落ちることも有るようなので対策忘れずに*1

参考にした処)



追記1)

 onCreateで最初スプラッシュ用レイアウト出して、本画面レイアウトに切替ようと思ってずっと出来なかったんだけど
結局下記の形にしたら出来たので一応メモ

 ようは setContentViewが描画されるには
IO待ちしてやらないと駄目で、しかも new Threadで完全別スレッドにしないと駄目というオチ

@Override
public void onCreate(Bundle savedInstanceState) {
	this.requestWindowFeature(Window.FEATURE_NO_TITLE);
	getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
	getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
	super.onCreate(savedInstanceState);

	setContentView(R.layout.start);
	new Handler(getMainLooper()).post(new Runnable(){
		@Override
		public void run() {
			ViewStub stub = (ViewStub)findViewById(R.id.start);
			stub.setLayoutResource(R.layout.start_img);
			stub.inflate();
		}
	});

	//[TODO]ImageViewのリフレッシュも駄目・・・
	//ImageView iv = (ImageView)findViewById(R.id.start);
	//iv.invalidate();
		
	//[TODO]Handler遅延も駄目・・・
/*
	Handler handler = new Handler() {
        	public void handleMessage(Message msg) {
        		onCreateAction();
            	}
        };
        
        long time = 3000;
        Message msg = new Message();
        handler.sendMessageAtTime(msg,time);
*/
		
	final Activity activity = this;
       	new Thread(new Runnable(){

		@Override
            	public void run() {
                	// これは別スレッド上での処理(一度IO待ちを入れないと駄目みたい・・100ミリ以下は駄目だった・・)
                	try {
        	       		if( "MOTO".equals(Build.BRAND) && "MZ604".equals(Build.MODEL) ){
                			Thread.sleep(1000);
            	        	}
            	        	else{
					//Splashをちゃんと表示させたいなら最低500msは必要かも
					//時間かかるときだけの認識なら100msでOK
					Thread.sleep(500);
            	        	}
                	} catch (InterruptedException ignore) {}
                
        		activity.runOnUiThread(new Runnable(){
                    		@Override
                    		public void run() {
                    			onCreateAction();
                    		}
        		});
            	}
        }).start();
}

参考)



追記2)

応用編としてViewStubの画像、layout_width/layout_heightを変更することは可能
基本B)で動的にA)にも変更したい場合

setContentView(R.layout.start);

ViewStub stub = (ViewStub)findViewById(R.id.start);
stub.setLayoutResource(R.layout.start_img);
View v = stub.inflate();

//後から差し替え
TypedArray id_arr = m_r.obtainTypedArray(R.array.splash_type);
int no = Math.random() * id_arr.length();
final int res_id = id_arr.getResourceId(no, -1);
id_arr.recycle();

if(res_id!=-1)
	//backgroundの差替
	v.setBackgroundResource(res_id); 
	//全画面にレイアウトを拡大
	v.setLayoutParams(new FrameLayout.LayoutParams(
	LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
}

ViewStubは内部的にはFrameLayout扱いのようだ

リソースの扱いは

の話と同じ



追記3)

infrateされるViewにanimation-listを設定してアニメーション等も可能*2
ちなみに

  • new Handler().post
  • new Handler(getMainLooper()).post

を使うとANRでやすいよう<newのコストが重いのかなー(汗

setContentView(R.layout.start);

ViewStub stub = (ViewStub)findViewById(R.id.start);
stub.setLayoutResource(R.layout.start_img);
View iv = stub.inflate();

//animation-list をセット
iv.setBackgroundResource(R.drawable.flag);

final AnimationDrawable anim = (AnimationDrawable) iv.getBackground();

//[TODO]遅延させたいなら postDelayedも有る		
iv.post(new Runnable() {
	public void run() {
		anim.start();
	}
});
  • drawable/flag.xml
<?xml version="1.0" encoding="utf-8"?>
<animation-list 	
	xmlns:android="http://schemas.android.com/apk/res/android" 
	android:oneshot="false"
	>
    <item android:drawable="@drawable/f01" android:duration="100" />
    <item android:drawable="@drawable/f02" android:duration="100" />
    <item android:drawable="@drawable/f03" android:duration="100" />
    <item android:drawable="@drawable/f04" android:duration="100" />
    <item android:drawable="@drawable/f05" android:duration="100" />
    <item android:drawable="@drawable/f07" android:duration="100" />
</animation-list>

参考)

この例だとImageViewつかってるんだけど、
Viewの基本クラスの関数なのでImageViewである必要もないんですよね。。

*1:有り得そうなのが setContentViewが既に別のものに変更されている時とか

*2:でもこれってGN起動時のパラパラアニメ手法みたいですね<汗