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
参考にした処)
- Android ViewStubを用いたapiキーの切り替え | Taosoftware Developer Blog
- Androyer in Japan: 実験:ViewStubはViewの動的挿入に使えるか
追記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である必要もないんですよね。。