[android] DialogFragment의 너비와 높이를 설정하는 방법은 무엇입니까?

XML 레이아웃 파일 (이라고 부르 자)에서 DialogFragment의 레이아웃을 지정 layout_mydialogfragment.xml하고 그 속성 layout_widthlayout_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);

… 따라서 대화 상자의 너비와 높이를 두 곳에서 변경해야한다는 점을 기억해야합니다.



답변

자원 값에서 직접 변환하는 경우 :

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"

한 곳만 걱정하면됩니다 (에 배치 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너비와 높이 를 제어하는 ​​한 가지 방법 은 값이 인 경우 대화 상자가보기의 너비와 높이를 존중하도록하는 것입니다 WRAP_CONTENT.

사용 ThemeOverlay.AppCompat.Dialog

이를 달성하는 간단한 방법 중 하나 ThemeOverlay.AppCompat.Dialog는 Android 지원 라이브러리에 포함 된 스타일을 사용하는 것 입니다.

DialogFragmentDialog:

@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;
}

DialogFragmentAlertDialog(주의 : 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();
}

ThemeOverlay.AppCompat.Dialog대화 상자를 만들 때 앱의 xml 테마에 대화 상자를 추가하여 기본 테마로 설정할 수도 있습니다 .
많은 대화 상자가 제대로 보이도록 기본 최소 너비가 필요하므로주의하십시오.

<!-- 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>

DialogFragmentDialog의 사용을 만드는 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제목으로 인해 너비 문제가있는 것 같습니다 (설정하지 않은 경우에도). 스타일
을 사용 하지 않고 제목이 필요하지 않은 경우 (또는 사용자 지정 제목이있는 경우) 비활성화 할 수 있습니다.ThemeOverlay.AppCompat.DialogDialog

@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주제 에 적용되고있었습니다 .

나는 세 가지 가능한 해결책을 생각해 냈습니다.

해결 방법 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());
}

(AN과 해결책 3 AlertDialog) 적용 android:windowMinWidthMinorandroid:windowMinWidthMajorContextThemeWrapper의해 생성 AlertDialog$Builder.

<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();
}


답변

문제 # 13 : DialogFragment레이아웃

정말 정신 마비입니다.

을 만들 때 ( .xml 레이아웃을 첨부하기 위해 a 를 전달 ) 또는 DialogFragment을 무시하도록 선택할 수 있습니다 .onCreateViewViewGrouponCreateDialog

대화 상자의 레이아웃이 언제 팽창했는지에 대해 안드로이드를 혼동시킬 수 있기 때문에 두 가지 방법을 모두 무시해서는 안됩니다! WTF?

재정의 여부 OnCreateDialog또는 OnCreateView대화 상자 사용 방법에 따라 선택합니다 .

  • 대화 상자를 창에서 시작하면 (정상적인 동작) 재정의해야 OnCreateDialog합니다.
  • 기존 UI 레이아웃 내에 대화 상자 조각을 포함 시키려면 (FAR이 덜 일반적 임)을 재정의해야 OnCreateView합니다.

이것은 아마도 세상에서 최악의 일입니다.

onCreateDialog 광기

그래서, 당신은 무시하고 onCreateDialog당신에 DialogFragment의 사용자 인스턴스를 생성 AlertDialog창에 표시합니다. 멋있는. 그러나 사용자 지정 .xml 레이아웃 에 첨부 onCreateDialog하지 ViewGroup마십시오 . 문제 없습니다 . 단순히 메소드에 전달 합니다 .nullinflate

광기가 시작하자.

을 재정의 onCreateDialog하면 Android가 팽창 한 .xml 레이아웃의 루트 노드에 대한 여러 속성을 완전히 무시 합니다. 여기에는 다음이 포함되지만 이에 국한되지는 않습니다.

  • background_color
  • layout_gravity
  • layout_width
  • layout_height

당신은 설정해야합니다 이것은 거의 코믹입니다 layout_widthlayout_height수치의 좋은 작은 빨간 배지 당신을 때릴 것 EVERY .XML 레이아웃 또는 안드로이드 스튜디오.

단어 만으로 DialogFragment말하고 싶어요 나는 안드로이드 gotchas와 snafus로 가득 찬 소설을 쓸 수 있지만, 이것은 가장 내부적 인 것 중 하나입니다.

정신 건강으로 돌아가려면 먼저 우리는 단지 복원 할 스타일을 선언 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();
    }
}

위의 코드 AlertDialogAlertDialog다시 처럼 보이게 합니다. 아마도 이것으로 충분할 것입니다.

그러나 더 많은 것이 있습니다!

SPECIFIC 을 설정 layout_width하거나 layout_height표시 AlertDialog될 때 (매우 가능성이 높은) 것을 찾고 있다면 , 아직 완료하지 않은 것을 추측하십시오!

특정 스타일 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>

특정 창 너비 또는 높이를 설정하려면 전체 ‘너머 방법으로 넘어 가서 다음을 처리하십시오 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캐스팅하고 나중에 ViewGroup.LayoutParams다시 WindowManager.LayoutParams몇 줄로 다시 캐스팅 합니다. 코드를 해독하기 어렵게 만드는 것 외에는 불필요한 캐스팅으로 아무것도 제공하지 않습니다.

참고 사항 : LayoutParams근본적으로 열악한 디자인의 완벽한 예 인 Android SDK 전체에서 몇 차례의 반복이 있습니다.

요약해서 말하자면

의 경우는 DialogFragment그 재정이야 onCreateDialog:

  • 표준 AlertDialog모양과 느낌 을 복원하려면 background_color= transparentlayout_gravity= 를 설정 center하고에 해당 스타일을 적용하는 스타일을 onCreateDialog만듭니다.
  • 특정를 설정하려면 layout_width및 / 또는 layout_height,에서 프로그래밍을 할 수 onResumeLayoutParams
  • 건전성을 유지하려면 Android SDK에 대해 생각하지 마십시오.

답변

DialogFragment를 조금 더 넓게 만들어야 할 때 minWidth를 설정합니다.

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:minWidth="320dp"
    ... />