My PopupWindow keeps stealing my EditText's focus - android

I have a simple "command dialog" that's a PopupWindow containing an EditText and a couple of buttons. I want the following behavior:
Touching outside the popup window dismisses it
When the popup appears, the EditText should grab (and keep) the focus
My EditText looks like this:
<EditText
android:id="#+id/send_cmd_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:maxLines="1"
android:hint="#string/send_cmd_hint"
android:textColor="#FFFFFF"
android:minEms="100"
android:layout_marginLeft="3dp"
android:layout_marginRight="3dp"
android:textColorHint="#BBBBBB"
android:inputType="text"
android:imeOptions="actionSend" >
<requestFocus />
</EditText>
The popup construction looks like this:
val popup = PopupWindow(view)
popup.isOutsideTouchable = true
popup.isTouchable = true
popup.isFocusable = true
popup.contentView = view
// This bizarre hack allows outside touching to dismiss it.
popup.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
sendButton.setOnClickListener {
sendCommand()
popup.dismiss()
}
if (A.isHardwareKeyboardAvailable()) {
// This only fires for the hardware keyboard.
editText.setOnKeyListener { _, code, event -> handleKey(code, event) }
} else {
setImeListener()
}
editText.requestFocus()
There seems to be a race condition occurring. I've got a hardware keyboard attached, and there are two ways to open the popup:
I can hit the Enter key, which the Activity notices, and then it calls the function to construct and show the popup.
I can press a button in my UI, which calls the same function.
Whenever I open the popup by pressing the button, the EditText gets the focus and everyone is happy.
Whenever I open the popup by pressing the Enter key on my hardware keyboard, the EditText gets the focus briefly, and then becomes unfocused. I suspect without proof that the PopupWindow is stealing the focus.
I need the popup to be focusable -- otherwise the keypresses simply go to the Activity, where it becomes difficult to route them back to the EditText.
I also need the popup to be outsideTouchable, so it will dismiss when you touch outside it.
I've tried setting isTouchable to false, but it seems to have no effect either way.
I've tried various oddball suggestions I've found related to this issue, such as calling popup.update() and so on. Nothing has solved the problem.
Again, this only happens when I have opened the popup by hitting the Enter key. The only difference I can see is that perhaps the Activity gets the focus temporarily before I create the popup, whereas if I press the UI button to open the popup, the Activity never gets the keyboard focus. Not sure, though.
The only thing that has worked for me is to set a timer:
android.os.Handler().postDelayed({ editText.requestFocus() }, 250)
This does the trick, but is obviously lame and fragile.
Any idea how to prevent my popup from stealing the focus from an EditText inside it?

Find the solution
final PopupWindow popUp = new PopupWindow(vbl.getMainLayout());
....
popUp.setFocusable(true);
popUp.update();

Related

Android, onClick of Button fires before completing the built in animation

I'm new to android development. Developing a flipflop game.
On click button changes the colour and then it checks if the two turned buttons match or not.
I haven't added any animation below is my on click code.
fun onButtonClick(view: View) {
val id = getResources().getResourceEntryName(view.id)
val btnItem = getButtonItem(id)
view.setBackgroundColor(Color.parseColor(btnItem.color))
btnItem.isTurned = true
btnItem.resId = view.id
checkMatch()
}
and here is what each button looks like
<Button
android:onClick="onButtonClick"
android:id="#+id/btn02"
android:layout_margin="5dp"
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight=".50"/>
The problem is, when I click the button, the colour is changed after finishing the onclick execution, not sure if it's setBackgroundColor which is taking time or the onClick itself delays this. Even If i put a Thread.sleep right after setBackgroundColor it will sleep and don't even change the colour.
In checkMatch i want to match the turned cards and if they don't match i set the background colour back. but this all completes before even showing the hidden colour.
What should I do to complete animation and set background colour and then proceed further ?
I hope this makes sense.

Android EditText Long Press Behaviour

I'm having some problems with the EditText in Android. Usually, when a user long clicks on the EditText or double-taps it, the word the cursor is in is highlighted, and the Contextual Actionbar (CAB) for the EditText pops up (on Android 3.0 and later).
My EditText did indeed do this until recently: the issue is that now long-pressing the EditText results in the selected word being "picked up", i.e. an enlargened "ghost" image of the word is picked up, and you can drag and drop it anywhere else in the text where it is inserted. I have not touched the code for the EditText at all. Anyone running Google Chrome (desktop version) can see the type of behaviour I mean if they highlight any text and drag it with their cursor.
I think the issue may have been caused by my device's upgrade to Android 4.2.2 recently. I have looked all over Google for information, but it has turned up nothing. Also, double-tapping the word also does not bring up the CAB as expected - it flashes for a second then goes away - but I do not think this is a related issue.
I really need this behaviour to stop, as my app cannot function without the CAB. So the question is: how can I get the "normal" behaviour back? All behaviour has been seen on a Nexus 4 running Android 4.2.2. All help is much appreciated; thank you very much!
XML Layout code for the EditText:
<EditText
android:id="#+id/editor_mainText"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_above="#+id/options_bottom"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_below="#+id/options_top"
android:background="#FFE7E7E7"
android:imeOptions="flagNoExtractUi"
android:inputType="textMultiLine|textNoSuggestions|textVisiblePassword"
android:padding="8dp"
android:scrollbars="none"
android:textCursorDrawable="#null"
android:textSize="17sp"
android:typeface="monospace" >
<requestFocus />
</EditText>
Note: My original answer was a bit wrong. I hadn't spotted my careless mistake in the code, but now that I have, here is why it didn't work
I've solved it, but I absolutely cannot explain why this behaviour happened in the first place, and why doing the following made any difference. But anyway, it did.
The EditText had been extended in order to make it "flingable" using a Scroller and VelocityTracker. This involved Overriding onTouchEvent(MotionEvent). But there was a little mistake in the code, where super.onTouchEvent(MotionEvent) would be called twice, as I had accidentally left out one of the break; statements in the switch-case, except during the MotionEvent.ACTION_MOVE event. The app worked fine even with this error all the way up to Android 4.2.1. I hadn't touched the code following the Android 4.2.2 upgrade, but for whatever reason, in the new version of Android, this small error triggered this weird behaviour.
So basically, it was a very basic mistake, and now I have learnt: always make sure to close off a case in a switch-case with a break statement!
I faced almost exact same behavior. I coudnt find any related question on stackoverflow, so will put my answer here. Maby it will be usefull for somebody. So if you ever faced a problem, that after closing copy/paste popup (by clicking anywhere on the screen) you cant select same text again (getting that "ghost" instead) all you have to do is manually disable textIsSelectable attribute and enable it again on view. For that i used this code im my ActivityMain. Poor solution, but its worked for me
override fun dispatchTouchEvent(ev: MotionEvent?): Boolean {
if (ev?.action == MotionEvent.ACTION_DOWN) {
val v = currentFocus
if (v is TextView || v is TextInputEditText) {
val outRect = Rect()
v.getGlobalVisibleRect(outRect)
if (!outRect.contains(ev.rawX.toInt(), ev.rawY.toInt())) {
val view = when (v) {
is TextView -> v
is TextInputEditText -> v
else -> null
}
view?.setTextIsSelectable(false)
view?.refreshDrawableState()
view?.setTextIsSelectable(true)
}
}
}
return super.dispatchTouchEvent(ev)
}

EditText: how to display the number while you are typing it?

I have three EditText widgets in my app and the XML for one of them is below. They work, mostly, but the problem is that the actual widget is at the bottom of my devices screen. When I tap the widget, and the numeric keypad is displayed, it completely covers the text entry window and I can't see what number I'm typing. Can I modify TextView so that when the Keypad is displayed on my device, it also displays the number that I'm currently typing?
<EditText
android:id="#+id/EditTextPrices" android:layout_width="100dip"
android:layout_height="wrap_content" android:inputType="number|numberDecimal"
android:singleLine="true" android.imeOptions="actionDone"/>
Another problem is that when I finish typing one number, instead of returning me to the main activity screen, it brings up the numeric keypad for the next TextEdit widget. I don't want this to happen. I had thought that setting android.imeOptions="actionDone" would cause the keypad to go away and be done when I finished typing the number, but not so. How can I stop the 'next' window from appearing?
Look into adding android:windowSoftInputMode to your manifest file. "adjustPan" as it's value is probably what you want though I've found that it sometimes fails to account for the space taken just above a softkeyboard by the strip of word-guesses while you're typing things in.
Add android:windowSoftInputMode=”adjustPan” to your manifest for the activity. That will cause the activity to scroll up so that the focused edit text is always on screen.
The other advice given to use adjustPan is good, and another idea is to put your layout in a scroll view.
Regarding your second problem, how are you handling actionDone?
For example this is how I hide the keyboard (or do whatever you want when they press done).
final EditText editTextPrices = (EditText) findViewById(R.id.editTextPrices);
editTextPrices.setOnEditorActionListener(new OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView view, int actionID, KeyEvent event) {
if (actionID == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) MyClass.this.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(bugemailaddress.getWindowToken(), 0);
// DO OTHER HANDLING OF INPUT HERE
return true;
}
return false;
}
});

Show/Hidden Soft Keyboard event in Android

I need to get the Show/Hidden event from the SoftKeyboard in Android.
I did a research, but nothing worked.
I wanted that 'cause we're working with a tablet 5.0'' with low resolution, so when you edit a EditText, the keyboard rise in full screen, and then or you press the "enter or next" key, or you press the back button to hide the keyboard... I need to update some fields with the new value, but I can't use the TextWatcher 'cause have some business logics on what's the right fields to update, and 'cause I just want to update when the user really finish the input.
And the onFocusChanged isn't a option, 'cause we don't want our customers needing to cliking in the next field, and hiding the keyboard to see the new values.
I don't want to override the onTouchEvent too, see if where the user cliked isn't the same field that he is editing.
Sorry for the specific problem and more specific solution that I'm asking for.
And sorry for my bad English :D
Use tree view observer to detect any change in view height and that time you can check whether keyboard state
final View activityRootView = findViewById(R.id.chat_pane_root_view);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
{
#Override
public void onGlobalLayout()
{
InputMethodManager mgr = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if(mgr.isAcceptingText())
{
//keyboard is up
}
}
});
First of all in your declairation of your activity in manifest file declaire like this
<activity android:name="Map" android:windowSoftInputMode="stateHidden">
from this property your keyboard is being hidden,
after this you are declaire the imeOption property in your main.xml file edittext like this
<EditText
android:id="#+id/edttexttitle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="5dp"
android:layout_marginTop="5dp"
android:hint="#string/tasktitle"
android:imeOptions="actionNext"
android:inputType="text"
android:textSize="#dimen/font_size_medium"
android:textColor="#color/darkgray1" />
this code is for your first edittext if more then one and if only one edittext then your need to change the imeOption of edittext like
android:imeOptions="actionGo"

Android show input keyboard only when user press a button

I have a PopupWindow in one Activity.
When user press on the list item in the activity, the window will popup for getting input from users.
There are some EditText in the window. And also I provided some buttons that preset some text on it, so when user press on it then it will enter to the edittext.
I can disable the softkeyboard when the window first popup. But when I change the focus on edittext (Move from one edittext to another edittext), the keyboard shown up.
I want the softkeyboard show only when user press on the "show keyboard" button in the popup window
How can I do it?
Updated:
public void onFocusChange(View view, boolean hasFocus) {
if (hasFocus) {
selectedEditText = (EditText)view;
String text = selectedEditText.getText().toString();
selectedEditText.setSelection(text.length());
InputMethodManager inputManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
inputManager.hideSoftInputFromWindow(selectedEditText.getWindowToken(), 0);
}
}
I tried the code above but it still showing.
set onFocusChangedListener() on every editText you have and disable Keyboard Pop inside it if it has focus..
Show it only when the user Presses the button..
There is very simple solution too; create fake focus above your EditText and you good to go.
Like this:
<LinearLayout
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
android:focusableInTouchMode="true">
</LinearLayout>
<!--Your EditText-->
<EditText
...
</EditText>
also you can add these two line above your mentioned EditText in any VIEW, like TextView and so on.
android:focusable="true"
android:focusableInTouchMode="true"
Go to the xml and find the activity in which you want to hide keyboard
add given attribute to the Activity..
android:windowSoftInputMode="stateAlwaysHidden"

Categories

Resources