【问题标题】:DialogFragment not resizing when keyboard shown显示键盘时 DialogFragment 未调整大小
【发布时间】:2013-06-02 17:21:11
【问题描述】:

我正在尝试使用SherlockDialogFragment 来询问用户的一些输入。在我的手机(Galaxy Nexus,4.2)上一切正常,但在较小的手机(模拟器 2.3.3)上,当键盘出现时,它会覆盖 DialogFragment 的两个按钮,如下所示:

我的布局位于 ScrollView 内,我将 onViewCreated 上的 softInputMode 更改为 SOFT_INPUT_ADJUST_RESIZE。我也试过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>

那么,您能帮我,并指导我如何显示这些按钮吗?要么平移视图,要么让它调整大小...

【问题讨论】:

    标签: android actionbarsherlock android-view android-dialogfragment


    【解决方案1】:

    我只是在 DialogFragment 中使用以下行:

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

    【讨论】:

    • 对我来说,从 onCreateView() 和其他地方调用 setSoftInputMode() 非常重要,例如从 onCreateDialog() 调用它不起作用
    【解决方案2】:

    在使用对话框片段的活动的AndroidManifest.xml 中将windowSoftInputMode 属性设置为adjustNothing

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

    onCreateDialog 隐藏软输入:

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

    仅供参考:https://developer.android.com/training/keyboard-input/visibility.html#ShowOnStart

    【讨论】:

    • 由于它是一个DialogFragment,它在manifest中没有任何关联的activity,所以第一个点没用,但是另一个修复了它。谢谢。
    • 我编辑了我的答案,以更具体地了解清单代码的版本。
    • 为什么没有dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN); 对话框不会重新调整大小?这看起来像错误。
    【解决方案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 comment

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

    【讨论】:

    • 在尝试获得 SOFT_INPUT_ADJUST_PAN 行为时,绝对是唯一对我有用的东西。
    • 是的,这应该是公认的答案,谢谢@Sara
    【解决方案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】:

      如果有人对 BottomSheetDialog 有类似的问题。这个解决方案就像一个魅力。

      内部样式:

      <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>
          <item name="android:statusBarColor">@android:color/transparent</item> 
      </style>
      

      android:windowIsFloating 应该是false

      android:windowSoftInputMode 必须是adjustResize

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

      在 NestedScrollView 中包裹布局

      <androidx.core.widget.NestedScrollView
          android:layout_width="match_parent"
          android:layout_height="wrap_content">
      
           <--Rest of the layout-->
      </androidx.core.widget.NestedScrollView>
      

      在某些设备上,这种解决方案还不够。将此添加到代码中完全解决了我的问题。

      override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
          super.onViewCreated(view, savedInstanceState)
          dialog?.setOnShowListener {
              val dialog = it as BottomSheetDialog
              val bottomSheet = dialog.findViewById<View>(R.id.design_bottom_sheet)
              bottomSheet?.let { sheet ->
                  dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
                  sheet.parent.parent.requestLayout()
              }
          }
      }
      

      【讨论】:

      • 谢谢,在浪费了两天时间尝试不同的事情之后,您的解决方案对我有用,但只有前两个步骤。我不需要任何嵌套的scoolview
      【解决方案6】:

      这也可能是由以下原因引起的:

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

      尝试将其从您的主题中删除。

      【讨论】:

      • 你知道这是为什么吗?
      • 我认为这是一个错误。
      • 谢谢。顺便说一句,你知道如何在启用半透明状态的情况下“修复”它吗?
      • 我遇到了同样的问题。我使用 #someTranslucentColor 作为解决方法。它似乎适用于 fitsystemwindows 和其他东西
      【解决方案7】:

      除了其他答案中提到的更改外,还要检查对话框片段的主题
      根据我的实验,“android:windowIsFloating”属性似乎会影响窗口对软输入的反应。

      如果将此设置为 false,则当键盘可见时,窗口不会向上滑动。

      【讨论】:

      • 这很神奇,花了这么多小时后,这个答案拯救了一天!
      【解决方案8】:

      要正常使用 AutoCompleteTextView DialogFragment 不能设置为全屏。 相反,您可以在样式中将宽度设置为 match_parent。 下面的示例代码:

      override fun onCreateView(
          inflater: LayoutInflater,
          container: ViewGroup?,
          savedInstanceState: Bundle?
      ): View? {
          dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE)
          return inflater.inflate(R.layout.dialog_filter, container)
      }
      
      override fun getTheme(): Int {
          return R.style.AlertDialog_FullWidth
      }
      

      样式:

      <style name="AlertDialog" parent="android:Theme.Dialog">
          <item name="android:windowIsFloating">true</item>
          <item name="android:windowIsTranslucent">false</item>
          <item name="android:windowNoTitle">true</item>
          <item name="android:windowFullscreen">false</item>
          <item name="android:windowBackground">@android:color/transparent</item>
          <item name="android:backgroundDimEnabled">true</item>
          <item name="android:backgroundDimAmount">0.8</item>
          <item name="android:windowAnimationStyle">@style/PauseDialogAnimation</item>
      </style>
      
      <style name="AlertDialog.FullWidth" parent="AlertDialog">
          <item name="android:layout_width">match_parent</item>
          <item name="android:windowIsFloating">false</item>
      </style>
      

      【讨论】:

        【解决方案9】:

        如前所述,android:windowSoftInputMode="adjustResize"dialog.getWindow().setSoftInputMode(WIndowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); 是正确的做法。

        但是。如果您的视图根本无法调整大小,那么底部的按钮仍将被隐藏。就我而言,这个 hack 就足够了:

        我为顶视图设置了android:layout_weight,这样当键盘打开并调整对话框大小时——顶视图将被隐藏:

        【讨论】:

        • 嗨@soshial,我知道这已经很老了,但是当我尝试这个时,对话框会粉碎内容!
        • 是的,内容被最小化了——这是我发现唯一可行的快速解决方法。
        • 我正在使用 MaterialDialog 库;)
        【解决方案10】:

        对于DialogFragment,似乎只有在DialogFragment 类而不是调用者类内部设置时,应用SoftInputMode 才有效:

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

        【讨论】:

          猜你喜欢
          • 2021-02-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-10-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多