読者です 読者をやめる 読者になる 読者になる

AndroidでIOSと同じようなダイアログを表示する

自分が参照しづらいのでエントリ分割)
元エントリは


一番よくあるのは Dialogの見た目を一致させたいという話が

な話はあるけど、こっちはうまくいかないorz
外枠が変にのこっちゃんだよね‥‥

  • AndroidManifest.xml
        <activity android:theme="@style/my_activity_theme"
  • values/style.xml
    <style name="my_activity_theme" parent="@android:style/Theme">  
        <item name="android:alertDialogStyle">@style/AlertDialog</item>  
    </style>
    
   <style name="AlertDialog">  
    	<item name="android:windowNoTitle">true</item>  
    	<item name="android:colorBackground">@null</item>
<!--
    	<item name="android:windowBackground">@android:color/transparent</item>  
-->
    </style>
<item name="android:colorBackground">@null</item>

の指定は 背景塗りつぶさない指定*1


コード自体は下記みたいに頑張ってみたんですけどね(汗

    	View layout = getLayoutInflater().inflate(R.layout.dialog, null);
    	final AlertDialog al = new AlertDialog.Builder( this ).
		setCancelable(false).
		setView(layout).
		create();
		
       //show前はinfrateするレイアウト経由でアクセス
    	TextView tx_title = (TextView) layout.findViewById(R.id.title);
    	tx_title.setText("");
    	TextView tx = (TextView) layout.findViewById(R.id.body);
    	tx.setText(R.string.default_txt);

    	Button btn = (Button) layout.findViewById(R.id.ok);
    	btn.setOnClickListener(new	View.OnClickListener(){
			public	void onClick(View v )
			{
				al.dismiss();
			}
		});


	//別の場所でshow
        al.show();
		
        //show後は下記のようにアクセス
	TextView tx_aft = (TextView)al.findViewById(R.id.body);
	tx_aft.setText("hogehoge");


Dialogクラスで頑張るって方針はなんとか動かしたことはある

  • values/style.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <style  
	    name="Theme.CustomProgressDialog"  
	    parent="android:style/Theme.Dialog">  
    	  
    	<item name="android:windowNoTitle">true</item>  
    	<item name="android:windowBackground">@android:color/transparent</item>  
    </style>   
</resources>
  • layout/dialog.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:background="@drawable/ios_dialog_back"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

<!-- //〜略〜 -->

</LinearLayout>
Dialog mDialog = null;

if(mDialog!=null){
	try{
		mDialog.dismiss();
	}catch(Exception ex){mDialog.cancel();}
	mDialog = null;
}

mDialog = new Dialog(this, R.style.Theme_CustomProgressDialog);
mDialog.setContentView(R.layout.dialog);


mDialog.setOnKeyListener(new OnKeyListener() { 
	@Override 
	public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent e) {	
		if(e.getKeyCode() != KeyEvent.KEYCODE_BACK) return false;
		if(e.getAction() != KeyEvent.ACTION_DOWN)return false;
		mDialog.cancel();
		mDialog = null;
		return false; 
	}
});


TextView tx_title = (TextView) mDialog.findViewById(R.id.title);
tx_title.setText("");
TextView tx = (TextView) mDialog.findViewById(R.id.body);
tx.setText(R.string.default_txt);

Button btn = (Button) mDialog.findViewById(R.id.ok);
btn.setOnClickListener(new	View.OnClickListener(){
	public	void onClick(View v )
	{
		try{
			mDialog.dismiss();
		}catch(Exception ex){mDialog.cancel();}
		mDialog = null;
	}
});

mDialog.show();


ProgressDialogもIOSに似せて! という話でチャレンジしてみたら、以下な感じ

http://twitter.com/bina1204/status/291125702214963200:twitter:detail:right

ProgressDialog	mDialog = new ProgressDialog(addContext, R.style.Theme_CustomProgressDialog);
mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mDialog.setCancelable(true);

mDialog.setIndeterminate(true);
mDialog.show();

//show後にレイアウトを上書き
mDialog.setContentView(R.layout.dialog);
mDialog.setOnKeyListener(new OnKeyListener() { 
	@Override 
	public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent e) {	
		if(e.getKeyCode() != KeyEvent.KEYCODE_BACK) return false;
		if(e.getAction() != KeyEvent.ACTION_DOWN)return false;
		mDialog.cancel();
		mDialog = null;
		return false; 
	}
});


TextView tx_title = (TextView) mDialog.findViewById(R.id.title);
tx_title.setText("");
TextView tx = (TextView) mDialog.findViewById(R.id.body);
tx.setText(R.string.default_txt);

Button btn = (Button) mDialog.findViewById(R.id.ok);
btn.setOnClickListener(new	View.OnClickListener(){
	public	void onClick(View v )
	{
		try{
			mDialog.dismiss();
		}catch(Exception ex){mDialog.cancel();}
		mDialog = null;
	}
});

でよくあるパターンで IOSっぽいダイアログ背景画像を高解像度の奴しか渡されない時
自分でサイズ調整しないとダイアログが画像に引っ張られて間延びすると。。(汗

ProgressDialogの方は
setContentView以降に設定してねの感じ・・

	Resources m_r = getResource();
	DisplayMetrics metrics = m_r.getDisplayMetrics();  
	int dialogWidth = (int) (metrics.widthPixels * 0.9);  

	int dlg_height_p = 80;//m_r.getInteger(R.integer.dlg_height_p);
	if("KDDI".equals(Build.BRAND) && "IS03".equals(Build.MODEL))dlg_height_p += 5;

	int dialogHeight = (int) (metrics.heightPixels * dlg_height_p * 1/100);  

	WindowManager.LayoutParams lp = mDialog.getWindow().getAttributes();  
	lp.width = dialogWidth;  
	lp.height =dialogHeight;
	mDialog.getWindow().setAttributes(lp);  

 ココらへんのお話と同じ対応なわけだけど

プログラムでサイズ補正ってもんによりしちゃうかな‥‥

 通常は

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
	android:background="@drawable/dialog_ios"
	android:orientation="vertical"
	android:layout_width="wrap_content"     //☆
	android:layout_height="wrap_content"> //☆

の ☆の 指定でうまく自動計算するはずなので
余程のものでなければ上記のレイアウト任せで諦める
という手はありますが。。*2


 だからといってdimens.xml地獄も厳しいわけですし。
一番理想はアニメパターンみたいにlayout.xmlのwidth等に


10%p
10% 
みたいな指定ができるといいんですけどね

ちなみにWindowsみたいにダイアログをモードレスダイアログにしたいという要望があったりする
その場合は

	Window window = mDialog.getWindow();
	window.setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL,
                WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
	window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
	mDialog.show();  

な対応が必要。

あたりを参照してる*3

ただ本来Androidじゃモーダルではないらしい

備考)
AlertDialog系のDialog設定は



IOSのAlertみたいに表示中は背景を半透明黒にしたい場合)
これはActivityの場合の対処メモ

ようは某社さんの全画面広告で、背景を黒半透明にしたいみたいな要望があったわけで・・(汗
企画の方は IOSベースで考えるから IOSと似たような表示にならないと違和感感じるんだろうな。。。というお話
で、実際の対処

の2番めを使う

  • res/style.xml
<style name="Theme.DimPanel" parent = "@android:style/Theme.Panel">
	<item name="android:windowBackground">@android:color/transparent</item>
	<item name="android:backgroundDimEnabled">true</item>
	<item name="android:backgroundDimAmount">0.5</item>
</style>
  • AndroidManifest.xml
<activity
	android:name="jp.basicinc.gamefeat.android.sdk.view.GameFeatPopupActivity"
	android:configChanges="orientation|keyboardHidden"
	android:theme="@style/Theme.DimPanel"
	android:label="GameFeat" />
<!-- 
	android:theme="@android:style/Theme.Translucent.NoTitleBar"
 -->

類似>

*1:LinerLayoutで background="@null" と同じ感じ?

*2:でも拘られるとリリースできないorz

*3:ダイアログを出していると、後ろの広告(Ad)が押せないって話の対応