I appreciate there's a number of questions around this but none of them seem to resolve the situation I find myself in. I've written a small test case to see if the community can support.
<?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">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="75dp"
android:background="#ff0000">
</RelativeLayout>
<EditText
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="12dp"
android:text="Hello World!" />
</RelativeLayout>
This snippet above, produces the following: -
when given a theme in the android manifest for this activity of: -
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowTranslucentStatus">true</item>
</style>
So.. this is exactly what I would like, however when I open the keyboard, the following happens: -
(given that I have the following set in the manifest)
android:windowSoftInputMode="adjustResize"
As you can see, the keyboard hides the edit text.
This is where there's a number of other posts and confusion
The recommendations seemed to be to set things like (and see the result for each): -
android:fitsSystemWindows in the root relativelayout
Great, this fixes the keyboard hiding the edit text but now the red bar at the top is moved downwards, which is not what I would like (see original image if needed)
Change windowSoftInputMode to adjustPan
As expected, the view pans and the top bar is lost.
At this point, I'm a bit lost without coming up with a hacky solution to resize and calculate on the fly, which feels very dirty.
So given what I've posted above, does anyone have any solution to achieve the following: -
Translucent status bar (so the red panel sits behind it)
red panel doesn't disappear when the soft keyboard is shown
soft keyboard doesn't cover the text control
Let's also assume for arguments sake that colouring the status panel is not an option as I actually want to view the content behind the status panel, i.e. a map. I've used a red panel as an example.
Related
TL;DR: soft keyboard should overlap a bottom-anchored view instead of pushing it up. Gitlab link for an mcve.
Summary:
I have an AppCompatDialogFragment (androidx) which appears fullscreen on phones and has fixed dimensions on tablets (using dialog?.window?.setLayout(width, height) in case this matters). The dialog's layout has some content placed in a ScrollView and a button-like layout anchored at the bottom (complete XML structure see below).
Side note: the superclass of the AppCompatDialogFragment in question calls setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN)on its Window.
The problem:
When the soft keyboard appears as a result of some text input receiving focus, it pushes the complete layout up, including the bottom-anchored view that I want overlapped by the soft keyboard. For some reason, the issue only affects phones, on tablets the soft keyboard correctly overlaps everything including the bottom-anchored view without any additional adjustments or flags.
What I have tried (without any success):
setting android:windowSoftInputMode="adjustNothing" (tried other flags "just in case" as well) for the Activity in question, also tried to apply them in code
setting android:isScrollContainer="false" on the ScrollView and its parent
combinations of the above
looking for similar questions like this one and confirming the proposed solutions didn't work
Here's the layout in question (note: I omitted many unrelated attributes to keep the snippet reasonably sized; everything is positioned vertically matching the elements' order. The <include> elements contain the text inputs):
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.widget.Toolbar
android:layout_width="match_parent"
android:id="#+id/toolbar"
android:layout_height="?attr/actionBarSize"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toTopOf="#id/bottom_layout"
app:layout_constraintTop_toBottomOf="#id/toolbar"
android:isScrollContainer="false"
android:scrollbarStyle="outsideOverlay">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<include
layout="#layout/some_layout_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<include
layout="#layout/some_layout_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
<!-- I want this one to be overlapped by the soft input, but it's just pushed up -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/bottom_layout"
app:layout_constraintBottom_toBottomOf="parent">
<View
android:layout_width="match_parent"
android:layout_height="#dimen/divider"
android:background="#color/dark_grey" />
<TextView
android:layout_width="match_parent"
android:layout_height="#dimen/some_dimen"
android:foreground="?attr/selectableItemBackground"
android:text="#string/text" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
The question: how do I force the soft keyboard to overlap the layout anchored at the bottom on all devices?
Please comment if you need any additional details.
EDIT: here's a minimal demo app that reproduces the issue: https://gitlab.com/Droidman/soft-keyboard-issue-demo
Try adding the following line to onCreateView() of DemoDialog:
dialog.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
It is important to apply this change to the window of the dialog and not to the window of the activity.
With this in place, this is what I see on an Nexus 6 emulator running API 29 using your MCVE:
You may need to work with the placement a little, but this should help.
Let's look under the hood a little. For a phone and a tablet, the soft input mode is zero in onCreateView(). This value corresponds to SOFT_INPUT_ADJUST_UNSPECIFIED. The documentation for SOFT_INPUT_ADJUST_PAN explains what happens when the soft input mode is unspecified (emphasis is mine.)
Adjustment option for softInputMode : set to have a window pan when an input method is shown, so it doesn't need to deal with resizing but just panned by the framework to ensure the current input focus is visible. This can not be combined with SOFT_INPUT_ADJUST_RESIZE ; if neither of these are set, then the system will try to pick one or the other depending on the contents of the window.
Looking at the value of the soft input mode in onStart() (dialog?.window?.attributes?.softInputMode) shows the value selected by the system for the phone is SOFT_INPUT_ADJUST_RESIZE) and the value selected for the tablet is SOFT_INPUT_ADJUST_PAN. This explains the difference that is seen between phones and tablets.
So, always setting the soft input mode to SOFT_INPUT_ADJUST_PAN looks like the best solution although SOFT_INPUT_ADJUST_NOTHING also works and may be preferable for certain layouts.
Add this to your class inside the tags in the AndroidManifest in your Class:
android:windowSoftInputMode="stateHidden|adjustResize"
I am developing an app with Android Studio 2.2.3 and I'm facing a problem I did not find before: if I add an Activity from a template such as Basic Activity, the newly created activity will let the device status bar display
If I add instead an activity from the Empty Activity template, no status bar shows up any more.
Reading through the layout files, I see that the Basic activity uses a android.support.design.widget.CoordinatorLayout whereas the Empty Activity uses a RelativeLayout. I cannot find any other differences, neither in the manifest. I programmed some apps with Eclipse some time ago and the status bar was there, even with the RelativeLayout, as far as I remember.
Any suggestion?
Thanks in advance, regards
Edit:
Status bar does not relate with layout. It is about the theme defined in the styles.xml. Can you check which theme is applied your activity?
Thanks steve for your suggestion: the behavior is due to
Yet another question: keeping this no-actionbar theme, why is my textbox not aligned with the top of the screen, like this:
My activity layout is:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main4"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="it.pgsoftware.firebasepublisher.Main4Activity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="test string"
android:layout_alignParentTop="true"
android:layout_marginTop="0dp"/>
</RelativeLayout>
and with the Layout inspector I get the following UI structure:
The LinearLayout at the top has a 72dp top-padding which I can't find digging into the themes: any suggestion?
Thanks in advance, regards
Please check the android:appTheme="#style/AppTheme" option in the manifest file . Check the theme option in res>style.xml file . Copy the stylesheet and paste in comment to see.
I have a layout with a graphic at the top, an EditText in the middle and a button some distance below it, like so:
When the user is typing in the EditText, I want to pan the layout so that the "Go" button is still visible, even if that means clipping the image off the top, like so:
I know about windowSoftInputMode="adjustPan" in the manifest, but that doesn't work because it only pans far enough for the EditText to be visible. Is there a way to make sure it pans until the button is visible too?
For comments with K_Anas, this is my layout. It has all the extra margins and spacing removed compared to the first screenshot, to remove any other source of problems.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<View
android:layout_width="300dp"
android:layout_height="150dp"
android:layout_alignParentTop="true"
android:background="#999"/>
<EditText
android:layout_width="280dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:hint="Sample..."/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="Go"/>
</RelativeLayout>
Spoke with the Android developers hangout, and it doesn't seem like there's an easy way to solve this problem. The consensus seems to be reworking the layout rather than having an API to fix the issue.
did you tried:
android:windowSoftInputMode="adjustResize"
in your activity Tag in Manifest
see these docs on android developer blog
I tried your layout with: android:windowSoftInputMode="stateVisible|adjustResize"
and give me these results:
I'm sure it isn't the BEST way, but couldn't you just change the layout attributes for your button (add/change a margin) and redraw when the edittext is clicked? Use an onClickListener & maybe invalidate your button.
I have one problem with text overflow.
I have searched all the topics about this problem and tried everything but none work for me(android:singleLine etc..).
To be more specific,text is showing in a single line,in textview,in listview even in alert dialog without custom layout.
The strange fact is that in alert dialog is showing only the first time,if i open again the dialog its ok.But the problem persists in lists and textviews......
The most strange part is that sometimes text is overflowing even in other AVD but later are OK,but in QHD and in my phone(HTC DESIRE) is overflowing.In Graphical Layout is looking fine in every configuration.
One layout of the many layouts that have problem is that:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/ListView01"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#android:color/transparent"
android:cacheColorHint="#android:color/transparent"
android:fadingEdge="none"
android:fastScrollEnabled="true" >
<!-- Preview: listitem=#layout/listview -->
</ListView>
</LinearLayout>
This problem appeared now,i didnt have it before...i dont know what is causing this because i have update ADT Tools,JDK and i replace my custom Action Bar with ActionBarCompat from ApiDemos.
What is should do?Why this is happening?Maybe is ActionBarCompat fault??
EDIT:
I have attached a screenshot of dialog overflow problem(1 of 2)
To be honest I suggest using a custom alert dialog since languages other than English is not properly measured. Imagine a box [a] where a holds a character, it gets measured on the width of that character. However android doesn't have the width of other characters other than English. I know this because I also work with other languages on android, it messes up my view so what I did was compromise with the text data. Sorry didn't see your view before posting my previous answer.
I found the solution.It was the ActionBarCompat from API Demos that make all these problems!!!After so many days trying to find out,was the ActionBar!!!!!!I reported the issue and i hope to fix that soon!The problem is that i changed
<style name="AppTheme" parent="android:style/Theme.Light">
to
<style name="AppTheme" parent="android:style/Theme.Holo">
in styles.xml and cause that bug.
When the software keyboard shows, it resizes my layout and thus squeezes the background image together. My question is basically a duplicate of this question, which is explained in a very good way:
Software keyboard resizes background image on Android
However, that question was closed when they found a hack to solve it. I cannot use this hack. My entire layout is inside a ScrollView, and I need to be able to use this scrollview properly at all times. By using android:windowSoftInputMode="stateVisible|adjustPan" the user will not be able to scroll down and see the bottom of the screen while the keyboard is showing, since the layout will partly exist behind the keyboard. Thus the solution is unacceptable to me. Are there any better solutions out there?
Cheers,
I actually ran into a similar problem not too long ago. I stumbled upon the correct answer with a bit of work, though.
In your android manifest for this project, attached to the specific activity that you are using, use the line android:windowSoftInputMode="adjustPan|stateVisible" in the activity tag.
adjustPan basically means that your activity will not resize itself to fit the soft keyboard, and stateVisible means that the soft keyboard will show when requested (this can be stateAlwaysVisible, etc if necessary)
source :
Android Dev for Activity tags
After days of hardcore hacking I finally managed to construct a solution so advanced it might actually hurt to read it. I place an ImageView with the background behind the scrollview, and set scaleType="matrix" so it does not shrink when the keyboard is shown.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#color/black"
>
<ImageView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:src="#drawable/mah_kewl_background"
android:scaleType="matrix"
/>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fillViewport="true"
>
<RelativeLayout
android:id="#+id/smsLayout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="PLUNX"
/>
</RelativeLayout>
</ScrollView>
</RelativeLayout>
You can use the windowBackground property, which makes the drawable fit the whole screen.
To do that you need to:
1- Create a style:
<style name="Background" parent="#android:style/Theme.NoTitleBar">
<item name="android:windowBackground">#drawable/you_bg_drawable</item>
</style>
2- Set your activity style in the AndroidManifest.xml
<activity
android:name=".ui.your_activity"
android:theme="#style/Background"/>
I was googling for a solution to this exact problem when I came across this, and after doing some research I found a solution I think is slightly better. Instead of hacking with a ImageView you can use this from your activity:
getWindow().setBackgroundDrawableResource(R.drawable.bg_my_background);
Hope it helps anyone else searching for a solution for this.
I can't comment on your answer but I'd like to add something.
I understand your dilemma and why the solution you linked to isn't a complete solution for your situation (since you can't scroll to the bottom of the view). I have a similar situation with a large scrollable EditText box. When the soft keyboard pops up I don't like my background getting squished.
I have tried your solution and while at first glance it appears to work, there are some situations where it might not be ideal:
If you allow your app the have a landscape mode, the background will not resize/stretch
If you run your app on a device with a larger screen or dpi, your background may not fill the screen
Basically it seems that when you set the scaleType to matrix you're telling Android to draw the background 1:1 and not to scale. So what's happening when you open the soft keyboard using your solution is, your scrollView and imageView are all getting resized as usual, but the image src you set remains 1:1 thus continues showing the same area.
So if for example your background image was set to a specific size (e.g. 480 x 800) and it perfectly fills your Nexus One, the moment you rotate to landscape you will have a black area along the right.
This is moot, of course, if your background is simply a repeating pattern, in which case you can make it extremely large and hopefully compensate for various screens (maybe even tablets).
Or you can also supply different backgrounds for different screen sizes/densities/orientations, but this still doesn't account for scaling.
In a vain effort to try and solve this, I stumbled upon a View attribute called android:isScrollContainer. This attribute tells certain views whether or not they are allowed to resize upon display of the soft keyboard. This is also mentioned by someone in your linked solution. I have tried setting this (to false) on the ViewGroup containing my background, but any child element that scrolls seems override it causing the squishing again.
As of right now I don't think there is a complete solution for our situation. Your's definitely works in some instances and I thank you for the effort. Hopefully Google will offer a solution in the future, but I don't think they would consider this a problem/priority.
Maybe there's another (really simple!) solution:
In styles.xml:
create a new style like this:
<style name="Yourstyle" parent="AppBaseTheme">
<item name="android:windowBackground">#drawable/mybackground</item>
</style>
AppBaseTheme is your normally used theme for your app.
Then you add in Manifest.xml:
<activity
android:name="com.your.app.name.Activity"
android:theme="#style/Yourstyle">
</activity>
So you have the same style but with a background.
Important: don't set any backgrounds in your normal .xml file!
It's my first post and I hope it helps and sorry for my English.
in Androidmanifest in activity tag use:
<activity ... android:windowSoftInputMode="adjustPan" ></activity>
check Android Developer reference
How about a solution where the 'background' is a Layout. Can we inflate a layout, make it the entire window size, then insert it as a window background?
After a lot of time searching...
Put android:windowSoftInputMode="adjustPan|stateVisible" in each Activitys