Overlapping fragments when soft keyboard appears - android

I've got an activity with several fragments, in particular:
<LinearLayout
android:orientation="vertical"
android:layout_width="1056dp"
android:layout_height="match_parent">
<fragment
android:layout_width="1056dp"
android:layout_height="0dp"
android:name="FragEntryEdit"
android:id="#+id/itemEditFragment"
tools:layout="#layout/fragment_entry_edit"
android:layout_weight="2"
/>
<ScrollView
android:layout_width="1056dp"
android:layout_height="0dp"
android:layout_weight="1.5">
<fragment
android:layout_width="1056dp"
android:layout_height="match_parent"
android:name="FragPhotos"
android:id="#+id/itemPhoto"
tools:layout="#layout/fragment_photos"
/>
</ScrollView>
</LinearLayout>
The first fragment contain a few EditText controls some of which are multi-line.
When creating, I hide the soft keyboard. When an editText control gets focus, the soft keyboard appears.
However the content of the second fragments (which is beneath the first) is pushed up by the keyboard, overlapping the EditText-controls (the first fragment).
I have tried to set set the 'windowSoftInputMode' to 'AdjustPan', but this doesn't appear to work.
Anybody got any suggestions?

Figured it out!
The problem was not the fragments, but the vertical weighting in the LinearLayouts.
I removed the weighting and wrapped a ScrollView around the first fragment, and it works.

I would suggest to set a background to the fragments. I had a similar problem with overlapping fragment and I solved it setting a white background to the fragments.
my_fragment.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/white"
android:orientation="vertical" >
<!-- MORE XML -->
</LinearLayout>

Related

Android app freezes when app soft keyboard is displayed or hide

I have an activity which has a fragment. Inside that fragment, there are 5 fragmnets inside ViewPager. Each fragment has either more than 30 input fields including EditTexts, custom Dropdowns and Date Pickers or nested ViewPagers with fragments having same amount of input fields.
The problem is; when user taps on any EditText to input data, soft keyboard gets visible and when it is completely visible, the app freezes for around 2 seconds. When user presses back button to hide soft keyboard, keyboard gets off from screen and screen area which is underneath soft keyboard becomes white and app freezes again for same amount of time. This happens every time. Here is activity configuration from manifest:
<activity
android:name=".activities.HomeActivity"
android:launchMode="singleTask"
android:screenOrientation="portrait"
android:windowSoftInputMode="adjustPan|adjustResize" />
I have tried different combinations for android:windowSoftInputMode nothing worked. Although this does not happen in other activities with same manifest configuration and with less number of fields. With so many input fields, its very annoying for user that app freezes after inputting data in textfields. Can anyone suggest me workaround for this?
I have found the solution. In most of the layouts, the views were aligned vertical to each other inside RelativeLayout using android:layout_below property like:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--nested form view containers-->
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layout1"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--nested form view containers-->
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/layout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/layout2"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--nested form view containers-->
</RelativeLayout>
</LinearLayout>
</RelativeLayout>
I replaced root RelativeLayouts with vertical oriented LinearLayouts and it did the magic trick like this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:id="#+id/layout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--nested form view containers-->
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/layout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!--nested form view containers-->
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="#+id/layout3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!--nested form view containers-->
</RelativeLayout>
</LinearLayout>
</LinearLayout>
I am still looking for some technical details on how it impacts keyboard visibility states. Will update here if I find something.
I will need to hands-on debug to find the issue, but what I think I will do is:
Check whether this is actually because of those many fragments and input controls. Can you try with only 1 fragment instead of 5 fragments and see if the speed improves? If yes, then try to display a fragment at once (ex: if you change from tab 1 to tab 2, explicitly remove fragment 1 from the pager view hierarchy and explicitly add fragment 2 to the pager view hierarchy). If after you simplify your controls, you still see the freeze, then that might not be because of too many controls.
Check whether there is offending control(s).Maybe you have a control or two that unexpectedly do a routine that heavily taxed your resources. If from point #1 you can find a fragment that significantly slowing down your app when it gets displayed, you might want to check further into that fragment and controls inside.

How to prevent ScrollView scrolling down when a child has textIsSelectable="true" attribute?

Previously, this was the layout for my DialogFragment:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".InfoDialog"
android:id="#+id/scrollView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:id="#+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<!-- (More Views here) -->
</LinearLayout>
</ScrollView>
It works fine. However, I need to make textView1 selectable. But when I add the android:textIsSelectable="true" attribute to it, scrollView is scrolled down a bit when the dialog is displayed. (NB - I am able to scroll it up to the top manually, but that's obviously not a solution.)
I've tried adding android:descendantFocusability="beforeDescendants" to scrollView, but that hasn't worked.
I've also tried this in my onCreateDialog() and onViewCreated() methods:
ScrollView scrollView = layoutView.findViewById(R.id.scrollView);
scrollView.fullScroll(ScrollView.FOCUS_UP);
scrollView.scrollTo(0, 0);
But that hasn't worked either - ie, scrollView is still scrolled down a bit when the Dialog is shown.
Any ideas?
Update:
Using this to the end of my onCreateDialog() works:
ScrollView scrollView = layoutView.findViewById(R.id.scrollView);
scrollView.post(() -> {
scrollView.fullScroll(ScrollView.FOCUS_UP);
});
However, it's not an ideal solution (esp. as you can see the scroll being performed on-screen). Is there a better solution, preferably xml?

android questions about poping the soft keyboard

i want the whole layout move up to show while popping the soft keyboard, but the button on the bottom of the view cannot be seen.
the AndroidManifest.xml:
<activity
android:name="cn.duckr.android.plan.PlanConfirmPaymentActivity"
android:windowSoftInputMode="adjustPan"
style="#style/base_activity_style"
android:theme="#style/confirm_payment_anim_theme" />
To ensure that the system resizes your layout to the available space—which ensures that all of your layout content is accessible (even though it probably requires scrolling)—use "adjustResize".
link
android:windowSoftInputMode="adjustResize"
You can put whole layout except the particular button in a ScrollView to achieve this.
like this
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/scrollView5"
android:fillViewport="true">
//put your contents here..
</ScrollView>
<ImageButton
android:id="#+id/ibSample"
android:layout_width="50dp"
android:layout_height="50dp"
android:adjustViewBounds="true"/>
</RelativeLayout>

CardView Scroll behavior when keyboard is up

Our app's main content is a RecylerView of CardView's. For signup we require more than just a username/password to create an account so we decided to make the signup flow out of CardView's to match the user experience once they sign up.
To do that I have a single Activity that animates fragments in from the bottom and existing fragments out the top to emulate scrolling. This fake scrolling occurs when the user enters data and hits next to advance. This works pretty well except for one case. When we have a EditText for input the keyboard comes up and covers the 'next' button on the bottom of the screen.
In our user testing we've noticed a high percentage of users trying to scroll the card up to get to the next button instead of dismissing the keyboard.
I've spent a lot of time unsuccessfully trying to get the CardView to scroll up to reveal the button and I'm out of ideas and looking for new ones.
The signup Activity layout only contains a FrameLayout that I load Fragments into. Each fragment that gets loaded has a CardView for the root layout.
In the manifest I have set the activity's windowsSoftInputMode to adjustResize, adjustPan with little success.
activity_signup.xml
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/signUpContent"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
simplified fragment_enter_code.xml
<android.support.v7.widget.CardView
style="#style/CardViewStyle.SignUp"
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:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardCornerRadius="25dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true"
app:contentPadding="8dp">
<EditText
android:id="#+id/codeEditText"
style="#style/HintedEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Code"
android:inputType="text"/>
<Button
style="#style/NextButton"
android:id="#+id/nextButton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:enabled="false"
android:text="#string/next"/>
</android.support.v7.widget.CardView>
When I tried putting the CardView in a ScrollView the cardview layout (with fillViewport true), I get a scrollbar but the card doesn't scroll and the cardview layout gets messed up.
Does anyone know the windowSoftInputMode's well enough to point me in the right direction? Or is the CardView just not going to scroll outside of a Container that is design to hold them?
It feels like the solution to this is in manipulating the activity's view not the fragments.
I ended up creating a new app to just play around with this issue and noticed that if I had a layout that didn't contain a CardView whose root layout was a ScrollView it didn't scroll unless the activities windowSoftInputMode is set to adjustResize and then it will scroll.
I then made a layout with a <ScrollView><CardView><content...></CardView></ScrollView> and the size of the CardView was always the default row size for a card and wouldn't match_parent. I solved that with fillViewPort="true" on the ScrollView but when the keyboard came up it wouldn't scroll.
Turns out the secret sauce was to put a FrameLayout (or anyother layout) in between the CardView and the ScrollView.
You still have to account for the resize of the Layout to prevent your view elements not stacking over each other but Once you do that you now get the view above the soft keyboard to scroll and the ability to reach the rest of the UI with a CardView.
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:fillViewport="true">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.v7.widget.CardView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardCornerRadius="35dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="true"
app:contentPadding="8dp">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="#+id/image"
android:layout_width="match_parent"
android:layout_height="200dp"
android:src="#drawable/common_ic_googleplayservices"/>
<EditText
android:id="#+id/input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_below="#id/image"
android:hint="Input"
android:inputType="text"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/input"
android:orientation="vertical"
android:gravity="bottom|center_horizontal">
<Button
android:id="#+id/nextButton"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:enabled="false"
android:text="Next"/>
</LinearLayout>
</RelativeLayout>
</android.support.v7.widget.CardView>
</FrameLayout>
</ScrollView>

Soft-keyboard appears every time layout becomes visible

I have two layouts within a fragment that I switch back and forth between by making one invisible and the other visible and visa versa. When the layout that contains an EditText becomes visible the soft keyboard automatically pops up. I have used the following in the manifest but it didn't help.
android:windowSoftInputMode="stateUnchanged"
I never explicitly request focus on the EditText and have even tried requesting focus on something else to no avail.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent"
android:id="#+id/container">
<LinearLayout android:id="#+id/dial_pad_ll"
android:layout_width="match_parent" android:layout_height="match_parent"
android:orientation="vertical" android:layout_centerInParent="true"
android:background="#1E1E1E" android:layout_marginLeft="20dp" android:layout_marginRight="20dp">
<EditText android:layout_height="wrap_content" android:id="#+id/search_et"
android:layout_width="match_parent" android:layout_alignParentTop="true"
android:layout_marginTop="20dp" android:layout_marginBottom="10dp" >
</EditText>
<!-- Other widgets here -->
</LinearLayout>
<!-- Other Layout Here -->
</RelativeLayout>
Anyone know how to prevent this? Thanks.
Edit: I should also have mentioned that this doesn't happen the first time. I open layout 1 with the edit text, make it invisible, make it visible again, then the keyboard pops up.
try adding this to your activity.
this.getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

Categories

Resources