I created an activity which should have the keypad always popped up. So, I used requestFocus() for the edittext. But I don't want only keypad disappear. Instead I want the whole activity to finish() when back button is pressed even when keypad is present. I tried this answer, but it didn't work. I tried this too though it looked a bit extra work, but this isn't working with textwatcher. Below is the edittext. I kept it's dimension attributes to 0dp because to avoid showing user even the password field. Any help on achieving this is appreciated. Please let me know if any further information is needed.
<EditText
android:layout_width="0dp"
android:layout_height="0dp"
android:id="#+id/passwordet"
android:inputType="number"
/>
P.S: Overriding onBackPressed() doesn't work because it doesn't get fired when keypad is present on Activity.
You can override the onBackPressed method to finish the activity:
#Override
public void onBackPressed() {
finish();
}
Extend EditText and add following method.
public class MyEditText extends EditText {
OnKeyListener onKeyListener = null;
public static int BACK_KEY = 10001;
public void setOnKeyListener(OnKeyListener l) {
super.setOnKeyListener(l);
onKeyListener = l;
Log.i(TAG, "setOnKeyListener Called");
}
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
Log.i(TAG, "onKeyPreIme");
if (keyCode == KeyEvent.KEYCODE_BACK
&& event.getAction() == KeyEvent.ACTION_UP) {
if (onKeyListener != null) {
onKeyListener.onKey(this, BACK_KEY, event);
}
return false;
}
return super.dispatchKeyEvent(event);
}
}
And from activity
editText.setOnKeyListener(this);
and handle on onKey method
You need to create a custom EditText in order to capture keyBoardDismissEvent.
You can try something like this:
public class CustomEditText extends EditText {
private OnKeyboardDismissListener listener;
public void setOnKeyBoardDismissListener(OnKeyboardDismissListener listener) {
this.listener = listener;
}
public CustomEditText(Context context) {
super(context);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && listener != null)
listener.onKeyBoardDismiss();
return super.onKeyPreIme(keyCode, event);
}
static interface OnKeyboardDismissListener {
void onKeyBoardDismiss();
}
}
In layout
<YourPackageName.CustomEditText android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
Inside Activity:
CustomEditText editText = (CustomEditText) findViewById(R.id.editText);
editText.setOnKeyBoardDismissListener(new OnKeyboardDismissListener() {
#Override
public void onKeyBoardDismiss() {
MainActivity.this.finish();
}
});
Related
When I am writing something in EdiText and pressing the back button, it is hiding the keyboard, which is perfect. But I want to handle this Back Button Click when Keyboard is open for EditText. The reason is I want to clear EditText's text when the back button is pressed when the keyboard is open.
Activity method onBackPressed() is not called when keyboard is open for EditText.
I checked here but didn't help though.
Any help would be appreciated.
You can use custom edittext and implement onKeyPreIme to listen backPressed
public class MyEditText extends androidx.appcompat.widget.AppCompatEditText {
private MyEditTextListener listener;
public interface MyEditTextListener {
void callback();
}
public void setListener(MyEditTextListener listener) {
this.listener = listener;
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
listener.callback();
return true;
}
}
activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MyEditText myEditText = findViewById(R.id.myEditText);
myEditText.setListener(new MyEditText.MyEditTextListener() {
#Override
public void callback() {
//handle backPressed event when keyboard have shown
}
});
}
I did few modifications to #GuanHongHuang's answer and now I am able to do this by these 3 steps:
1. Creating Custom EditText Class to handle Back Press:
public class CustomEditTextWithBackPressEvent extends androidx.appcompat.widget.AppCompatEditText {
private MyEditTextListener onBackPressListener;
public CustomEditTextWithBackPressEvent(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setOnBackPressListener(MyEditTextListener onBackPressListener) {
this.onBackPressListener = onBackPressListener;
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK &&
event.getAction() == KeyEvent.ACTION_UP) {
//back button pressed
if (Objects.requireNonNull(ViewCompat.getRootWindowInsets(getRootView())).isVisible(WindowInsetsCompat.Type.ime())) {
//keyboard is open
onBackPressListener.callback();
}
return false;
}
return super.dispatchKeyEvent(event);
}
public interface MyEditTextListener {
void callback();
}
}
2. Replace your normal EditText with this CustomEditTextWithBackPressEvent in XML
<CustomEditTextWithBackPressEvent
android:id="#+id/etSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/search_hint"
android:imeOptions="actionSearch"
android:inputType="text"
android:maxLines="1" />
3. Handle Back Press:
binding.etSearch.setOnBackPressListener(() -> {
//handle click
//your code here
});
I have created a window and i am showing it on screen through Broadcast receiver.But the problem is that it appears on the screen and i want to dismiss it once the back button is pressed.I am unable to get the event of button press on this view.My code for back press looks as follows-
view.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getKeyCode() == KEYCODE_BACK) {
Log.d("LOG", "back button is pressed");
}
return true;
}
});
But Nothing is happening.I tried to do the same through DISPATCHKEY but it was also of no use.Please help me what i am not figuring out.Wouldn't this work on the view.?
Maintain global reference for Window and override onBackPressed()
Try this:
#Override
public void onBackPressed() {
if (view != null && view.isShowing()) {
view.dismiss();
} else {
super.onBackPressed();
}
}
In my activity, the soft keyboard should more or less always be open. So when a user presses the back button, the activity should finish like normally. However, the default Android behavior is to close the keyboard instead when it is open. This makes the user have to click twice to exit the activity. How can I override this behavior so that the activity always finishes when the back button is pressed, even when the soft keyboard is open? Is there some simple way to do this?
I'm sure this is a common problem, but I did not find this direct question.
I have same situation.I tried so many ways finally i got solution. Here i will share with you. I have solved this using CustomEditText.
CustomEditText.Java
public class CustomEditText extends android.support.v7.widget.AppCompatEditText {
public CustomEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
OnKeyPreImeListener onKeyPreImeListener;
public void setOnKeyPreImeListener(OnKeyPreImeListener onKeyPreImeListener) {
this.onKeyPreImeListener = onKeyPreImeListener;
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_UP) {
if(onKeyPreImeListener != null)
onKeyPreImeListener.onBackPressed();
return false;
}
return super.dispatchKeyEvent(event);
}
public interface OnKeyPreImeListener {
void onBackPressed();
}
}
MainActivity.Java
public class MainActivity extends BaseActivity{
private CustomEditText editSearchMenu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editSearchMenu =
(CustomEditText)findViewById(R.id.editSearchMenu);
//Initialise interface
CustomEditText.OnKeyPreImeListener onKeyPreImeListener=new CustomEditText.OnKeyPreImeListener() {
#Override
public void onBackPressed() {
((MainActivity)getActivity()).finish();
}
};
editSearchMenu.setOnKeyPreImeListener(onKeyPreImeListener);
}
}
xml file
<com.app.helper.CustomEditText
android:id="#+id/editSearchMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="#dimen/diam5dp"
android:background="#drawable/custom_rounded_edittext"
android:drawableLeft="#drawable/ico_search"
android:drawablePadding="#dimen/diam20dp"
android:drawableStart="#drawable/ico_search"
android:hint="#string/M_SEARCH_HINT"
android:padding="#dimen/diam10dp"
android:textColor="#android:color/white"
android:textColorHint="#android:color/white"
android:textSize="#dimen/diam16sp" />
Hope this will help you...this works in every devices i have tested my self...other solutions are creating problems in some devices..there will be some other solution also...if you get something let me know...
You should implement TextWatcher.
Here is the the code of you requirement.
public class MainActivity extends AppCompatActivity implements TextWatcher{
EditText editTextt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
editTextt = (EditText) findViewById(R.id.editTextt);
editTextt.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable s) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(before == count + 1)
{
finish();
}
}
}
I use this method to hide the keyboard
//hides keyoard
private void hideSoftKeyboard(View v) {
InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
}
Try this.
mEditText.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
finish();
return false;
}
});
You can hide Keyboard and finish Activity.
If you use Dialog,you can do like this.
mDialog.setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
if (isShowDialog) {
isShowDialog = false;
mDialog.dismiss();
context.finish();
}
}
return false;
}
});
Note: It also can use in Dialog.Dismiss Dialog and do something.And you can use v、 keyCode、 event.And it can be used by most View.
I am starting my softkeyboard in my ActivityB with this lines in my manifest
<activity android:name=".ActivityB"
android:label="#string/title_activity_activity_b"
android:windowSoftInputMode="stateAlwaysVisible" >
</activity>
Now I would like that when I press a back button I exit(finish) the activity immediately. I would like to press back button only once to exit the activity.
Right now I have to first press back button once to lower the soft-keyboard and press the back button again for the second time to exit activity.
Is this possible and how can I do that? I tried various common techniques from this site but none of them worked. I use LG L50 for development.
EDIT: I am extending activity and not appcompatactivity
EDIT 2: The program works now, here is the code
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}}
MyEditText.java
package com.example.actionbarimagetest;
import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
public class MyEditText extends EditText implements OnClickListener {
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyEditText(Context context) {
super(context);
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public void FlashBorder()
{
//do some custom action
}
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
EditText txt = (EditText) v;
txt.selectAll();
}
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
System.out.println("KEYCODE BACK");
((Activity)getContext()).finish();
return true;
}
return super.onKeyPreIme(keyCode, event);
}
}
activity_main.xml
<?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">
<com.example.actionbarimagetest.MyEditText
android:id="#+id/edtTaskName"
android:layout_height="wrap_content"
android:layout_width="match_parent"/>
</LinearLayout>
Just override activity method and finish explicitly
#Override
public void onBackPressed() {
finish();
}
UPDATED2
Yes, this doesn't work for such case. But I've tried few solutions and one of them did work. You need to extend EditText and override method:
#Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
((Activity)getContext()).finish();
return true;
}
return super.onKeyPreIme(keyCode, event);
}
Note:
don't forget to replace your previous EditText in layout xml with new extented class
call the following function on your backbutton wherever and whatever:
yourMethod()
{
// close keyboard
InputMethodManager mgr = (InputMethodManager) TempActivity.this.getSystemService(Context.INPUT_METHOD_SERVICE);
mgr.hideSoftInputFromWindow(searchBox.getWindowToken(), 0);
//close activity
YourActivity.finish();
}
for backpressed of android device do as:
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
yourMethod();
YourActivity.finish();
}
Activity.onBackPressed() won't work, because it's being called after (and if) nothing else handled the back button (which IME does).
Override Activity.dispatchKeyEvent() instead:
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return super.dispatchKeyEvent(event);
}
I'm having a really hard time getting the OnKey event to trigger on my EditText view. I've been Googling for over an hour now and it seems everyone says all you have to do is add a OnKeyListener to the view but it's not triggering it. I tried adding it to the entire Activity and also tried adding it to the view itself but neither way is triggering the function.
My code:
XML:
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/interests_editText" />
Java:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_post);
interests_editText = (EditText) findViewById(R.id.interests_editText);
interests_editText.setOnKeyListener(new OnKeyListener(){
public boolean onKey( View view, int keyCode, KeyEvent event){
Log.i("DEBUG","TeST");
if (keyCode == KeyEvent.KEYCODE_ENTER) {
return true;
}
else {
return false;
}
}
}
);
Update:
My final goal is to get it to recognize when you press space while in that editText view. I added to the XML
android:inputType="text"
and then changed the code to
public boolean onKey( View view, int keyCode, KeyEvent event){
Log.i("DEBUG","Outside");
if (keyCode == KeyEvent.KEYCODE_SPACE) {
Log.i("DEBUG","Space");
return true;
}
else {
return false;
}
Now the keyboard shows a Next button that when pressed logs "Outside" but it doesn't log "Space"
Do you wanna capture Enter event? If so, try setOnEditorActionListener
For your Update Info: capture space key, try addTextChangedListener
Following up on #BNK's answer I got it to work using the following code:
interests_editText.addTextChangedListener(new TextWatcher() {
#Override
public void afterTextChanged(Editable s) {
String str = s.toString();
if(str.substring(str.length()-1, str.length()).equals(" "))
Log.i("DEBUG","Space pressed");
else if(str.substring(str.length()-1, str.length()).equals("\n"))
Log.i("DEBUG", "Enter pressed");
else
Log.i("DEBUG", "Pressed : " +str.substring(str.length()-1, str.length()) );
}}