material-dialogsでMaterial Designっぽくないダイアログを作る

2017/01/11

AndroidでMaterial Design準拠のダイアログをさくっと作れるライブラリがMaterial Dialogs

DialogFragmentは扱いが厄介なのでダイアログ周りはライブラリに任せることが個人的には多いです。そんな中でもMaterial Dialogsは重宝していて出番が多いのですが、見た目を弄ろうとしてちょっとハマりました。

どうもMaterial DialogsはMaterial Designに準拠するポリシーらしく、Material Designから外れた変更は難しいようです。Material Designの範囲内なら見た目のカスタマイズ性は高いのですが。

今回やってみたのは

  • ダイアログを四角以外の形にする
  • 背景を透明にする
  • 幅や高さを変える

です。この3つができればたいていのDialogは作れるんじゃないでしょうか。

ダイアログを四角以外の形にする

CustomViewを渡せるので描画はそこで頑張るとして、標準で描画される外枠をどうやって消すかがポイントです。 スマートなやり方が見つけられなくて、泥臭いworkaroundになっちゃいました。

@SuppressWarnings("ConstantConditions")
View v = dialog.getWindow().getDecorView();
v.setBackground(new ColorDrawable(Color.TRANSPARENT));

ViewGroup viewGroup = (ViewGroup) v;

for (int i = 0; i < viewGroup.getChildCount(); i++) {
    viewGroup.getChildAt(i).setBackground(new ColorDrawable(Color.TRANSPARENT));
}

v.findViewById(android.R.id.content).setBackground(new ColorDrawable(Color.TRANSPARENT));
v.findViewById(R.id.md_root).setBackground(new ColorDrawable(Color.TRANSPARENT));

背景を透明にする

Material Dialogsのissueで幾度となく要望が上がり、そのたびに「Material Designに準拠しない要望は取り込まない」という理由で却下されています。

そんな中、need transparent background · Issue #598 · afollestad/material-dialogsでworkaroundが提示されていました。

MaterialDialog dialog = new MaterialDialog.Builder(getContext()..content(R.string.content).build();

// make dialog itself transparent
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

// remove background dim
dialog.getWindow().setDimAmount(0);
dialog.show();

幅や高さを変える

これはMaterial Dialogsに限った話じゃないですね。@yanzmさんの記事が参考になりました。

Y.A.M の 雑記帳: Android DialogFragment では Dialog のサイズ指定は onActivityCreated でやれ

Dialogに対して直接高さや幅を指定すればOKです。高さも幅も画面サイズの50%のダイアログにするにはこんな感じ。

Dialog dialog = getDialog();  

WindowManager.LayoutParams lp = dialog.getWindow().getAttributes();  

DisplayMetrics metrics = getResources().getDisplayMetrics();  
int dialogWidth = (int) (metrics.widthPixels * 0.5);  
int dialogHeight = (int) (metrics.heightPixels * 0.5);  

lp.width = dialogWidth;  
lp.height = dialogHeight;  
dialog.getWindow().setAttributes(lp);  

どれも力業感が漂ってますが、ときには必要、ということで。




関連(するかもしれない)記事


おススメ