Android BottomSheetBehavior with Keyboard adjustResize - android

I have the following layout in an activity.
<CoordinatorLayout ...>
<ScrollView ...>
<LinearLayout
...
android:orientation="vertical">
<!-- Some stuff -->
<EditText ...>
<!-- Some more stuff -->
<View
android:id="#+id/keyboard_extender"
...>
</LinearLayout>
</ScrollView>
<LinearLayout
android:id="#+id/bottom_sheet"
android:orientation="vertical"
...
app:layout_behavior="android...BottomSheetBehavior">
<!-- Even more stuff -->
</LinearLayout>
</CoordinatorLayout>
and I want that the keyboard shouldn't push up the bottom_sheet but it should push up the keyboard_extender. Please note that the bottom_sheet is not a BottomSheetDialog but just a view using the android.support.design.widget.BottomSheetBehavior. This can't be changed to a BottomSheetDialog because I want the rest of the screen to remain active at the same time as the bottom_sheet
I never set the visibility of the bottom_sheet to View.GONE. I only change its state from BottomSheetBehavior.EXPANDED to BottomSheetBehavior.COLLAPSED and back. Also, I want the bottom_sheet to be visible only when the keyboard isn't.
Since I need that the keyboard_extender should always be above the keyboard, I have set in the AndroidManifest.xml that android:windowSoftInputMode="adjustResize" (which I assume is unavoidable)
I have a method which when called should hide the keyboard and show the bottom_sheet, but the problem I'm facing is that the bottom_sheet starts animating to BottomSheetBehavior.EXPANDED at the same time that the keyboard starts hiding, and when the keyboard starts hiding, the screen is actually resized because of the windowSoftInputMode="adjustResize" and the bottom_sheet starts expanding from the top of the keyboard and it doesn't move down along with the keyboard. So, when the keyboard completely hides, the bottom_sheet is actually sitting in the middle of the screen (just above the height of the keyboard).
Ideally, I'd like that the keyboard starts hiding and the bottom_sheet starts expanding at the same time, but the bottom_sheet starts expanding from the bottom of the screen and not the top of the keyboard.
The very hacky fix I'm currently using to overcome this issue is to delay the expanding of the bottom_sheet by SoftInput.KEYBOARD_POPUP_DELAY, which seems to be working for the time being. Is there any cleaner alternative?

Related

Scrollable layout when keyboard pops up, but without focus change

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.

Keyboard does not push layout above EditText

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

Using adjustResize with fragments and requestFocus

I'm trying to create an activity with a single RelativeLayout used as a fragment container, where each fragment has a separate background color that bleeds under a translucent status bar, and where the activity as a whole accounts for the keyboard size.
The layout for the activity is:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The fragments are wrapped with:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:animateLayoutChanges="true" />
And the activity is defined as:
<activity android:screenOrientation="portrait"
android:name=".login.LoginActivity"
android:windowSoftInputMode="adjustResize" />
Everything is working fine for the first fragment. The activity resizes the RelativeLayout, the fragment contained within it resizes to adjust for the keyboard, and everything is fine. However, when replacing one fragment with another that uses <requestFocus /> on its <EditText />, the keyboard stays up but the second fragment that is pushed on takes the full screen size (under the keyboard). Closing and re-opening the keyboard causes the activity to re-measure and then everything is fine. Similarly, if the keyboard changes height during the fragment transition (when moving from a field that doesn't support autocorrection to one that does, so the keyboard gets taller), the fragment measures correctly. So it only appears to be a problem when transitioning between two fragments where the keyboard size is constant.
Adding fitsSytemWindows=true to the wrapping RelativeLayout fixes the problem, but also prevents the fragment's view from appearing under the status bar, which isn't what I want. Is there some way to force the fragment to re-measure or something that I'm missing? This is using native fragments, not app-compat.

Android how to ignore auto resizing when keyboard pops up?

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"

Status bar always on screen

Good day (or evening, or night)
I'm developing an app for android and I'm very curious about one thing. I have an activity, where user chats with another, like "im" chat. There are an EditText on the bottom and some kind of actionbar on the top. What I need is when user enters a message and the software keyboard is on screen, my activity should move up, but the actionbar should still be "glued" to the top of the screen, because it has some valuable controls on it.
Again, that's not an ActionBar, but just a 48dp height layout in a parent vertical linear layout. So I need to know is there an easy way to prevent it from moving to the top, when the layout moves off the screen.
I tried to put everything in a FrameLayout and put this bar on top of it, but on keyboard opens it goes off the screen too...
On you Activity at AndroidManifest you should put this: android:windowSoftInputMode="adjustResize"
Use something like this:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.myapp.MyActionBar
android:layout_width="match_parent"
android:layout_height="48dp"/>
<LinearLayout
android:id="#+id/mylayout"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1dp"/>
<!-- Add your edittext and button -->
</LinearLayout>
This will make sure the actionbar and edittext + button are allways on screen, and the mylayout takes up the rest of the screen. When your keyboard is shown, the mylayout will shrink.
Try adding android:windowSoftInputMode="adjustResize" to your activity in the manifest. This tells Android to completely resize your layout when the keyboard comes up, rather than pan it. Note that if there isn't enough room for the entire layout this still won't work. But you ought to be able to make it work if your top level layout is a RelativeLayout, with the edit text set to align bottom, the top bar to align top, and the middle section to fill_parent and be above the edit text and below the bar.
use a RelativeLayout as your base Layout and add android:layout_alignParentTop="true" to your action bar to keep it up
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<LinearLayout
android:id="#+id/action_bar_layout"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_alignParentTop="true" >
</LinearLayout>
<TextView
android:id="#+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true" />
</RelativeLayout>

Categories

Resources