Reputation: 173
I am writing my first real Android application. I have an Android DialogFragment
that I am displaying to allow users to add or edit details of a selected item. The DialogFragment pops up and displays fine in full screen mode. However, on the Lollipop emulator when I click on EditText
widgets that are lower on the screen, the soft keyboard covers up the widget, rather than scrolling the screen up so that the user may see what they are typing. I do NOT experience this behavior in the pre-Lollipop emulator. On the KitKat emulator, the screen adjusts so that the EditText
is still visible. StackOverflow will not let me post pictures yet. So, you'll have to use your imagination. :-( I have tried different ways to overcome this issue. Unfortunately, none have worked for Lollipop.
UPDATE - I have tested this on a Sony Xperia Z3 Compact running Android 5.0.2, and the DialogFragment
does not scroll or adjust the screen when selecting the lower EditText
widgets.
Here are the styles in use:
<!-- 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>
As you can see in the DialogTheme
, I have included the android:windowSoftInputMode
attribute. I have also tried using that attribute in the AndroidManifest.xml file under the Activity that ultimately contains the DialogFragment
. Here is the XML layout file for the DialogFragment
:
<?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>
As you can see, my layout does include a ScrollView
. I have even defined the android:theme="@style/DialogTheme"
in the layout. I have tried setting android:fillViewport="true"
on the ScrollView, as I saw in another StackOverflow posting.
On the Java side of things, I have an override for the onCreateDialog
method defined as such:
@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;
}
The Fragment
that initiates the DialogFragment
has a method that looks like this:
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();
}
}
As I said, this is working fine for the KitKat emulator. This is NOT working for the Lollipop emulator. You can see that I am trying very hard to get the DialogFragment
to do adjust resize. :-) Does anyone see what I am missing or doing wrong? Also, if there is code that I have neglected to include that would help to find a solution, the please let me know, and I will post that as well. Thank you for any insight you can provide.
Upvotes: 2
Views: 1320
Reputation: 173
It took a while before I discovered this answer. I had actually refactored my DialogFragment
to be an AppCompatActivity
. I then began to think that perhaps the Navigation Drawer set up for Android Lollipop was perhaps to blame for the problems I was experiencing with the DialogFragment
. My MainActivity layout file for API level 21 and above uses a DrawerLayout
widget with a ScrimInsetsFrameLayout
for the Navigation Drawer view. So, both the DrawerLayout
and the ScrimInsetsFrameLayout
utilize android:fitsSystemWindows="true"
in their definition as part of achieving the Material Design UI specification for a Navigation Drawer. That android:fitsSystemWindows="true"
in the DrawerLayout
definition was interfering with the android:windowSoftInputMode="stateHidden|adjustResize"
defined for the MainActivity in the AndroidManifest.xml file to cause the dialog to adjust and resize when the soft keyboard is launched. Here is the XML layout of the MainActivity:
<?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>
When telling the FragmentManager to add the DialogFragment
, I was using the android.R.id.content
as the view container, which is prescribed by the documentation. By experimenting with which view container to use, I was able to find one that gave the expected results. In my case, it is the DrawerLayout
view defined in the MainActivity layout file.
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();
}
Once I had made these changes and refactored my LogEditFragment
class to once again extend DialogFragment
, both the dialog and the navigation drawer behaved as expected.
Upvotes: 3