Keyboard and Focus issue in PopupWindow - android

I am showing a popup window , if i initialize it as follows :
popupWindow.setBackgroundDrawable(new BitmapDrawable());
popupWindow.setFocusable(false);
And
#Override
public void onBackPressed() {
if (popupWindow.isShowing()) {
showConfirmationDialogForExit();
} else {
super.onBackPressed();
}
}
The Keyboard in my PopupWindow doesn't open ( the popupWindow has EditText ).
Also i have kept a dialog box to confirm the exit of the screen on Back Press which works.
Now opposite to this , if i keep
popupWindow.setFocusable(true);
The keyboard opens and works but the onBackPressed() doesn't check the
popupWindow.isShowing()
here my question is , i want to achieve the backpress check when the popup window is showing and also the keyboard needs to be worked when click on the EditText on that popupWindow.
The solutions i have gone through suggests me to keep
popupWindow.setFocusable(true);
but i am not be able to achieve the goals i am looking for.
Please guide me.

try
popWindow.setFocusable(true);
popWindow.update();
This updates the state of the popup window, if it is currently being displayed, from the currently set state.
If that don't work for you for some reason, you can always just set a local flag when you open the popWindow....
boolean popupshowing = true;
And then use that to check if it is open or not. (I agree it isn't the most elegant solution)

Related

Android - Memory leak with popup window in Recyclerview

I'm having trouble with the following error displaying in my app:
"E/WindowManager: android.view.WindowLeaked: Activity com.awt.myapp.MyList has leaked window android.widget.PopupWindow$PopupDecorView{84fdb1f V.E...... .......D 0,0-369,120} that was originally added here..."
Basically I've got a recyclerview and in the adapter I have a bunch of textviews in each row and am binding click listeners to them, as clicking one of these textviews brings up a popup window. The problem is if I hit the Android back button while a popup is still visible the above error appears.
I understand that in my activity that holds the recyclerview I can add an 'onBackPressed()' method, but from here I'm not sure how to get a reference to any of the popup windows within the adapter (and close it at this stage) as I believe this is what I need to do.
Below is my click listener code, I've experimented with some options and having setFocusable just causes the back button to stop working so not sure if that's needed.
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View moreInfoView) {
myPopupWindow.setBackgroundDrawable(new ColorDrawable());
//myPopupWindow.setFocusable(true);
myPopupWindow.setTouchable(false); // Ignores taps
myPopupWindow.setOutsideTouchable(true); // Disappear when tapping anywhere on screen
int position = -tv.getHeight();
myPopupWindow.showAsDropDown(tv, 0, position);
((MyList) context).onToggleMoreInfo("show");
myPopupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
#Override
public void onDismiss() {
((MyList) context).onToggleMoreInfo("hide");
}
});
}
});
Hopefully this makes sense, if you need any more info let me know. Any advice would be appreciated.
If you create a listener on your adapter that implements the activity and calls it when you click on the item, you can export popup window logic to activity and override on back pressed to dimiss it.

Empty space when I return to Activity (Soft Keyboard forced)

I have an ActionView with menu item on ActionBar (using ActionBarSherlock), I'm able to display an EditText as a search field in it. It's an input to launch another Activity with a CustomView in ActionBar which it displays the same layout (I don't use anything to force the SoftKeyboard to appear in this second activity, there is no problem here). When I want to make the Soft Keyboard appears/disapears automatically when the view collapse in first activity, I use:
openKeyboard method
mImm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
closeKeyboard method
mImm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);
I use the ActionExpandListener to make the SoftKeyboard appears or disappears when the View expands or collapse. With these two methods above, I have the expected result. I found this on several questions on SO (especially on Close/hide the Android Soft Keyboard and Showing the soft keyboard for SearchView on ActionBar or Forcing the Soft Keyboard open).
Just to understand, when I used SHOW_IMPLICIT or SHOW_FORCED alone, it was no effect on lower versions (as 2.+). The EditText was focused but the keyboard didn't show up (so, you guess it was a bad thing). In recent versions (as 4.+ for example), it was a nice effect and no problem. Then, I forced keyboard to show up with the openKeyboard method above.
Now, I got some troubles with this...
On lower versions, I got "empty" space before and after the keyboard created/destroyed, I can live with this. BUT in recent versions, I got "empty" space which it displays when I return to the first Activity. And it's here during less than one second, but sufficient to see that!
To better understand what happens, see the image below:
1. Second Activity: I press the Up Home Button - the keyboard disappears properly.
2. (back to) First Activity: my ListView is covered by a "empty" space (background color in my application). And it disappears (this is the same height of the SoftKeyboard, no possible doubt!)
I guess it's because I forced the keyboard to appear in my first activity although I also forced the keyboard to hide when I go the second, but how can I resolve the "empty" space when I return to the first activity?
Summary
1) A activity => press item in menu > view collapse > show the keyboard > tap text > send it > hide keyboard > launch B activity.
2) B activity => setCustomView in actionbar > show the keyboard only if the edittext is focused/clicked > tap text > send it > hide keyboard > refresh content > press home button > return to A activity
3) A activity => "empty" screen > screen disappears.
Any help will be very appreciate.
Thanks for your time.
EDIT
I add my code of my first class, to see if someone tells me what I'm doing wrong. Maybe it's my code which makes the issue.
Menu (ActionView)
ActionBar actionBar;
MenuItem itemSearchAction;
EditText mSearchEdit;
InputMethodManager mImm;
#Override
public boolean onCreateOptionsMenu(final Menu menu) {
getSupportMenuInflater().inflate(R.menu.main, menu);
itemSearchAction = menu.findItem(R.id.action_search);
View v = (View) itemSearchAction.getActionView();
mSearchEdit = (EditText) v.findViewById(R.id.SearchEdit);
itemSearchAction.setOnActionExpandListener(this);
return true;
}
OnActionExpandListener
#Override
public boolean onMenuItemActionExpand(MenuItem item) {
actionBar.setIcon(R.drawable.ic_app_search); // change icon
mSearchEdit.requestFocus(); // set focus on edittext
openKeyboard(); // the method above
mSearchEdit.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || (event != null && event.getKeyCode() == KeyEvent.KEYCODE_ENTER)) {
closeKeyboard(); // same method as above
// new Intent() to second activity
// perform with startActivity();
itemSearchAction.collapseActionView(); // collapse view
return true;
}
return false;
}
});
// add a clicklistener to re-open the keyboard on lower versions
mSearchEdit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
openKeyboard();
}
});
return true;
}
#Override
public boolean onMenuItemActionCollapse(MenuItem item) {
actionBar.setIcon(R.drawable.ic_app_logo); // change icon again
if(!(mSearchEdit.getText().toString().equals("")))
mSearchEdit.setText(""); // reinitial the edittext
return true;
}
OnOptionsItemSelected
// I had this verification when I make new Intent() to
// a new activity, just in case (works like a charm)
if(itemSearchAction.isActionViewExpanded())
itemSearchAction.collapseActionView();
ActionView (Item + layout)
<item
android:id="#+id/action_search"
android:icon="#drawable/ic_app_search"
android:title="#string/action_search"
android:showAsAction="ifRoom|collapseActionView"
android:actionLayout="#layout/search_actionview" />
<EditText
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/SearchEdit"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:layout_gravity="right|bottom" android:gravity="left"
android:layout_marginBottom="6dip"
android:hint="#string/action_search"
android:textColor="#color/white"
android:textColorHint="#color/white"
android:singleLine="true"
android:cursorVisible="true"
android:inputType="text"
android:imeOptions="actionSearch|flagNoExtractUi"
android:imeActionLabel="#string/action_search"
android:focusable="true" android:focusableInTouchMode="true"
android:background="#drawable/bt_edit_searchview_focused" >
<requestFocus />
</EditText>
UPDATE
I see a lot of similar issues, with EditText in ActionBar which not makes the keyboard appear even the focus has set. I tried this again (even if I already tested several time):
/*
* NOT WORKING
* Sources: https://stackoverflow.com/questions/11011091/how-can-i-focus-on-a-collapsible-action-view-edittext-item-in-the-action-bar-wh
* https://stackoverflow.com/a/12903527/2668136
*/
int mode = WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE;
getWindow().setSoftInputMode(mode);
postDelayed() to show: .showSoftInput(mSearchEdit, InputMethodManager.SHOW_IMPLICIT); - 200ms (Not working on lower versions)
postDelayed() to hide: .hideSoftInputFromWindow(mSearchEdit.getWindowToken(), 0); - 200ms
new Runnable() on edittext => requestFocus() + showSoftInput(SHOW_IMPLICIT/FORCED/HIDE_NOT_ALWAYS/HIDE_IMPLICIT_ONLY)
It seems with me, only SHOW_FORCED|HIDE_IMPLICIT_ONLY can force the keyboard to show automatically when the view collapse. After this, in all versions, I must to make a hideSoftInputFromWindow to 0 for hiding it.
BUT this undisplays the keyboard even if the edittext is pressed, so I added an ClickListener to force the keyboard to show again (this happens only on lower versions).
UPDATE2:
It's clearly weird, when I try to make a little Thread like I saw in many SO answers (with/without ABS), nothing happens in lower versions.
I tried a different way. I created the new thread to have a short time before call the new intent for hide the keyboard. I had the keyboard which forced to close, OK. And then I opened the new activity, OK. But now when I return, it's worth! The "empty" space is also on lower versions when I come back. I did this:
// close the keyboard before intent
closeKeyboard();
// make the intent after 500 ms
Handler handler = new Handler();
Runnable runner = new Runnable() {
public void run() {
// new intent with startActivity()
}
};
handler.postDelayed(runner, 500);
// collapse the View
itemSearchAction.collapseActionView();
It gives me headaches! I don't understand why in my case, the tip above not working whereas on other answers, when they use a new thread to show/hide the keyboard, this works perfectly.
NOTE: my tests were on (emulator:) GalaxyNexus, NexusS, NexusOne and (real devices:) Samsung GalaxySL (2.3.6) and Nexus4 (4.4).
If someone can help me with this ugly situation. Thanks in advance.
Did you tried this one?
setContentView(R.layout.activity_direction_3);
getWindow().getDecorView().setBackgroundColor(
android.R.color.transparent);
Remove Translucent theme:
android:theme="#style/Theme.AppCompat.Translucent"
and use your Activity in manifest.xml as:
<activity
android:name=".SearchActivity"
android:screenOrientation="portrait">
I had the same issue.
Try to add in Manifest, in First Activity:
android:windowSoftInputMode="adjustPan"
I have found the solution here:
Soft Keyboard pushes layout of my activity out of screen

Android - Edittext getting focus after dialog

I am calling a Dialog in an OnClick function in the OnCreate. In that dialog the user of the app can add something to a external database.
Now my problem is that when the dialog is gone ( myDialog.dismiss() ) and it is returning to the actual activity, an EditText is getting focussed. My whole screen contains Spinners and TextViews, except for only 1 EditText.
The weird thing is that when the activity is first called, it stats on top of the activity (showing the first Spinner and not foucssing the EditText), but when the dialog is dismissed, EditText is focussed.
I've got android:windowSoftInputMode="adjustResize|stateHidden" in the manifest within the activity tags
And i have tryed to put android:focusableInTouchMode="true" in the EditText in the XML too, but that didn't work.
Can anyone help me find what i'm looking for?
Thanks in advance!
Android will focus the first focusable View from the top so you can try set something else focusable :)
Android focus is somewhat random, you can't really control it. You could try to disable the textview and enable it again when the dialog is gone, but I would advice against it.
To be honest, just let Android do it's thing. We have tried to work against the focus logic in a really big app and gave up after a lot of tries and convinced the customer it's not worth the hassle.
I've been having this same problem. Try:
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
hideSoftKeyboard();
}
});
private void hideSoftKeyboard() {
View view = this.getCurrentFocus();
if (view != null) {
InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
This worked for everything except for a button in my dialog that has only an
onDismiss() method. Adding focusable=true and focusableInTouchMode=true to a TextView above my EditText (as Jeppe Andersen mentioned) solved this issue. Hope this helps.

How to close soft keyboard in fragment

I have an EditText inside a fragment, which is in itself inside an actionbarsherlock tab. When I touch inside the EditText box a soft keyboard appears with one of the keys having a magnifying glass (search) icon. When I type some text and click on the search key I can process the typed-in-string in my onEditorAction, but the soft keyboard remains on display. How can I close it programatically?
By the way if one answer is that I could configure some setting for EditText such that it closes automatically on search, I would still like to know if the soft keyboard can be closed with a method call as I also have my own search button on screen (nothing to do with the soft keyboard) and I would like the soft keyboard to close when that's pressed too.
Note: Before anyone rushes to claim this question is a repeat of a previous question, I have seen many Q&A's about hiding the soft keyboard at various points. Many of the answers seem inordinately complicated and in many it is not clear whether the idea is to permanently hide the keyboard or just just temporarily close it till the user taps on an EditText field again. Also some answers require calls to methods not available in fragments.
In my fragments I close the keyboard simply in this way:
public static void closeKeyboard(Context c, IBinder windowToken) {
InputMethodManager mgr = (InputMethodManager) c.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(windowToken, 0);
}
closeKeyboard(getActivity(), yourEditText.getWindowToken());
This is working code to hide soft keyboard for android.
try {
InputMethodManager input = (InputMethodManager) activity
.getSystemService(Activity.INPUT_METHOD_SERVICE);
input.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}catch(Exception e) {
e.printStackTrace();
}
I'm using this code in a fragment
InputMethodManager imm = (InputMethodManager)getActivity().getSystemService(
Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(text.getWindowToken(), 0);
when I click on an action bar icon and it's working, I don't see why it shouldn't work in your case (maybe I misunderstood the question).
You can check my answer here. It was the only way that worked for me inside fragment.
A clear way to close keyboard and clearfocus of an EditText inside a fragment, is to make sure that your EditText XML has :
android:id="#+id/myEditText"
android:imeOptions="actionDone"
Then set listener to your EditText (with Kotlin, and from a fragment):
myEditText.setOnEditorActionListener({ v, actionId, event ->
if (actionId == EditorInfo.IME_ACTION_DONE) {
myEditText.clearFocus()
val imm = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view!!.windowToken, 0)
}
false
})
Working in Fragment
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

android - show soft keyboard on demand

Hi I wrapped edittext control onto a control that is being displayed on the screen at users request. It overlays the whole screen until user presses 'done' button on the keyboard.
I am not able to explicitly show the control on the screen. only when user taps into control only then its shown. Am I missing something?
I even try this and it does not brin it up when I launch the overlay that Edit Text exists on:
customCOntrol.showKeyboard();
public void showKeyboard()
{
InputMethodManager imm = (InputMethodManager)_context.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(this._textView.getWindowToken(), InputMethodManager.SHOW_IMPLICIT);
}
here is the settig I have on the screen itself in the config file android:windowSoftInputMode="stateHidden|adjustPan"
Thank you in advance
In your showKeyboard function you are calling:
imm.hideSoftInputFromWindow(this._textView.getWindowToken(), InputMethodManager.SHOW_IMPLICIT);
This will hide the softInput keyboard from the window!
Do you want to show the keyboard? If yes then would you use:
imm.showSoftInput(view, flags, resultReceiver);
EDIT: I think you can also toggle the keyboard from the InputMethodManager, try:
imm.toggleSoftInput(0, 0);
#dropsOfJupiter
You can do: editText.requestFocus() as you launch the Activity or Fragment containing your EditText reference. This will give the focus to the EditText and will bring uo the SoftKeyboard.
I hope this helps.
PROBLEM:
I faced with this keyboard not showing up problem. I wrote the following solution inspired by this answer but not their solution! It works fine. In short the reason for this mess is that the request focus and the IMM provided service can only run on a view that is created and active. When you do all these on the creation phase onCreate(Bundle savedInstance).. or onCreateView(LayoutInflater inflater... and the view is still in initializing state, you won't get an active view to act on! I have seen many solutions using delays and checks to wait for that view to get active then do the show keyboard but here is my solution based on the android frame work design:
SOLUTION:
in your activity or fragment override the following make sure your view has the access (define it in the top of the activity/fragment):
#Override
public void onStart() {
yourView.requestFocus();
showSoftKeyboard(yourView);
super.onStart();
}
public void showSoftKeyboard(View view) {
if(view.requestFocus()){
InputMethodManager imm = (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.showSoftInput(view,InputMethodManager.SHOW_IMPLICIT);
}
}

Categories

Resources