DialogFragmentのレイアウトをxmlレイアウトファイルで指定し(layout_mydialogfragment.xml
と呼びましょう)、特にそのlayout_width
およびlayout_height
属性を指定します(それぞれ100dp
としましょう)。次に、DialogFragmentのonCreateView(...)
メソッドでこのレイアウトを次のように拡張します。
View view = inflater.inflate(R.layout.layout_mydialogfragment, container, false);
残念ながら、ダイアログ(DialogFragment)が表示されると、xmlレイアウトファイルで指定されているlayout_width
およびlayout_height
を尊重しません(そして、コンテンツに応じてダイアログが縮小または拡大します)。 xmlレイアウトファイルで指定されているlayout_width
とlayout_height
を尊重するようにダイアログを取得できるかどうか、またはどのように取得できるかは誰でも知っていますか?現時点では、DialogFragmentのonResume()
メソッドでダイアログの幅と高さを次のように再度指定する必要があります...
getDialog().getWindow().setLayout(width, height);
...したがって、望ましくないことに、ダイアログの幅と高さを今後2か所変更する必要があります。
リソース値から直接変換する場合:
int width = getResources().getDimensionPixelSize(R.dimen.popup_width);
int height = getResources().getDimensionPixelSize(R.dimen.popup_height);
getDialog().getWindow().setLayout(width, height);
次に、ダイアログのレイアウトでmatch_parentを指定します。
Android:layout_width="match_parent"
Android:layout_height="match_parent"
心配する必要があるのは1か所だけです(DialogFragment#onResume
に配置します)。完全ではありませんが、少なくとも、ダイアログのレイアウトファイルのルートとしてRelativeLayoutを使用する場合には機能します。
最終的にFragment.onResume()
をオーバーライドし、基になるダイアログから属性を取得し、そこで幅/高さのパラメーターを設定しました。一番外側のレイアウトの高さ/幅をmatch_parent
に設定します。このコードは、xmlレイアウトで定義したマージンも尊重しているようです。
@Override
public void onResume() {
super.onResume();
ViewGroup.LayoutParams params = getDialog().getWindow().getAttributes();
params.width = LayoutParams.MATCH_PARENT;
params.height = LayoutParams.MATCH_PARENT;
getDialog().getWindow().setAttributes((Android.view.WindowManager.LayoutParams) params);
}
XMLメインレイアウト(私の場合はLinearLayout)で以下を定義する固定サイズのDialogFragmentを取得しました。
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:minWidth="1000dp"
Android:minHeight="450dp"
私の場合に働いた唯一のことは、ここで指摘された解決策でした: http://adilatwork.blogspot.mx/2012/11/Android-dialogfragment-dialog-sizing.html
Adilブログ投稿のスニペット:
@Override
public void onStart()
{
super.onStart();
// safety check
if (getDialog() == null)
return;
int dialogWidth = ... // specify a value here
int dialogHeight = ... // specify a value here
getDialog().getWindow().setLayout(dialogWidth, dialogHeight);
// ... other stuff you want to do in your onStart() method
}
DialogFragment
の幅と高さを制御する1つの方法は、値がWRAP_CONTENT
の場合、ダイアログがビューの幅と高さを尊重するようにすることです。
ThemeOverlay.AppCompat.Dialog
を使用するこれを実現する簡単な方法の1つは、Androidサポートライブラリに含まれているThemeOverlay.AppCompat.Dialog
スタイルを使用することです。
DialogFragment
with Dialog
:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
dialog.setContentView(view);
return dialog;
}
DialogFragment
with AlertDialog
(注意:minHeight="48dp"
):
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.ThemeOverlay_AppCompat_Dialog);
builder.setView(view);
return builder.create();
}
ダイアログを作成するときに、アプリのxmlテーマに追加することで、ThemeOverlay.AppCompat.Dialog
をデフォルトのテーマとして設定することもできます。
多くのダイアログでは見栄えを良くするためにデフォルトの最小幅が必要なので注意してください。
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- For Android Dialog. -->
<item name="Android:dialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- For Android AlertDialog. -->
<item name="Android:alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- For AppCompat AlertDialog. -->
<item name="alertDialogTheme">@style/ThemeOverlay.AppCompat.Dialog</item>
<!-- Other attributes. -->
</style>
DialogFragment
とDialog
、Android:dialogTheme
:を使用して
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext());
dialog.setContentView(view);
return dialog;
}
DialogFragment
とAlertDialog
、Android:alertDialogTheme
またはalertDialogTheme
を使用(注意:minHeight="48dp"
):
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
AlertDialog.Builder builder = new AlertDialog.Builder(getContext());
builder.setView(view);
return builder.create();
}
古いAndroid APIでは、Dialog
sにはタイトルが設定されていなくても、幅の問題があるようです。ThemeOverlay.AppCompat.Dialog
スタイルを使用したくない場合で、Dialog
にタイトルが必要ない(またはカスタムのタイトルがある)場合は、無効にすることができます。
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
LayoutInflater inflater = LayoutInflater.from(getContext());
View view = inflater.inflate(R.layout.dialog_view, null);
Dialog dialog = new Dialog(getContext());
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(view);
return dialog;
}
プログラムで固定サイズを指定せずに、ダイアログがレイアウトの幅と高さを尊重するようにしました。
Android:windowMinWidthMinor
とAndroid:windowMinWidthMajor
が問題を引き起こしていると考えました。 Activity
またはDialog
のテーマには含まれていませんでしたが、それらはまだActivity
テーマに適用されていました。
私は3つの可能な解決策を思いつきました。
解決策1:カスタムダイアログテーマを作成し、DialogFragment
でダイアログを作成するときに使用します。
<style name="Theme.Material.Light.Dialog.NoMinWidth" parent="Android:Theme.Material.Light.Dialog">
<item name="Android:windowMinWidthMinor">0dip</item>
<item name="Android:windowMinWidthMajor">0dip</item>
</style>
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(getActivity(), R.style.Theme_Material_Light_Dialog_NoMinWidth);
}
解決策2:ダイアログのContextThemeWrapper
として機能するContext
で使用されるカスタムテーマを作成します。カスタムダイアログテーマを作成しない場合(たとえば、Android:dialogTheme
で指定されたテーマを使用する場合)に使用します。
<style name="Theme.Window.NoMinWidth" parent="">
<item name="Android:windowMinWidthMinor">0dip</item>
<item name="Android:windowMinWidthMajor">0dip</item>
</style>
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new Dialog(new ContextThemeWrapper(getActivity(), R.style.Theme_Window_NoMinWidth), getTheme());
}
ソリューション3(AlertDialog
を使用):Android:windowMinWidthMinor
およびAndroid:windowMinWidthMajor
をAlertDialog$Builder
によって作成されたContextThemeWrapper
に適用します。
<style name="Theme.Window.NoMinWidth" parent="">
<item name="Android:windowMinWidthMinor">0dip</item>
<item name="Android:windowMinWidthMajor">0dip</item>
</style>
@Override
public final Dialog onCreateDialog(Bundle savedInstanceState) {
View view = new View(); // Inflate your view here.
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder.setView(view);
// Make sure the dialog width works as WRAP_CONTENT.
builder.getContext().getTheme().applyStyle(R.style.Theme_Window_NoMinWidth, true);
return builder.create();
}
DialogFragment
レイアウトそれは本当に麻痺しているようなものです。
DialogFragment
を作成するときに、onCreateView
(.xmlレイアウトをアタッチするためにViewGroup
を渡す)またはonCreateDialog
をオーバーライドすることを選択できます。
両方のメソッドをオーバーライドしないでください。ダイアログのレイアウトがいつ膨らんだか、または膨らんだかどうかについてAndroidを混同する可能性が非常に高いからです。 WTF?
OnCreateDialog
またはOnCreateView
をオーバーライドするかどうかの選択は、ダイアログの使用方法によって異なります。
OnCreateDialog
をオーバーライドすることが期待されます。OnCreateView
をオーバーライドする必要があります。これはおそらく世界で最悪のことです。
onCreateDialog
狂気したがって、onCreateDialog
内のDialogFragment
をオーバーライドして、ウィンドウに表示するAlertDialog
のカスタマイズされたインスタンスを作成します。クール。ただし、onCreateDialog
は、カスタム.xmlレイアウトtoを添付するViewGroup
を受け取らないことに注意してください。問題ありません。単にnull
をinflate
メソッドに渡すだけです。
狂気を始めましょう。
onCreateDialog
をオーバーライドすると、Android COMPLETELY IGNORES展開する.xmlレイアウトのルートノードのいくつかの属性。これには以下が含まれますが、おそらくこれに限定されません:
background_color
layout_gravity
layout_width
layout_height
これはほとんど滑comicです。すべての.xmlレイアウトの
layout_width
およびlayout_height
を設定する必要があるか、Android Studioが恥ずかしい素敵な小さな赤いバッジであなたを平手打ちします。
WordDialogFragment
だけで私はukeりたくなる。 Androidの落とし穴とスナフスで満たされた小説を書くこともできますが、これは最も内部的なものの1つです。
正気に戻るには、まず、期待するbackground_color
とlayout_gravity
を復元するスタイルを宣言します。
<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
<item name="Android:windowBackground">@Android:color/transparent</item>
<item name="Android:layout_gravity">center</item>
</style>
上記のスタイルは、Dialogsのベーステーマ(この例ではAppCompat
テーマ)から継承します。
次に、スタイルをプログラムで適用して、単に捨てられた値Androidを元に戻し、標準のAlertDialog
のルックアンドフィールを復元します。
public class MyDialog extends DialogFragment {
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
View layout = getActivity().getLayoutInflater().inflate(R.layout.my_dialog_layout, null, false);
assert layout != null;
//build the alert dialog child of this fragment
AlertDialog.Builder b = new AlertDialog.Builder(getActivity());
//restore the background_color and layout_gravity that Android strips
b.getContext().getTheme().applyStyle(R.style.MyAlertDialog, true);
b.setView(layout);
return b.create();
}
}
上記のコードはAlertDialog
を再びAlertDialog
のように見せます。たぶんこれで十分でしょう。
表示されているときにAlertDialog
にSPECIFIClayout_width
またはlayout_height
を設定することを検討している場合(可能性が高い)、何をしたかはまだわかりません!
ファンシーな新しいスタイルで特定のlayout_width
またはlayout_height
を設定しようとすると、Androidもそれを完全に無視することに気づいたとき、喜びは続きます!:
<style name="MyAlertDialog" parent="Theme.AppCompat.Dialog">
<item name="Android:windowBackground">@Android:color/transparent</item>
<item name="Android:layout_gravity">center</item>
<!-- NOPE!!!!! --->
<item name="Android:layout_width">200dp</item>
<!-- NOPE!!!!! --->
<item name="Android:layout_height">200dp</item>
</style>
SPECIFICウィンドウの幅または高さを設定するには、 'nutherメソッド全体に進み、LayoutParams
を処理します。
@Override
public void onResume() {
super.onResume();
Window window = getDialog().getWindow();
if(window == null) return;
WindowManager.LayoutParams params = window.getAttributes();
params.width = 400;
params.height = 400;
window.setAttributes(params);
}
多くの人は、
WindowManager.LayoutParams
をより一般的なViewGroup.LayoutParams
にキャストするというAndroidの悪い例に従っていますが、数回後にViewGroup.LayoutParams
をWindowManager.LayoutParams
に戻すだけです。効果的なJavaは、コードを解読するのをさらに難しくする以外に、不必要なキャストが何も提供しないことを気にかけられます。サイドノート:Android SDK全体で
LayoutParams
が20回繰り返されています-根本的に貧弱なデザインの完璧な例です。
DialogFragment
をオーバーライドするonCreateDialog
sの場合:
AlertDialog
ルックアンドフィールを復元するには、background_color
= transparent
およびlayout_gravity
= center
を設定するスタイルを作成し、そのスタイルをonCreateDialog
に適用します。layout_width
および/またはlayout_height
を設定するには、プログラムでonResume
をLayoutParams
に設定しますDialogFragmentを少し広くする必要がある場合、minWidthを設定します。
<LinearLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:minWidth="320dp"
... />
一番外側のレイアウトの寸法は、ダイアログでは機能しません。寸法を最も外側に設定するレイアウトを追加できます。
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<LinearLayout
Android:layout_width="xxdp"
Android:layout_height="xxdp"
Android:orientation="vertical">
</LinearLayout>
以下は、xmlでDialogFragmentの幅/高さを設定する方法です。 viewHierarchyを透明な背景を持つFramelayout(任意のレイアウトが機能します)でラップするだけです。
透明な背景は特別なフラグのようです。これを行うと、frameLayoutの子がウィンドウの中央に自動的に配置されるためです。フラグメントの背後にある全画面が暗くなり、フラグメントがアクティブな要素であることを示します。
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@color/transparent">
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="300dp"
Android:background="@color/background_material_light">
.....
ルート要素のレイアウトパラメーターの設定を修正しました。
int width = activity.getResources().getDisplayMetrics().widthPixels;
int height = activity.getResources().getDisplayMetrics().heightPixels;
content.setLayoutParams(new LinearLayout.LayoutParams(width, height));
onResume
のonStart
内のWindow
の幅と高さを設定するためにDialogFragment
またはDialog
をオーバーライドする説得力のある理由はありません-これらの特定のライフサイクルメソッドは繰り返し呼び出され、マルチウィンドウなどの理由でコードを複数回不必要に実行する可能性があります切り替え、バックグラウンド化、アプリのフォアグラウンド化など。その繰り返しの結果はかなり些細なことですが、なぜそれで落ち着くのでしょうか?
オーバーライドされたonActivityCreated()
メソッド内で代わりにwidth/heightを設定すると、このメソッドは実際にはDialogFragment
のインスタンスごとに1回しか呼び出されないため、改善されます。例えば:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
Window window = getDialog().getWindow();
assert window != null;
WindowManager.LayoutParams layoutParams = window.getAttributes();
layoutParams.width = ViewGroup.LayoutParams.MATCH_PARENT;
window.setAttributes(layoutParams);
}
上記では、デバイスの向きに関係なく、幅をmatch_parent
に設定しています。ランドスケープダイアログをそれほど広くしたくない場合は、事前にgetResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT
かどうかを確認できます。
幅にパーセンテージを使用できます。
<style name="Theme.Holo.Dialog.MinWidth">
<item name="Android:windowMinWidthMajor">70%</item>
この例では、Holoテーマを使用しました。
以下のコードで、Javaからレイアウトの幅と高さを設定できます。
final AlertDialog alertDialog = alertDialogBuilder.create();
final WindowManager.LayoutParams WMLP = alertDialog.getWindow().getAttributes();
WMLP.gravity = Gravity.TOP;
WMLP.y = mActionBarHeight;
WMLP.x = getResources().getDimensionPixelSize(R.dimen.unknown_image_width);
alertDialog.getWindow().setAttributes(WMLP);
alertDialog.show();
AlertDialog.Builderを使用してダイアログを作成するため、OnShowListener内でRodrigoの回答を使用しました。
dialog.setOnShowListener(new OnShowListener() {
@Override
public void onShow(DialogInterface dialogInterface) {
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics outMetrics = new DisplayMetrics ();
display.getMetrics(outMetrics);
dialog.getWindow().setLayout((int)(312 * outMetrics.density), (int)(436 * outMetrics.density));
}
});
Android 6.0で作業中に、同じ問題が発生しました。 AlertDialog
は、カスタムビューのルートwidth
に設定されている実際のwidth
に関係なく、テーマに設定されている事前定義済みLayout
にデフォルト設定されます。 loading_message
width
のTextView
を適切に調整して設定することができました。さらに調査することなく、実際の要素のサイズを決定し、ルートLayout
でそれらをラップすると、期待どおりに動作するようです。以下は、ダイアログのwidth
を正しく設定する読み込みダイアログのXMLレイアウトです。アニメーションに このライブラリ を使用します。
<RelativeLayout
xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:background="@color/custom_color"
Android:padding="@dimen/custom_dimen">
<com.github.rahatarmanahmed.cpv.CircularProgressView
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:id="@+id/progress_view"
Android:layout_width="40dp"
Android:layout_height="40dp"
Android:layout_centerHorizontal="true"
app:cpv_color="@color/white"
app:cpv_animAutostart="true"
app:cpv_indeterminate="true" />
<TextView
Android:id="@+id/loading_message"
Android:layout_width="100dp"
Android:layout_height="wrap_content"
Android:layout_below="@+id/progress_view"
Android:layout_centerHorizontal="true"
Android:gravity="center"
Android:textSize="18dp"
Android:layout_marginTop="@dimen/custom_dimen"
Android:textColor="@color/white"
Android:text="@string/custom_string"/>
</RelativeLayout>
カスタムダイアログレイアウトの親レイアウトをRelativeLayoutに設定し、共通の幅と高さを自動的に取得します。
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
簡単で堅牢:
@Override
public void onResume() {
// Sets the height and the width of the DialogFragment
int width = ConstraintLayout.LayoutParams.MATCH_PARENT;
int height = ConstraintLayout.LayoutParams.MATCH_PARENT;
getDialog().getWindow().setLayout(width, height);
super.onResume();
}
私が見つけた最良の解決策は、onCreateDialog()
ではなくonCreateView()
をオーバーライドすることです。 setContentView()は、膨張する前に正しいウィンドウサイズを設定します。リソースファイルに寸法、背景色、スタイルなどを保存/設定し、手動で設定する必要がなくなります。
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
Dialog dialog = new Dialog(getActivity());
dialog.setContentView(R.layout.fragment_dialog);
Button button = (Button) dialog.findViewById(R.id.dialog_button);
// ...
return dialog;
}
私の場合、RelativeLayout
内のビューに与えられたalign_parentBottom="true"
が原因でした。すべてのalignParentBottomを削除し、すべてのレイアウトを垂直のLinearLayoutsに変更し、問題はなくなりました。
FragmentDialog
に追加:
public void onResume() {
Window window = getDialog().getWindow();
Point size = new Point();
Display display = window.getWindowManager().getDefaultDisplay();
display.getSize(size);
window.setLayout( (int)(size.x * 0.9), WindowManager.LayoutParams.WRAP_CONTENT );
window.setGravity( Gravity.CENTER );
super.onResume();
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null)
{
dialog.getWindow().setLayout(-1, -2);
dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
Window window = getDialog().getWindow();
WindowManager.LayoutParams params = window.getAttributes();
params.dimAmount = 1.0f;
window.setAttributes(params);
window.setBackgroundDrawableResource(Android.R.color.transparent);
}
}
以前のソリューションの1つはほとんど機能しました。私は少し違うことを試してみましたが、それは私のために働いてしまいました。
(必ず彼のソリューションを見てください)これは彼のソリューションでした.. ここをクリック 次を除いて機能しました:builder.getContext()。getTheme()。applyStyle(R.style.Theme_Window_NoMinWidth、 true);
に変更しました
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
// Use the Builder class for convenient dialog construction
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get layout inflater
LayoutInflater layoutInflater = getActivity().getLayoutInflater();
// Set layout by setting view that is returned from inflating the XML layout
builder.setView(layoutInflater.inflate(R.layout.dialog_window_layout, null));
AlertDialog dialog = builder.create();
dialog.getContext().setTheme(R.style.Theme_Window_NoMinWidth);
最後の行は、本当に違うものです。