My activity have a top bar and a bottom bar. the space between topbar and bottom bar i have a linearlayout with several edittext views inside. Because i don't want my layout resize every time the softkeyboard show up, so i set android:windowSoftInputMode="adjustPan" for my activity in manifest. But when the softkeyboard is openned, i want to scroll down to select another edittext to input, it's not allow me do that. Im only able to select the edittext at bottom when i close the softkeyboard. That's very annoying and inconvenient.
How can i get both scrollview and ajustpan mode for softkeyboard work well together?
Please help me out. thanks you so much.
At last, i find out a workaround for my problem, so i want to share for someone maybe get the same problem in future. A brief description of my layout as following:
<myRelativeLayout>
<topbar.../>
<myscrollView>
<linearLayout>
//all stuff controls:editview,textview,....
</linearLayout>
</myscrollView>
<bottombar.../>
i create custom class myRelativeLayout extend RelativeLayout
public class myRelativeLayout extends RelativeLayout{
public interface OnRelativeLayoutChangeListener {
void onLayoutPushUp();
void onLayoutPushDown();
}
private OnRelativeLayoutChangeListener layoutChangeListener;
public myRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
final int proposedheight = MeasureSpec.getSize(heightMeasureSpec);
final int actualHeight = getHeight();
if (actualHeight > proposedheight){
// Keyboard is shown
layoutChangeListener.onLayoutPushUp();
} else if(actualHeight < proposedheight){
// Keyboard is hidden
layoutChangeListener.onLayoutPushDown();
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setLayoutChangeListener(OnRelativeLayoutChangeListener layoutChangeListener) {
this.layoutChangeListener = layoutChangeListener;
}
public OnRelativeLayoutChangeListener getLayoutChangeListener() {
return layoutChangeListener;
}
}
And in my activity , i just set setLayoutChangeListener for myRelativeLayout to hide bottombar when softkeyboard show up and display bottombar when softkeyboard hide:
myRlayout.setLayoutChangeListener(new OnRelativeLayoutChangeListener() {
#Override
public void onLayoutPushUp() {
// TODO Auto-generated method stub
myBottombar.setVisibility(View.GONE);//in my case i need to setVisibility(View.GONE) to bottombar in order for this bar is not displayed when softkeyboard show up.
}
#Override
public void onLayoutPushDown() {
// TODO Auto-generated method stub
myBottombar.setVisibility(View.VISIBLE);// redisplay myBottombar when keyboard is closed.
}
});
Dont forget set android:windowSoftInputMode="adjustResize" for activity.
Hope this useful for someone got the same problem.
put those EditText in a ScrollView like this:
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/linearLayout1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="#+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<requestFocus />
</EditText>
<EditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<EditText
android:id="#+id/editText3"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
Related
This might look like a redundant and already answered query but I am stuck. I have browsed through previously shared plethora of responses but none of them turned out to be a holistic solution.
Here's how the main activity xml looks like:
<RelativeLayout >
<include
android:id="#+id/toolbar"
layout="#layout/toolbar" />
<ScrollView >
<LinearLayout >
<android.support.v7.widget.CardView >
<LinearLayout >
</LinearLayout>
</android.support.v7.widget.CardView>
<android.support.v7.widget.CardView >
</android.support.v7.widget.CardView>
</LinearLayout>
</ScrollView>
</RelativeLayout>
<android.support.design.widget.NavigationView />
The Problem
There is a edit text view in child linear layout of first card view. As of now, if I click on it, the keyboard pops up but doesn't hide when I click elsewhere or scroll the page or click any other view (there's a drop down).
What I plan to do is to hide the keyboard when,
1. I click anywhere outside the edit text view.
2. Scroll the page.
3. Interact with other views (the drop down).
Possible Solutions Tried
how to dismiss keyboard from editText when placed in scroll view - This one isn't working at all for me.
How to hide soft keyboard on android after clicking outside EditText? - There was one solution from #vida which worked partially, as in when clicked outside, the keyboard did dismiss. But then again, that's only a partial solution to what I am trying to achieve.
I would appreciate if someone could share a solution (or procedure) to sort this one out. Thanks!
You could try to override the Scroll Views onClickListener to call this method every time the user clicks anywhere on the app. If that doesnt work just set the outer relative layout to be clickable and everytime the layout is clicked you can call this hideKeyboard method!
public void hideKeyboard(View view) {
InputMethodManager im =(InputMethodManager)getSystemService(Activity.INPUT_METHOD_SERVICE);
im.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
First, extend EditText and add a snippet of code that helps dismiss the keyboard every time the EditText instances lose their focus
public class MyEditText extends AppCompatEditText {
public MyEditText(Context context) {
super(context);
setupEditText();
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setupEditText();
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setupEditText();
}
public void setupEditText() {
// Any time edit text instances lose their focus, dismiss the keyboard!
setOnFocusChangeListener(new View.OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && !(findFocus() instanceof MyEditText)) {
hideKeyboard(v);
} else {
showKeyboard(v);
}
}
});
}
public void hideKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
public void showKeyboard(View view) {
InputMethodManager inputMethodManager = (InputMethodManager) getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.showSoftInput(view, 0);
}
}
Then, set android:clickable="true" and android:focusableInTouchMode="true" in the child layout of your ScrollView!
Please note that, it should be the child layout of ScrollView, not ScrollView itself.
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:focusableInTouchMode="true"
android:orientation="vertical">
<MyEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</MyEditText>
</LinearLayout>
</ScrollView>
That should work!
I'm using TextInputLayout from Android Design Library to show label on EditText.
The problem is when I start activity with that EditText hint (label) text overlaps the actual text (for a second) and only then returns to its own place (at the top of the EditText).
To illustrate this issue I recorded a short sample video: https://youtu.be/gy0CzcYggxU
Here is my activity.xml:
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:orientation="vertical">
<android.support.design.widget.TextInputLayout
android:id="#+id/firstNameTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<EditText
android:id="#+id/firstNameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/first_name"
android:inputType="textCapWords"
android:textColor="#color/textPrimary"
android:textColorHint="#color/textSecondary"
android:textSize="16sp"
android:theme="#style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp">
<EditText
android:id="#+id/lastNameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/last_name"
android:inputType="textCapWords"
android:textColor="#color/textPrimary"
android:textColorHint="#color/textSecondary"
android:textSize="16sp"
android:theme="#style/CustomEditText"/>
</android.support.design.widget.TextInputLayout>
I came up with a cheap workaround for this and another bug.
Subclass the TextInputLayout
See code for addView()
If you have text set in the text view when it is inflated it will set the hint to collapsed and prevent an animation. This code performs a workaround that will temporarily set text until the state is set during setup. As a bonus there is code that makes sure the hint gets drawn just in case there is only one layout pass.
public class TextInputLayout extends android.support.design.widget.TextInputLayout {
public TextInputLayout(Context context) {
super(context);
}
public TextInputLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
#SuppressLint("DrawAllocation")
#Override
protected void onLayout(final boolean changed, final int left, final int top, final int right, final int bottom) {
if (ViewCompat.isLaidOut(this)) {
super.onLayout(changed, left, top, right, bottom);
} else {
// Workaround for this terrible logic where onLayout gets called before the view is flagged as laid out.
// The normal TextInputLayout is depending on isLaidOut when onLayout is called and failing the check which prevents initial drawing
// If there are multiple layout passes this doesn't get broken
post(new Runnable() {
#SuppressLint("WrongCall")
#Override
public void run() {
TextInputLayout.super.onLayout(changed, left, top, right, bottom);
}
});
}
}
#Override
public void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
EditText editText = (EditText) child;
if (StringUtils.isEmpty(editText.getText().toString())) {
editText.setText(" "); // Set filler text so the initial state of the floating title is to be collapsed
super.addView(child, index, params);
editText.setText(""); // Set back to blank to cause the hint to animate in just in case the user sets text
// This prevents the hint from being drawn over text that is set programmatically before the state is determined
return;
}
}
super.addView(child, index, params);
}
}
The workaround that worked for me was to update activity like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
...
textInputLayout.setHintAnimationEnabled(false);
textInput.setText("sample");
textInputLayout.setHintAnimationEnabled(true);
...
}
Finally found the adequate explanation of the issue:
Well it turns out that there was a performance optimization added to
the framework in Android 4.0 which allowed your view hierarchy only
one single draw pass before the Activity animation was started. Once
the Activity animation has ended, your view hierarchy is drawn every
~16ms as you expect.
Read more: https://medium.com/#chrisbanes
TLDR: it is platform limitation and this behavior will occur on older versions (Marshmallow and lower).
On Nougat animation will run as expected without the lag.
You can set the hints programmatically with a small delay. This is not a ideal solution, but at least it looks better than overlapping hints.
new Handler().postDelayed(
new Runnable() {
#Override
public void run () {
textInputLayout.setHint("My hint");
}
}, 100
);
I think this may be fixed for compile 'com.android.support:design:23.0.1'
Daniel Ochoa noted a workaround in the comments which worked for me - set the initial state for the EditText with some text content (an empty string should do it). That'll force the hint's initial state to be up.
<android.support.design.widget.TextInputLayout
android:id="#+id/firstNameTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp">
<EditText
android:id="#+id/firstNameEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/first_name"
android:inputType="textCapWords"
android:textColor="#color/textPrimary"
android:textColorHint="#color/textSecondary"
android:textSize="16sp"
android:theme="#style/CustomEditText"
android:text=" "/>
</android.support.design.widget.TextInputLayout>
I'm disabling the normal top action bar by using:
<style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
& I want to use a bottom action bar to have the done/cancel actions like this calendar app:
but when I try to write something to the editTexts available in the scrollView, the bottom action bar hides the fields, & I want it to be visible like also the calendar app below:
So, how can I achieve similar behavior? (so the bottom action bar won't hide any field when opening the soft keyboard),
I'm using code like this:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:custom="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="true"
android:orientation="vertical"
android:weightSum="1">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:fillViewport="false"
android:id="#+id/formScrollView">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<!-- all form fields goes here -->
</LinearLayout>
</ScrollView>
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/white"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:padding="#dimen/done_button_padding"
android:id="#+id/happeningDoneLayout">
<Button
android:id="#+id/doneButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="#string/done"
android:layout_alignParentBottom="true"/>
<Button
android:id="#+id/cancelButton"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:text="#string/cancel"
android:layout_alignParentBottom="true"/>
</FrameLayout>
</RelativeLayout>
Simplest thing to do is to prevent your layout from being resized when the virtual keyboard comes up:
<activity
android:name=".ShareFromDriveActivity_"
android:hardwareAccelerated="true"
android:label="#string/titleSharingCalendar"
android:launchMode="standard"
android:parentActivityName=".AppWidgetConfigure_"
android:screenOrientation="sensor"
android:theme="#style/Theme.Materialamberpurple"
android:windowSoftInputMode="stateHidden|adjustPan" >
<intent-filter>
<action android:name="de.kashban.android.picturecalendar.INTENT_ACTION_SHARE_FROM_DRIVE" />
</intent-filter>
</activity>
The important line is android:windowSoftInputMode="stateHidden|adjustPan". stateHidden ensures the keyboard is not opened up when starting the activity even if an EditText has focus.
adjustPan is what you are looking for: The Layout will no longer be resized (including your lower buttons), but the keyboad will overlay the layout. It is still possible to scroll them into the visible part, but when the keyboard comes up, they are not visible.
Source: Android Guides
Perhaps this setting alone will help your case.
If that's not enough and you require the Buttons to be really gone, try using this:
// Detect soft keyboard visibility changes
final SoftKeyboardStateHelper softKeyboardStateHelper =
new SoftKeyboardStateHelper(lyt_share_from_drive_main);
softKeyboardStateHelper.addSoftKeyboardStateListener(this);
SoftKeyboardStateHelper is a class from Artem Zinnatullin to detect state changes of the Softkeyboard:
/**
*
*/
package de.kashban.android.picturecalendar.util.local;
/**
* #author Artem Zinnatullin
* http://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android/9108219#9108219
* Usage: final SoftKeyboardStateHelper softKeyboardStateHelper = new SoftKeyboardStateHelper(findViewById(R.id.activity_main_layout);
* softKeyboardStateHelper.addSoftKeyboardStateListener(...);
*/
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
import java.util.LinkedList;
import java.util.List;
public class SoftKeyboardStateHelper implements ViewTreeObserver.OnGlobalLayoutListener {
public interface SoftKeyboardStateListener {
void onSoftKeyboardOpened(int keyboardHeightInPx);
void onSoftKeyboardClosed();
}
private final List<SoftKeyboardStateListener> listeners = new LinkedList<SoftKeyboardStateListener>();
private final View activityRootView;
private int lastSoftKeyboardHeightInPx;
private boolean isSoftKeyboardOpened;
public SoftKeyboardStateHelper(View activityRootView) {
this(activityRootView, false);
}
public SoftKeyboardStateHelper(View activityRootView, boolean isSoftKeyboardOpened) {
this.activityRootView = activityRootView;
this.isSoftKeyboardOpened = isSoftKeyboardOpened;
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(this);
}
#Override
public void onGlobalLayout() {
final Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);
final int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
if (!isSoftKeyboardOpened && heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
isSoftKeyboardOpened = true;
notifyOnSoftKeyboardOpened(heightDiff);
} else if (isSoftKeyboardOpened && heightDiff < 100) {
isSoftKeyboardOpened = false;
notifyOnSoftKeyboardClosed();
}
}
public void setIsSoftKeyboardOpened(boolean isSoftKeyboardOpened) {
this.isSoftKeyboardOpened = isSoftKeyboardOpened;
}
public boolean isSoftKeyboardOpened() {
return isSoftKeyboardOpened;
}
/**
* Default value is zero (0)
* #return last saved keyboard height in px
*/
public int getLastSoftKeyboardHeightInPx() {
return lastSoftKeyboardHeightInPx;
}
public void addSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
listeners.add(listener);
}
public void removeSoftKeyboardStateListener(SoftKeyboardStateListener listener) {
listeners.remove(listener);
}
private void notifyOnSoftKeyboardOpened(int keyboardHeightInPx) {
this.lastSoftKeyboardHeightInPx = keyboardHeightInPx;
for (SoftKeyboardStateListener listener : listeners) {
if (listener != null) {
listener.onSoftKeyboardOpened(keyboardHeightInPx);
}
}
}
private void notifyOnSoftKeyboardClosed() {
for (SoftKeyboardStateListener listener : listeners) {
if (listener != null) {
listener.onSoftKeyboardClosed();
}
}
}
}
In your activity implement the Interface SoftKeyboardStateListener and override these methods:
#Override
public void onSoftKeyboardOpened(int keyboardHeightInPx) {
if (D.DEBUG_APP) Log.d(TAG, "onSoftKeyboardOpened() called with keyboard height " + keyboardHeightInPx);
rdgVisibility.setVisibility(View.GONE);
if (tvPermissionLabel != null)
tvPermissionLabel.setVisibility(View.GONE);
lyt_ShareDriveOkCancel.setVisibility(View.GONE);
cbShareWithDev.setVisibility(View.GONE);
}
#Override
public void onSoftKeyboardClosed() {
if (D.DEBUG_APP) Log.d(TAG, "onSoftKeyboardClosed() called.");
rdgVisibility.setVisibility(View.VISIBLE);
if (tvPermissionLabel != null)
tvPermissionLabel.setVisibility(View.VISIBLE);
lyt_ShareDriveOkCancel.setVisibility(View.VISIBLE);
cbShareWithDev.setVisibility(View.VISIBLE);
}
In these two methods change the Visibility of your lower Buttons accordingly. Done.
Here's how it looks in my app:
Keyboard is closed, full layout visible
Keyboard is open, all controls but EditText gone. Reason is that the EditText could span several lines and on small screens it was too cluttered with the full layout in place.
To make sure the bottom action bar will not hide any other controls, the ScrollView and the bar can be stacked in a vertical linear layout. This allows the ScrollView to shrink/expand with the focused control visible when the keyboard appears/disappears, while keeping the bottom action bar always visible at the bottom of the screen below the ScrollView.
adjustPan should not be used with this solution.
The weights are distributed such that the ScrollView is the part that would change its height dynamically.
Here's a minimized sample of the code:
<?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">
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/formScrollView"
android:layout_width="fill_parent"
android:layout_height="match_parent"
android:layout_weight="1"
... >
...
</ScrollView>
<FrameLayout
android:id="#+id/bottomBar"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
... >
...
</FrameLayout>
</LinearLayout>
Android Keyboard hides EditText
android:windowSoftInputMode="adjustPan|adjustResize"
That should give you the effect your looking for. Put that in the manifest of the relevant activity.
possible duplicates
Android : autocompletetextview, suggestion list displays above the textview?
I am fully trying to display suggestion list overlapping on keyboard when suggestion list scroll by user but it always open up side.
here I am getting this way
here is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sl"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="8" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:label="#string/app_name"
android:name=".SuggestionListActivity"
android:windowSoftInputMode="adjustResize|adjustPan|stateHidden">
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
here is my main.xml file
<?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" android:padding="10dp">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/hello"
android:layout_margin="10dp"/>
<TextView android:layout_margin="10dp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="This is testing for the auto complete textview in this application to display suggestion list overlapping on keyboard." />
<AutoCompleteTextView android:id="#+id/autocomplete"
android:layout_width="fill_parent" android:layout_margin="5dp"
android:layout_height="wrap_content" android:hint="Search"
android:layout_marginLeft="5dp" android:dropDownHeight="300dp"
android:inputType="textAutoComplete" android:singleLine="true"
/>
</LinearLayout>
what to do in this code to display the suggestion over keyboard when list was focus.
I've had this problem before. For me, there was more screen space above the AutocompleteTextView than below (testing on a "normal" device), so the list opened upwards. I adjusted my layout slightly so that there was more space below the AutocompleteTextView and it started opening downwards. That's what fixed it for me.
You can either adjust the layout so that there is more space below the AutoCompleteTextView
or
you can change the dropdown height android:dropDownHeight and set some high value,
this would work when its inside a scrollView and the AutoCompleteTextView is near the top.
To display the list of options on focus do something like this
autoCompleteTextView.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus) {
autoCompleteTextView.showDropDown();
}
}
});
This would display a list of options when the user focuses on the AutoCompleteTextView
The trick is to ensure that the desired drop-down height is never larger than the available space below. My approach is to create a subclass that overrides showDropDown:
public class DownOnlyAutoCompleteTextView extends AppCompatAutoCompleteTextView {
private final static int MINIMAL_HEIGHT = 50;
public DownOnlyAutoCompleteTextView(Context context) {
super(context);
}
public DownOnlyAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public DownOnlyAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
public void showDropDown() {
Rect displayFrame = new Rect();
getWindowVisibleDisplayFrame(displayFrame);
int[] locationOnScreen = new int[2];
getLocationOnScreen(locationOnScreen);
int bottom = locationOnScreen[1] + getHeight();
int availableHeightBelow = displayFrame.bottom - bottom;
if (availableHeightBelow >= MINIMAL_HEIGHT) {
setDropDownHeight(availableHeightBelow);
}
super.showDropDown();
}
}
Then use this in your layout, e.g.:
<your.package.DownOnlyAutoCompleteTextView
android:id="#+id/auto_complete_text_view"
android:layout_margin="12dp"
android:hint="AutoComplete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:ignore="HardcodedText" />
Adjust MINIMAL_HEIGHT to fit your requirements -- if there's no or very little space below, it's probably better not to force the issue.
EDIT
As mentioned in the comments, passing a negative number to setDropDownHeight will trigger an exception in some Android versions. As long as you define a MINIMAL_HEIGHT greater than zero, that should not be a problem.
Here's my solution
private final static int DELAY_MS = 500;
autoCompletionTextView.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
autoCompletionTextView.requestFocus();
new Handler().postDelayed(() -> autoCompletionTextView.showDropDown(), DELAY_MS);
return false;
}
});
After keyboard shows up suggestion list is listed above yout AutoCompletionTextView.
use: android:dropDownHeight="wrap_content" in AutoCompleteTextView
Just adding the android:dropDownHeight="100dp" to the AutoCompleteTextView tag in your layout file will be the best solution I guess! it will simply control the height of drop down hight and allow us to scroll!
<AutoCompleteTextView
android:id="#+id/acetxt_assignclient"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:dropDownHeight="100dp">
</AutoCompleteTextView>
I have found if you are using a nested scroll view, it is more prone to open the view above or below as it sees fit where as when you are using a regular scroll view it opens below.
Set Full Layout containing Autocompletetextview inside Scrollview
This will solve your problem!
I have this layout:
<?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" >
<com.components.game.GameView
android:id="#+id/game_id"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
<RelativeLayout
android:id="#+id/ChatLayout"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="invisible"
android:focusable="true"
android:focusableInTouchMode="true" >
<Button
android:id="#+id/ChatCancelButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="X" />
<Button
android:id="#+id/ChatOkButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="OK" />
<EditText
android:id="#+id/ChatEditText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="#+id/ChatOkButton"
android:layout_toRightOf="#+id/ChatCancelButton"
android:maxLength="50"
android:singleLine="true" />
</RelativeLayout>
</RelativeLayout>
It's a RelativeLayout over a canvas. At start time it's invisible but when a user clicks a button the layout should become visible.
The problem is that it's not becoming visible. The layout is there but it's just not drawing it. If I press the position where the layout should appear it receives the event and opens the keyboard but it's not drawing the whole layout.
What is the problem?
If I set the RelativeLayout to visible at the beginning it works fine. it shows the layout and if I toggle between invisible and visible it works fine.
I made a workaround that almost always works.
I start the layout visible and than do that in the oncreate:
chatLayout.postDelayed(new Runnable() {
#Override
public void run() {
chatLayout.setVisibility(View.INVISIBLE);
}
}, 50);
But I don't like it and want to understand what's the problem.
The code:
It starts from a canvas button which send a message to a handler:
public void showInputLayout() {
Message.obtain(gameHandler, SHOW_INPUT_LAYOUT).sendToTarget();
}
In the handler:
case SHOW_INPUT_LAYOUT:
gameActivity.setChatVisibility(true);
break;
setChatVisibility:
public void setChatVisibility(boolean isVisible) {
int visible = isVisible ? View.VISIBLE : View.INVISIBLE;
chatLayout.setVisibility(visible);
if(isVisible){
chatEditText.setFocusable(true);
chatEditText.requestFocus();
}
}
Add a click listener to RelativeLayout and switch the visibility between GONE and VISIBLE. Try something like this:
int visibility = View.VISIBLE;
RelativeLayout layout = (RelativeLayout)findViewById(R.id.ChatLayout);
layout.setVisibility(visibility);
layout.setOnClickListener(new View.OnClickListener{
public void onClick(View v)
{
if(visibility == View.VISIBLE)
visibility = View.GONE;
else
visibility = View.VISIBLE;
v.setVisibility(visibility);
}
})
I ran into a similar issue recently, and for my case the problem was actually in the onDraw() method of the view underneath (should be com.components.game.GameView in your case). See if you can add calls to Canvas' getSaveCount(), save() and restoreToCount() in your drawing code, similar to this:
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int saveCount = canvas.getSaveCount();
canvas.save();
// custom drawing code here ...
// use Region.Op.INTERSECT for adding clipping regions
canvas.restoreToCount(saveCount);
}
I believe what happened was that sometimes the framework set the clipping regions for the elements on top of our Canvas-drawing widget before our onDraw() method is called so we need to make sure that those regions are preserved.
Hope this helps.