DialogFragment не изменяет размер, когда отображается клавиатура

Я пытаюсь использовать SherlockDialogFragment для запроса ввода от пользователя. Все работает отлично на моем телефоне (Galaxy Nexus, 4.2), но на меньшем телефоне (эмулятор 2.3.3), когда появляется клавиатура, он закрывает две кнопки диалогового окна "Диалог", например:

dialog covered by keyboard

Мой макет находится внутри ScrollView, и я меняю softInputMode на SOFT_INPUT_ADJUST_RESIZE на моем onViewCreated. Я также пробовал SOFT_INPUT_ADJUST_PAN, и он не работал

MyCustomDialog.java

public class AddTaskDialog extends SherlockDialogFragment implements OnDateSetListener{
//...
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
    }
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        this.inflater =  getActivity().getLayoutInflater();
        View mainView =inflater.inflate(R.layout.custom_dialog, null);
        builder.setView(mainView);
        this.taskNote = (EditText) mainView.findViewById(R.id.ET_taskNote);
        this.taskText = (EditText) mainView.findViewById(R.id.ET_taskText);
        this.taskValue = (EditText) mainView.findViewById(R.id.ET_taskValue);
        /*
         * Other stuff
         */
        builder.setTitle(getString(R.string.new_task, hType.toString()))
               .setPositiveButton(R.string.dialog_confirm_button, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                    //...
                    }
               })
               .setNegativeButton(R.string.dialog_cancel_button, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();
    }
}

И вот мой макет:

custom_dialog.xml

<LinearLayout 
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" 
android:background="@color/abs__background_holo_light">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content" 
        android:paddingLeft="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_vertical_margin">
        <TextView
            android:id="@+id/TV_taskText"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/task_text"
            android:textAppearance="?android:attr/textAppearanceLarge" />
        <EditText
            android:id="@+id/ET_taskText"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ems="10"
            android:hint="@string/create_task_hint"
            android:inputType="textNoSuggestions"
            android:singleLine="true" />

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_vertical_margin" >
        <TextView
            android:id="@+id/TV_taskNote"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/task_note"
            android:textAppearance="?android:attr/textAppearanceLarge" />

        <EditText
            android:id="@+id/ET_taskNote"
            android:layout_width="0dip"
            android:layout_height="wrap_content"
            android:minLines="2"
            android:layout_weight="1"
            android:ems="10"
            android:inputType="textMultiLine"
            android:hint="@string/task_note_hint">

        </EditText>

    </LinearLayout>
    <LinearLayout
        android:id="@+id/repeat_days"
        android:layout_width="wrap_content"
        android:layout_height="48dp"
        android:layout_gravity="top"
        android:orientation="horizontal"
        android:visibility="gone"
        android:paddingLeft="@dimen/activity_vertical_margin"
        android:paddingRight="@dimen/activity_vertical_margin">
        <!-- Day buttons are put here programatically -->
    </LinearLayout>
</LinearLayout>

Итак, не могли бы вы помочь мне и направить меня на то, как показывать эти кнопки? Либо для PAN просмотра, либо для изменения размера...

Ответ 1

Задайте для свойства windowSoftInputMode значение adjustNothing в AndroidManifest.xml действий, которые используют фрагмент диалога.

<activity
    ...
    android:windowSoftInputMode="adjustNothing">
...

и onCreateDialog, чтобы скрыть мягкий вход:

...
Dialog dialog = builder.create();
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
return dialog;
}

FYI: https://developer.android.com/training/keyboard-input/visibility.html#ShowOnStart

Ответ 2

Я просто использую следующую строку в своем диалоговом окне диалога:

getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

И ничего больше, см. здесь полный пример:

    public class TextEditor extends DialogFragment {

    public TextEditor () {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_text_editor, container);

        //set to adjust screen height automatically, when soft keyboard appears on screen 
        getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

        //[add more custom code...]
        return view;
    }
}

Ответ 3

Убедитесь, что макет находится внутри прокрутки:

<ScrollView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  -->your layout here 
</ScrollView>

и следуйте Комментарий Dirk:

 @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View view = inflater.inflate(R.layout.fragment_text_editor, container);

//add this line 
getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

      //[add more custom code...]
      return view;
    }

Ответ 4

Несмотря на то, что ответ немного задерживается, поскольку вопрос находится в DialogFragment, следующий код решает мою проблему.

@Override
public void onCreate(Bundle savedInstanceState) {
    ...

    // Setting STYLE_NO_FRAME allows popup dialog fragment to resize after keyboard is shown
    setStyle(DialogFragment.STYLE_NO_FRAME, R.style.theme_popupdialog_style);
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.setCanceledOnTouchOutside(false);

    dialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE);
    dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

    return dialog;
}

Что касается темы стиля, я применил следующий код

/** must put parent="@android:style/Theme.Dialog for it to work */
<style name="theme_popupdialog_style" parent="@android:style/Theme.Dialog">
    <item .... >...</item>
</style>

Ответ 5

Это также может быть вызвано:

<item name="android:windowTranslucentStatus">true</item>

Попробуйте удалить его из своей темы.

Ответ 6

Помимо изменений, упомянутых в других ответах, также проверьте тему диалоговогофрагмента

Из моих экспериментов атрибут android: windowIsFloating "влияет на то, как окно реагирует на мягкий ввод.

Это вы установите для этого значения false, окно не будет сдвигаться, когда клавиатура станет видимой.

Ответ 7

Как уже упоминалось, android:windowSoftInputMode="adjustResize" и dialog.getWindow().setSoftInputMode(WIndowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); это правильный способ сделать это.

НО. Если ваше представление не изменяет размер, то ваши кнопки внизу будут по-прежнему скрыты. В моем случае этого взлома было достаточно:

KEYBOARD HIDDEN

Я установил android:layout_weight для верхних видов, так что, когда клавиатура открывается и диалог изменяется, верхние виды будут скрыты: KEYBOARD SHOWN

Ответ 8

Это решение работает как шарм.

Внутри стили:

    <style name="BottomSheetDialogTheme" parent="Theme.Design.Light.BottomSheetDialog">
        <item name="bottomSheetStyle">@style/AppModalStyle</item>
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowSoftInputMode">adjustResize</item>
    </style>

    <style name="AppModalStyle" parent="Widget.Design.BottomSheet.Modal">
        <item name="android:background">@drawable/rounded_corner_dialog</item>
    </style>

Здесь android:windowIsFloating должен быть false & android:windowSoftInputMode должен быть adjustResize.

Обернуть макет внутри NestedScrollView

<androidx.core.widget.NestedScrollView
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

     <--Rest of the layout-->
</androidx.core.widget.NestedScrollView>

Ответ 9

Для DialogFragment кажется, что применение SoftInputMode работает только в том случае, если оно установлено внутри класса DialogFragment, а не класса вызывающего абонента:

@Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

getDialog().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);    

}

Кроме того, для метода onStart я добавил следующее, чтобы развернуть диалоговое расположение по горизонтали:

@Override
    public void onStart() {
        super.onStart();
        getDialog().getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    }