This question already has answers here:
Bottomsheet with edit text moved up by keyboard
(2 answers)
Closed 2 years ago.
I am using a BottomSheetDialogFragment which contains:
- A RecyclerView with a list of comments made by users
- A EditText at the bottom, where users can write a new comment and post it
When the user taps on the EditText, the keyboard shows up from the bottom.
What i want is the keyboard to push ONLY the EditText, so that the user can see what he's typing, but not push the whole BottomSheetDialogFragment.
You can see the desirable behaviour in the Facebook app for example.
I have tried setting different values for setSoftInputMode but all i can achieve is either to move the whole BottomSheetDialogFragment, or to move nothing (leaving the EditText covered).
The easiest way to do this is to not use a BottomSheetDialogFragment but instead to use a regular fragment that covers the entire window or an activity. Fragment or Activity; whichever you prefer doesn't matter as long as you're taking up the whole screen.
When the on-screen keyboard appears, the activity window (by default) resizes to make way for the on-screen keyboard.
Since a BottomSheetDialogFragment has it's gravity set to bottom, when the activity window resizes, it pushes the bottom sheet and all of it's contents upwards.
Here's an example of the simplest layout that can achieve what you're going for
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="#80000000" />
<androidx.recyclerview.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="vertical" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
First is a view with a constant height which imitates the dark area outside of a dialog. No matter how the window resizes this will always be 80dp.
Second is the RecyclerView which resizes based on the remaining available space the LinearLayout has. Pay attention to the attribute android:layout_weight.
Third is EditText which has a constant height of wrap_content. Again No matter how the window resizes this will always be the same height. Since the RecyclerView will take up as much space as it can, this EditText will remain at the bottom of the screen.
Once the window resizes due to the on-screen keyboard appearing, the LinearLayout will resize and recalculate it's children's sizes. Since the View and the EditText has a constant height it will have to make the RecyclerView smaller making it appear like the EditText moved upwards.
You don't have to use a LinearLayout to do this, you can achieve the same effect with any other layout. The key point here is to use a layout that takes up the whole screen.
Related
I have a UX problem with my layout. I want that is possible that the user can scroll over the compleat layout without a focus change when the keyboard popes up.
This is what the Layout looks like when the activity starts
This is what happens when the user clicks to the Big Text EditText
This is what I want the layout to look like, the positions should stand in the same way as before, but it should be possible to scroll to the bottom with the keyboard open
The rootView of my layout is
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
I also try to add android:windowSoftInputMode="adjustResize" and android:windowSoftInputMode="adjustPan" the the activity in the Manifest.xml but it does not solve my problem.
I've got this layout:
Without colors: https://i.stack.imgur.com/OdSda.png
Layout for the tabs (separate xml file)
RelativeLayout 1 surrounding everything else
A, B, C all have their own LinearLayout in RelativeLayout 2
The horizontal line, D (in a LinearLayout) and the "OK" button have their own RelativeLayout 3
And there's RelativeLayout 4 (=footer) for E
What I want to happen if I click on the EditText next to D and the keyboard opens up:
4 stays at the bottom and is hidden behind the keyboard
If there isn't enough space to fully display 3, 2 is collapsed until the keyboard is closed again
What's actually happening:
2 stays where it is
The keyboard covers 3 halfway and I can't see what I'm typing
4 is pushed up and covers D
Two things I've already tried but with both didn't fully work as expected:
I) Add android:windowSoftInputMode="adjustPan" to the manifest:
4 stays at the bottom BUT
Everything else is pushed up, so 2, 3 and the tabs which are then covered half way
II) Add android:windowSoftInputMode="adjustResize" to the manifest: Nothing changes unless I also add android:fitsSystemWindows="true" to the tab fragment's xml:
Now all the padding of the surrounding RelativeLayout 1 is ignored
The EditText next to D is pushed up against 2 but not readable and D and the "OK" button are covered by the keyboard
4 is still pushed up
I managed to find a way! :) A big thanks goes to Umair for giving me the tip with the ScrollView and testing different things too!
First of all, this is how the overall layout is built now:
Surrounding RelativeLayout 1 (nothing special, no android:fitsSystemWindows="true" - the ScrollView seems to disable that anyway!)
new ScrollView
new RelativeLayout (ScrollView can only contain a single element!)
RelativeLayout 2
LinearLayout A (TextView + EditText)
LinearLayout B (TextView + EditText)
LinearLayout C (TextView + EditText)
"Save" Button
RelativeLayout 3
LinearLayout D (TextView + EditText + "OK" Button)
RelativeLayout 4 (TextView E)
Manifest:
<activity android:name=".MainActivity"
android:windowSoftInputMode="adjustResize"
....
Code for RelativeLayout 4:
Before:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom">
<TextView
android:id="#+id/textE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/E"
android:textSize="20sp"/>
</RelativeLayout>
After:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:layout_below="#id/ScrollViewABCD"
android:gravity="bottom">
<TextView
android:id="#+id/textE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/E"
android:textSize="20sp"/>
</RelativeLayout>
I'm not sure if android:layout_gravity="bottom" is actually needed anymore (android:gravity="bottom" is to have the text at the bottom!) but I haven't noticed any changes without it either.
android:layout_alignParentBottom="true" is the important part here because without it, Relative Layout 4 would be simply below the ScrollView but this little extra makes it use up all the space it can, while still keeping it as far south as possible. Plus, you can still use margins to create some empty space between the ScrollView and RL 4 (even though you're only going to see it in the Preview window in Android Studio).
What this does:
The ScrollView is usable
The keyboard is always below the ScrollView
If there isn't enough space to display the ScrollView AND the keyboard, the former becomes scrollable
RelativeLayout 4 is always hidden behind the keyboard
The tabs stay where they are
The padding of RelativeLayout 1 doesn't get ignored (like it would with android:fitsSystemWindows="true")
So here's what I came up with: No matter how hard I tried keyboard on my devices/emulators was always at the bottom of layout 3I checked devices with height starting from 4.7 inches min. And if you put adjust:resize in manifest file it will always show last layout on top of keyboard . But if you put adjust:nothing then your bottom layout won't show up even if you want to write something on it. If you put adjust:adjutPan then it will push your layout on top like you said. Now come to the keyboard part:
If you want to take height or check that either your keyboard is covering your layout or not then you need to take height of your screen and keyboard and find out the difference. Take a look at this question.
How to check visibility of software keyboard in Android?
On the bases of that result you can show or hide your layout.
Note: if you want your requirements as it is then you will have to design your custom layout.
In my application I have the following layout:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<EditText
android:id="#+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:background="#color/text"
android:gravity="center_horizontal"
android:hint="#string/input_hint"
android:inputType="textVisiblePassword"
android:padding="#dimen/margin"
android:singleLine="true"
android:textColor="#color/input_text"
android:textColorHint="#color/input_hint">
</EditText>
</LinearLayout>
When EditText is clicked, the keyboard pushes the screen up including the ActionBar so that EditText is just above the keyboard. What I want is for only EditText to come up sitting on the keyboard, but the FragmentContainer that is above remains intact "as background". I got some of this by using android: windowSoftInputMode = "adjustResize" in the AndroidManifest.xml file, but my application is fullscreen and this tag apparently does not work with fullscreen.
As far as I am aware, there's no way to achieve what you're describing.
These are the choices available to you for windowSoftInputMode:
adjustNothing: When the keyboard appears, the window is not adjusted at all. This will stop your fragment_container from being moved or resizing, but will also cause the keyboard to cover your text input field.
adjustResize: When the keyboard appears, the window is "shrunk" vertically. This will cause your fragment_container to occupy less space than when the keyboard is closed, potentially affecting your fragment layout.
adjustPan: When the keyboard appears, the screen is "pushed" upwards. This will cause your fragment_container's top portion to be clipped by the edge of the screen.
adjustUnspecified: Allow the system to choose between the above three options.
Below are some pictures that (hopefully) help illustrate these attributes.
The layout with keyboard closed
From left to right: adjustNothing, adjustResize, and adjustPan
I am building a app and I just need some help with the attached screen shot.
Currently I have 5 Plain Textfields with the last 2 being textMultilines. I have a Relativelayout with a button placed at the bottom for the user to press submit. The problem is when the textViews above are filled in, especially the multiline ones, it will push the Relativelayout and button off the screen.
How can I stop this from happening
Picture of layout
Either You should fix the height of multi lines text or you can simply use Scroll View and put all the text view and button in same relative layout
You can make them Scrollable by adding ScrollView around them.
like
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
//all your views here
</LinearLayout>
</ScrollView>
let's say I have a view that is made up of 2 layers -> top layer and bottom layer. I place them both in a frame layout.
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- bottom layer -->
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#drawable/some_image_you_shouldnt_shrink"/>
<!-- top layer -->
<EditText
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/somewhat_transparent"/>
</FrameLayout>
now, presumably, when i tap on the editText, the keyboard will pop up, and shrink the size of the edit text. However, it seems that the bottom layer is ALSO getting resized. How do i prevent this bottom layer from getting resized?
Note: the framelayout is in a fragment, and the activity that holds this fragment must declare android:windowSoftInputMode="adjustResize".
EDIT*********
Just to clarify, i want the editText layer to adjust as high as the keyboard needs to. however, i don't want the image behind it to adjust at all
i only have 1 activity that handles these similar types of fragments.
You can't prevent a single view from resizing if you set android:windowSoftInputMode="adjustResize". But if you just want to set a non-resizing background, there is a work-around. Instead of setting the background image in the ImageView through XML, add this in your onCreate() method
getWindow().setBackgroundDrawableResource(R.drawable.some_image_you_shouldnt_shrink);
try this in the manifest
android:windowSoftInputMode="stateVisible|adjustPan"