I have a fragment with 2 TextInputEditText. When my activity starts, the soft keyboard covers part of my input, and when clicking NEXT on the keyboard the focus passes to the second input that is completely covered by the keyboard. It´s possible to see what has been typed only when I close the keyboard.
This is my layout:
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
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"
xmlns:tools="http://schemas.android.com/tools"
android:background="#drawable/back_gradient"
android:orientation="vertical"
android:padding="#dimen/DP10"
tools:context=".activities.MainActivity">
<TextView
android:id="#+id/tv_new_course_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/SP22"
android:layout_marginBottom="150dp"
android:text="#string/newCourse"
android:textColor="#color/colorPrimary"
android:textSize="#dimen/SP26"
android:textStyle="bold"/>
<com.google.android.material.textfield.TextInputLayout
style="#style/LoginTextInputLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/DP20"
android:layout_marginRight="#dimen/DP20"
android:hint="#string/courseName">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/et_new_course_name"
style="#style/LoginTextInputEditStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress"
android:nextFocusDown="#+id/et_new_course_acronym"
/>
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
style="#style/LoginTextInputLayoutStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/DP20"
android:layout_marginRight="#dimen/DP20"
android:hint="#string/acronym">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/et_new_course_acronym"
style="#style/LoginTextInputEditStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textEmailAddress" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.button.MaterialButton
android:id="#+id/btn_save_course"
style="#style/Widget.MaterialComponents.Button.OutlinedButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="#dimen/DP40"
android:layout_marginBottom="#dimen/DP10"
android:text="#string/save"
android:textColor="#color/color_ok"
app:cornerRadius="#dimen/DP15"
app:strokeColor="#color/color_ok"
app:strokeWidth="#dimen/DP2" />
The same layout works fine if inflated on an activity, but here it´s a fragment.
There are multiple ways to remove the problem:
Process 1
Use a ScrollView as the root layout and put all the other layouts inside it.
Process 2 (recommended)
Use android:windowSoftInputMode="adjustPan|adjustResize" in your manifest file.
More detail about this is here.
please add this in your activity attribute in the manifest
<activity android:name="Your_Activity" android:windowSoftInputMode="adjustPan" ></activity>
Related
Have a Xamarin Android app but I am sure this question applies to non-Xamarin as well. Most of my fragments have EditText controls. Each time they receive focus, the soft keyboard shows as expected. However, the soft keyboard will cover my EditText boxes on the lower half of the View.
I saw that I can set the following in either the Activity class attribute or the manifest. I am setting this in the Activities class attribute:
[Activity(Label = "MainActivity", ScreenOrientation = ScreenOrientation.Portrait, Theme = "#style/AppTheme", LaunchMode = LaunchMode.SingleTask, WindowSoftInputMode = SoftInput.AdjustResize)]
As you can see, I am setting WindowSoftInputMode to AdjustResize. The good news is that I can confirm that this does in fact work for the EditText controls that are on the actual MainActivity.
However, from my MainActivity which works, I also put fragments in to a FrameLayout. So, my MainActivity axml looks 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">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:animateLayoutChanges="true"
android:background="#drawable/sortingpackages">
<LinearLayout
android:id="#+id/LayoutControls"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="#FFFFFF"
android:animateLayoutChanges="true"
android:layout_marginTop="10dp">
<ImageView
android:src="#drawable/odenlogotransscaled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/imageView1"
android:layout_marginTop="0.0dp"
android:layout_marginBottom="0.0dp"
android:layout_centerInParent="true"
android:layout_gravity="center_horizontal" />
<Spinner
android:layout_width="220dp"
android:layout_height="40dp"
android:id="#+id/spSelectLocation"
android:layout_margin="10dp"
android:spinnerMode="dialog"
android:dropDownWidth="220dp"
style="#style/SpinnerOdenTheme" />
<EditText
android:layout_width="220dp"
android:layout_height="35dp"
android:id="#+id/tbUserLogin"
android:layout_margin="10dp"
android:hint="#string/UserLogin"
android:ellipsize="start"
android:gravity="left"
android:inputType="text"
android:background="#drawable/EditTextStyle"
android:cursorVisible="true"
android:textColorHint="#000000"
android:padding="3dp" />
<Button
android:text="#string/Login"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:id="#+id/btnLogin"
android:layout_margin="10dp"
style="#style/TextButtonOdenTheme" />
<Button
android:text="#string/Exit"
android:layout_width="220dp"
android:layout_height="wrap_content"
android:id="#+id/btnLogoutExit"
android:layout_margin="10dp"
style="#style/TextButtonOdenTheme" />
</LinearLayout>
<Button
android:text="#string/Settings"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/btnSettings"
android:layout_margin="10dp"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
style="#style/TextButtonOdenTheme" />
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:id="#+id/LoginFragmentContainer"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
</RelativeLayout>
You can see I put the FrameLayout for the Fragment Container towards the bottom. Any fragment I swap into this FrameLayout using the Support Fragment Manager, does not respect the Soft keyboard setting and resize or pan (I have tried both settings).
I have also tried wrapping either the FrameLayout or the whole Layout inside of a ScrollContainer as suggested by a post I was reading and nothing fixes the problem.
Anybody else have an issue getting the fragments in a FrameLayout to adjust to the soft keyboard and how do I fix it?
Thanks!
I have an XML layout in a second Activity that shows one of two LinearLayouts based on if a user is logged in or not, and the TextView I have never shows the text in the app, but it does render it correctly when I look at the "Design" panel in the layout editor
The TextView is there (if I set a background color, it shows that color) but the Text itself never renders.
Clicking a button on MainActivity results in starting the LoginActivity, which has the onCreate (it's Kotlin):
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.login_layout)
And layout:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:visibility="gone"
android:id="#+id/loggedOut"
android:padding="24dp">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/passName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:hint="Username"
android:inputType="textCapCharacters" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/passPin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:focusable="true"
android:hint="PIN"
android:inputType="numberPassword" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/passSubmit"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login" />
</LinearLayout>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:id="#+id/loggedIn"
android:visibility="visible"
android:padding="24dp">
<TextView
android:id="#+id/loggedInMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="You're currently logged in"
android:textAlignment="center"
android:textAppearance="#android:style/TextAppearance.Material.Headline" />
<Button
android:id="#+id/passLogout"
style="#style/Widget.AppCompat.Button.Colored"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Logout" />
</LinearLayout>
</FrameLayout>
This is what Android Studio shows (those errors are TextInputLayout bugs where it says it can't find the hide password icon and such)
And this is what my device shows
Edit: I've removed everything in the layout file except for the TextView and a parent LinearLayout and it's still not showing.
Found the issue. Switching android:text="You're currently logged in" to android:text="You\'re currently logged in" fixed it. So I guess Android requires escaping single quotes when setting the text in XML?
Found by using the layout inspector tool, which showed mText as having no value
I have an AutoCompleteTextView in my XML file:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.aashima.premiumpoint.PremiumPoint">
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/searchByName"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="10dp"
android:background="#ddd"
android:hint="Search By Name"
android:textColorHint="#fff"
android:gravity="center"
android:layout_alignTop="#+id/searchImageButton"
android:layout_alignBottom="#+id/searchImageButton"
android:layout_toLeftOf="#+id/searchImageButton"
android:textColor="#fff"
android:completionThreshold="1"
android:imeOptions="actionDone"
android:dropDownWidth="fill_parent"/>
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/searchImageButton"
android:src="#drawable/search40"
android:layout_alignParentRight="true"
android:padding="2dp"
android:background="#color/material_blue_grey_950"/>
</RelativeLayout>
I don't want it to gain focus when my Activity starts.
I tried giving the following to the parent layout:
android:descendantFocusability="beforeDescendants"
android:focusableInTouchMode="true"
giving a dummy item just above my AutoCompleteTextView:
<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
and setting:
android:nextFocusUp="#id/searchByName"
android:nextFocusLeft="#id/searchByName"
to AutoCompleteTextView .
On searching I found results similar to:
android:windowSoftInputMode="stateHidden"
android:windowSoftInputMode="stateUnchanged"
but what I want is prevent it from getting focus and not hiding the keypad from appearing.
I've tried many alternatives with no luck. Am I doing something wrong here?
Thanks in advance.
EDIT:
Also attempted:
clearFocus();
requestFocus();
Try combining 2 of your methods as follows:
<!-- Dummy item to prevent AutoCompleteTextView from receiving focus -->
<LinearLayout
android:focusable="true"
android:focusableInTouchMode="true"
android:layout_width="0px"
android:layout_height="0px"/>
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/searchByName"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:padding="10dp"
android:background="#ddd"
android:hint="Search By Name"
android:textColorHint="#fff"
android:gravity="center"
android:layout_alignTop="#+id/searchImageButton"
android:layout_alignBottom="#+id/searchImageButton"
android:layout_toLeftOf="#+id/searchImageButton"
android:textColor="#fff"
android:completionThreshold="1"
android:imeOptions="actionDone"
android:dropDownWidth="fill_parent"
android:nextFocusUp="#id/searchByName"
android:nextFocusLeft="#id/searchByName"/>
Now, bring the dummy View and your AutoCompleteTextView to your java code and use:
dummy.requestFocus();
search.clearFocus();
and vice versa as and when you require.
I have EditText that is wrapping content as required; however, when the virtual Keyboard in visible on screen, I am unable to scroll the text vertically to display the lines on top that are hidden from view (e.g., first line when I am typing "android:lines"+1 line). When I hide the keyboard, it starts scrolling normally.
Layout File:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/console_scroll"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp"
android:id="#+id/repl_container">
<TextView
android:id="#+id/console"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textIsSelectable="true"
android:gravity="left|top"
/>
<ProgressBar
android:id="#+id/progress_running"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:indeterminate="true"
android:visibility="invisible"
style="Widget.ProgressBar.Small"
/>
<EditText
android:id="#+id/code_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text|textNoSuggestions|textMultiLine"
android:imeOptions="actionNone"
android:imeActionLabel="#string/button_eval"
android:hint="#string/input_code_hint"
android:singleLine="true"
android:gravity="left|center_vertical"
android:layout_marginTop="10dp"
android:scrollHorizontally="false"
android:lines="5"
android:maxLines="100"
/>
<Button
android:id="#+id/button_eval"
android:text="#string/button_evaluate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:gravity="center"
/>
</LinearLayout>
</ScrollView>
I am observing this on KK 4.4.4, if it matters. Any pointers as to why this might be happening?
in your manifest.xml, add android:windowSoftInputMode="adjustPan|adjustResize" under your activity tag.
LIKE THIS:
<activity android:name="......"
.....
android:windowSoftInputMode="adjustPan|adjustResize">
......
/>
OK, so I have this very basic layout:
As you can see, the edit texts and the login button are centered in the area below the icon. They are not aligned with the bottom. And I want to keep it this way.
Now, when the soft keyboard is shown, all I want is that the whole view is pushed upwards, so that the login button is above the soft keyboard but takes into account its lower margin.
My activity has windowSoftInputMode set to adjustPan, but it just assures that the currently focused control is visible, not all three of them:
Question: What do I need to change so that all three controls are visible as soon as the keyboard is visible?
This is my view:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res/Recson.Apps.Android"
style="#style/Theme.Recson.NoActionBar"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/LoginViewRoot">
<ImageView
android:src="#drawable/Logo"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/Icon"
android:layout_marginBottom="30dp"
android:layout_marginTop="30dp"
android:layout_gravity="top" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/Credentials"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:layout_below="#id/Icon">
<EditText
android:inputType="textEmailAddress"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="Text Username"
android:hint="#string/Username"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:textColorHint="#color/text_hint" />
<EditText
android:inputType="textPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
local:MvxBind="Text Password"
android:hint="#string/Password"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:textColorHint="#color/text_hint" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="#string/Login"
local:MvxBind="Click Login;Enabled CanLogin"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp"
android:layout_marginBottom="30dp" />
</LinearLayout>
</RelativeLayout>
Try to use ScrollView and put your main layout inside it. I think it will do the job.
Try this in Manifest file.
<activity name="ActivityName"
android:windowSoftInputMode="stateVisible|adjustResize">
...
</activity>
As you're experiencing, adjustPan, adjustResize etc will only try to ensure the currently focused input field is visible.
What you could try to do is remove the LinearLayout then position your username password and login views in such a way that the system thinks they occupy the same space by using layout_marginTop and layout_marginBottom.
Just put this in your activity tag of your menifest file:
android:configChanges="screenSize"
And Use ScrollView in your Xml file something like below:
(I have changed your layout a bit):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/LoginViewRoot"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/Icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginBottom="30dp"
android:layout_marginTop="30dp"
android:src="#drawable/ic_launcher" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="#+id/btnLogin"
android:layout_below="#id/Icon" >
<LinearLayout
android:id="#+id/Credentials"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="vertical" >
<LinearLayout
android:id="#+id/Credentials1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:gravity="center_vertical"
android:orientation="vertical" >
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:inputType="textEmailAddress" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:inputType="textPassword" />
</LinearLayout>
</LinearLayout>
</ScrollView>
<Button
android:id="#+id/btnLogin"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="20dp"
android:text="Login" />
</RelativeLayout>
At least, the answers here show that I wasn't missing anything obvious.
I now solved it like that:
windowSoftInputMode set to adjustResize
Complete layout inside a ScrollView
On layout change, I simply scroll down the ScrollView to the bottom:
public class LoginView : MvxActivity, ViewTreeObserver.IOnGlobalLayoutListener
{
private ScrollView _activityRootView;
public void OnGlobalLayout()
{
var focusedControl = Window.CurrentFocus;
_activityRootView.FullScroll(FocusSearchDirection.Down);
if (focusedControl != null)
focusedControl.RequestFocus();
else if (Window.CurrentFocus != null)
Window.CurrentFocus.ClearFocus();
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.LoginView);
_activityRootView = FindViewById<ScrollView>(Resource.Id.LoginViewRoot);
_activityRootView.ViewTreeObserver.AddOnGlobalLayoutListener(this);
}
}
(this is C# code using Xamarin.Android and MvvmCross. It is based on this answer)
This solution has one drawback: The controls are no longer centered in the area below the icon, but right now, I am OK with that:
See it in action
Used This Code :
public MainPage()
{
InitializeComponent();
App.Current.On<Android>().UseWindowSoftInputModeAdjust(WindowSoftInputModeAdjust.Resize);
}