我正在编写我的第一个真正的 Android 应用程序。我有一个安卓DialogFragment
我显示的内容是为了允许用户添加或编辑所选项目的详细信息。 DialogFragment 弹出并在全屏模式下正常显示。但是,在 Lollipop 模拟器上,当我单击 EditText
时当小部件位于屏幕下方时,软键盘会覆盖小部件,而不是向上滚动屏幕以便用户可以看到他们正在输入的内容。我在 Lollipop 之前的模拟器中没有遇到这种行为。在 KitKat 模拟器上,屏幕会调整为 EditText
仍然可见。 StackOverflow 还不让我发布图片。所以,你必须发挥你的想象力。 :-( 我尝试了不同的方法来解决这个问题。不幸的是,没有一个对 Lollipop 有效。
更新 - 我已在运行 Android 5.0.2 的 Sony Xperia Z3 Compact 和 DialogFragment
上对此进行了测试。选择下方 EditText
时不滚动或调整屏幕小部件。
以下是正在使用的样式:
<!-- Base application theme. -->
<style name="AppTheme" parent="AppTheme.Base">
<!-- Customize your theme here. -->
</style>
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:textColorPrimary">@color/colorPrimaryText</item>
<item name="android:textColorSecondary">@color/colorSecondaryText</item>
<item name="android:dialogTheme">@style/DialogTheme</item>
<item name="android:actionBarStyle">@style/AppActionBarTheme</item>
<item name="actionBarStyle">@style/AppActionBarTheme</item>"
<item name="actionBarTheme">@style/AppActionBarTheme</item>
<item name="actionBarPopupTheme">@style/AppActionBarOverflowMenuTheme</item>
<item name="windowActionModeOverlay">true</item>
</style>
<style name="DialogTheme" parent="Theme.AppCompat.Light.Dialog">
<item name="android:clickable">true</item>
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
<item name="android:windowSoftInputMode">stateHidden|adjustResize</item>
<item name="windowActionModeOverlay">true</item>
</style>
正如您在 DialogTheme
中看到的那样,我已包含 android:windowSoftInputMode
属性。我还尝试在最终包含 DialogFragment
的 Activity 下的 AndroidManifest.xml 文件中使用该属性。 。以下是 DialogFragment
的 XML 布局文件:
<?xml version="1.0" encoding="utf-8"?>
<com.ahappydevelopment.android.fishtales.views.LogEditView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/dialog_margin_top"
android:background="@color/background_material_light"
android:theme="@style/DialogTheme">
<include
android:id="@+id/app_bar"
layout="@layout/app_bar_edit" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/app_bar">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin">
<Button
android:id="@+id/btnCatchDate"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:textAllCaps="false" />
<Button
android:id="@+id/btnCatchTime"
style="?android:attr/borderlessButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:textAllCaps="false" />
<EditText
android:id="@+id/editLatitudeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/btnCatchDate"
android:ems="10"
android:hint="@string/label_latitude"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/editLongitudeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/editLatitudeLabel"
android:ems="10"
android:hint="@string/label_longitude"
android:inputType="numberDecimal" />
<ImageView
android:id="@+id/imgCatchPicture"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_alignTop="@id/editLatitudeLabel"
android:background="@android:color/darker_gray"
android:contentDescription="@string/imgcatchpicture_contentdescription"
android:scaleType="centerInside"
android:src="@android:drawable/ic_menu_camera" />
<Spinner
android:id="@+id/spinnerLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/editLongitudeLabel" />
<TextView
android:id="@+id/txtFishHeader"
style="?android:attr/listSeparatorTextViewStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/spinnerLocation"
android:text="@string/section_fish" />
<Spinner
android:id="@+id/spinnerSpeciesType"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/txtFishHeader" />
<EditText
android:id="@+id/editLengthLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/spinnerSpeciesType"
android:ems="5"
android:hint="@string/hint_length"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/editWeightLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@id/spinnerSpeciesType"
android:ems="5"
android:hint="@string/hint_weight"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/editLengthLabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/editLengthLabel"
android:ems="5"
android:hint="@string/hint_length"
android:inputType="numberDecimal" />
<EditText
android:id="@+id/editWeightLabel2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:layout_below="@id/editWeightLabel"
android:ems="5"
android:hint="@string/hint_weight"
android:inputType="numberDecimal" />
</RelativeLayout>
</ScrollView>
</com.ahappydevelopment.android.fishtales.views.LogEditView>
如您所见,我的布局确实包含 ScrollView
。我什至定义了 android:theme="@style/DialogTheme"
在布局中。我尝试过设置 android:fillViewport="true"
在 ScrollView 上,正如我在另一篇 StackOverflow 帖子中看到的那样。
在 Java 方面,我覆盖了 onCreateDialog
方法定义如下:
@NonNull
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Dialog dialog = new Dialog(getActivity(), R.style.DialogTheme);
//set to adjust screen height automatically, when soft keyboard appears on screen
dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
return dialog;
}
Fragment
启动 DialogFragment
有一个如下所示的方法:
public void addLogButtonOnClickEvent() {
LogEditFragment addLog = LogEditFragment.get(0l);
if(mIsLargeLayout) {
// The device is using a large layout, so show the fragment as a dialog
addLog.show(getFragmentManager(), "AddLog");
} else {
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// To make it fullscreen, use the 'content' root view as the container
// for the fragment, which is always the root view for the activity
transaction.add(android.R.id.content, addLog).addToBackStack(null).commit();
}
}
正如我所说,这对于 KitKat 模拟器来说运行良好。这不适用于 Lollipop 模拟器。你可以看到我正在非常努力地获取 DialogFragment
进行调整调整大小。 :-) 有人看到我遗漏了什么或做错了什么吗?另外,如果我忽略了一些有助于找到解决方案的代码,请告诉我,我也会发布该代码。感谢您提供的任何见解。
最佳答案
我花了一段时间才发现这个答案。实际上,我已将 DialogFragment
重构为 AppCompatActivity
。然后我开始认为,为 Android Lollipop 设置的抽屉导航可能是我在使用 DialogFragment
时遇到的问题的罪魁祸首。我的 API 级别 21 及更高版本的 MainActivity 布局文件使用 DrawerLayout
小部件以及用于抽屉导航 View 的 ScrimInsetsFrameLayout
。因此,DrawerLayout
和 ScrimInsetsFrameLayout
在其定义中都利用了 android:fitsSystemWindows="true"
作为实现 Material Design UI 规范的一部分抽屉式导航。 DrawerLayout
定义中的 android:fitsSystemWindows="true"
干扰了为 MainActivity 定义的 android:windowSoftInputMode="stateHidden|adjustResize"
在 AndroidManifest.xml 文件中,使对话框在软键盘启动时调整和调整大小。这是 MainActivity 的 XML 布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context=".MainActivity">
<!-- The Main Content View -->
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="@+id/app_bar"
layout="@layout/app_bar_main" />
<FrameLayout
android:id="@+id/fragment_main_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/app_bar" />
</RelativeLayout>
<!-- The Navigation Drawer View -->
<com.ahappydevelopment.android.fishtales.widgets.ScrimInsetsFrameLayout
android:id="@+id/scrimInsetsFrameLayout"
android:layout_width="@dimen/navigation_drawer_width"
android:layout_height="match_parent"
android:layout_gravity="start"
android:elevation="10dp"
android:fitsSystemWindows="true"
app:insetForeground="#4000">
<FrameLayout
android:id="@+id/fragment_drawer_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.ahappydevelopment.android.fishtales.widgets.ScrimInsetsFrameLayout>
</android.support.v4.widget.DrawerLayout>
当告诉 FragmentManager 添加 DialogFragment
时,我使用 android.R.id.content
作为 View 容器,这是文档中规定的。通过尝试使用哪个 View 容器,我找到了一个能够提供预期结果的容器。就我而言,它是 MainActivity 布局文件中定义的 DrawerLayout
View 。
LogEditFragment addLog = LogEditFragment.get(0l);
if(mIsLargeLayout) {
// The device is using a large layout, so show the fragment as a dialog
addLog.show(getFragmentManager(), "AddLog");
} else {
// The device is smaller, so show the fragment fullscreen
FragmentTransaction transaction = getFragmentManager().beginTransaction();
// For a little polish, specify a transition animation
transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
// To make it fullscreen, use the 'drawer_layout' view
// as the container for the fragment
transaction.add(R.id.drawer_layout, addLog).addToBackStack(null).commit();
}
完成这些更改并重构我的 LogEditFragment
类以再次扩展 DialogFragment
后,对话框和抽屉导航的行为都符合预期。
关于Android Lollipop 软键盘隐藏 DialogFragment 中的用户输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30131024/