How to finish() an activity with SoftKeyboard visible with onBackPressed() - java

I have an activity where the whole screen is dedicated to sending one message. Being one EditText on the top half, and the SoftKeyboard always visible on the bottom half.
When i press back, the SoftKeyboard hides and i have to press back again to leave the activity.
The behavior that i'm struggling to get is : finishing the activity right away when i press the back button, instead of hiding the keyboard.
You can find this behavior in the twitter app for example, when writing a new tweet.
I tried with overriding the onBackPressed() function, but seems like when the keyboard is visible, the function is not called.
#Override
public void onBackPressed() {
finish();
}
Any help would be really appreciated!

So after trying many things, here something that worked :
Subclass EditText and override the onKeyPreIme() function to send a call back.
Here's the code for the subclass :
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();
Log.d(TAG, "HIDING KEYBOARD");
return false;
}
return super.dispatchKeyEvent(event);
}
public interface OnKeyPreImeListener {
void onBackPressed();
}
Then in your activity for each of your TextView :
EditTextGraphee.OnKeyPreImeListener onKeyPreImeListener =
new EditTextGraphee.OnKeyPreImeListener() {
#Override
public void onBackPressed() {
Log.d(TAG, "CALL BACK RECEIVED");
MyActivity.this.onBackPressed();
}
};
editText.setOnKeyPreImeListener(onKeyPreImeListener);

new answer:
so apparently you don't receive the onBackPressed callback, but that doesn't mean you can't detect the keyboard closing.
Using the technique described here: How to check visibility of software keyboard in Android?
you can detect when the keyboard open/close, so when the keyboard closes you call finish();
deprecated, original answer:
simply override the back press event in the activity:
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}

I assume that since the soft keyboard is visible probably an edittext has a focus. So you can catch the back pressed event by adding an OnEditorActionListener on that EditText and finish activity.
yourEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP){
if (event.getKeyCode() == KeyEvent.KEYCODE_BACK){
finish();
}
}
return false;
}
});

You nee to extend EdtText class and implement onKeyPreIme method.
public class MyEditText extends EditText {
/* Must use this constructor in order for the layout files to instantiate the class properly */
public MyEditText(Context context, AttributeSet attrs)
{
super(context, attrs);
// TODO Auto-generated constructor stub
}
#Override
public boolean onKeyPreIme (int keyCode, KeyEvent event)
{
// do your stuff here.
return true;
}
}

Override onBackPressed() method like this :
#Override
public void onBackPressed() {
hideKeyboard();
finish();
}
For hideKeyboard() function please search in the Internet .

Related

Android onBackPressed() is not being called?

in my MainActivity, which extends from AppCompatActivity, I want to override the onBackPressed method like so:
#Override
public void onBackPressed() {
Log.d("MainActivity","onBackPressed");
Toast.makeText(getApplicationContext(),"onBackPressed",Toast.LENGTH_SHORT).show();
}
but onBackPressed does not get called. How ever if I do not override onBackPressed, the application closes, when I press the backbutton and if I do override it it doesn't.
The rest of my activity looks like this:
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private Drawer drawer;
private FloatingActionButton fab_test;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
fab_test = (FloatingActionButton) findViewById(R.id.fab_test);
fab_test.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(),"FAB Test pressed",Toast.LENGTH_SHORT).show();
}
});
buildDrawer();
getSupportFragmentManager().beginTransaction().add(R.id.fragmentContainer,page).commit();
}
#Override
public void onBackPressed() {
Log.d("MainActivity","onBackPressed");
Toast.makeText(getApplicationContext(),"onBackPressed",Toast.LENGTH_SHORT).show();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main_menu, menu);
return true;
}
}
EDIT: I'm talking about the hardware-backbutton(not the actionbar one)
This question is already answered, but I feel to clear something here in this topic. Most comments and answeres point out to use super.onBackPressed() and that this is the cause of the not working method onBackPressed(). But that is not correct and important to let other beginners know. The method onBackPressed() does not need to use super.onBackPressed() . onBackPressed()also works if somebody, for example, comment super.onBackPressed() out.
As the questionier has written, he won´t use super.onBackPressed() because it will close the activity. So, the cause of this why it isn´t working, could be seperated into three possible causes:
The Log doesn´t work because of a wrong filter in the logcat console
The Toast dosn´t work because of the wrong passed context
The OS is implemented wrong by the supplier.
Usually, the toast works by passing the correct context. In the case of questioner, simply passing this .
#Override
public void onBackPressed() {
Log.d("MainActivity","onBackPressed");
Toast.makeText(this,"onBackPressed",Toast.LENGTH_SHORT).show();
}
For the Log, simply set the correct filter on logcat.
I don´t care if somebody give downvotes now, but it must be clear for other beginners, that super.onBackPressed() must not be used.
Anyway, the use of onKeyDown() also is a solution.
The onBackPressed() is a default action called from onKeyDown() in API < 5 and a default action called from onKeyUp() from API level 5 and up. If onKeyUp() does not call super.onKeyUp(), onBackPressed() will not be called.
Documentation onKeyDown()
Documentation onKeyUp().
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
/*
* without call to super onBackPress() will not be called when
* keyCode == KeyEvent.KEYCODE_BACK
*/
return super.onKeyUp(keyCode, event);
}
Also another reason that onBackPressed() may not be called is because you are using the soft back button on the actionbar, it that case the following is needed:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
You are missing, super.onBackPressed();
#Override
public void onBackPressed() {
super.onBackPressed();
}
or you can use
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//replaces the default 'Back' button action
if(keyCode==KeyEvent.KEYCODE_BACK) {
// something here
finish();
}
return true;
}
thanks
make sure you are not calling onkeydown in your super view as it handles the back button clicking first.
working fine onKeyDown function return type false;
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return false;
}
For whoever is wondering, as most functionality is deprected API 30>, the following will surely help you a lot.
public class MainActivity extends AppCompatActivity {
private OnBackPressedCallback onBackPressedCallback;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
onBackPressedCallback = new OnBackPressedCallback(true) {
#Override
public void handleOnBackPressed() {
// Your business logic to handle the back pressed event
Log.d(TAG, "onBackPressedCallback: handleOnBackPressed");
}
};
getOnBackPressedDispatcher().addCallback(this, onBackPressedCallback);
}
}
Just Remove super.onBackPressed() it will work

How can I jump from activity B to A more than just once

I have two layouts, A and B. The app launches the A_layout, and through a button you can go to the B_layout. On default when you press the back button the app closes, doesnt matter if the app is on the A or B layout. When I override the back button to set the content view always on the layout A whenever the back button is pressed, then I cant open the B activity anymore through the button. How do I need to override the method correctly? :)
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
setContentView(R.layout.activity_main);
return true;
}
return super.onKeyDown(keyCode, event);
}
activity_main = A layout
Do I need to make Intents there?
You can override the onBackPressed function:
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent(getApplicationContext(), ActivityA.class);
startActivity(intent);
finish();
}
When finsihing the activity is destroyed

How to trigger an event on Dialog dismiss Android?

I have a custom dialog which extends the Dialog Class, I would like to bind an event to execute some code after the Dialog is closed when the user presses the BACK button of the device. How can I do that? I found a post where someone says that the .addWindowListener() should be used when working with Dialogs and other Window widgets. But the dialog class doesn't have the addWindowListener method, so I cannot use it. Is there another way without using fragments cause I shouldn't re-write the MyCustomDialog class?
This is the code:
public class MyCustomDialog extends Dialog {
public MyCustomDialog(Context context, int layoutResourceId) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(layoutResourceId);
}
}
Thanks for the attention!
EDIT: i found this on the android developers site, is there a way to use it with MyCustomDialog class?
onDismiss DialogInterface
Since you are extending android Dialog class you can implement a Dismiss Listener in your Activity's and set it when you create the Dialog, and then in the listener implement any functionality you want depending on the button that was used to dismiss the Dialog.
Hope this will solve your problem.
Edit You can use dialog.setCanceledOnTouchOutside(false); which will stop closing the dialog if you touch outside of the dialog.
Something like,
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(false);
OR Alternatively
Override onTouchEvent() of dialog and check for action type. if the action type is
'MotionEvent.ACTION_OUTSIDE' means, user is interacting outside the dialog region. So in this case, you can dimiss your dialog or decide what you wanted to perform.
view plainprint?
dialog.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event)
{
if(event.getAction() == MotionEvent.ACTION_OUTSIDE){
Toast.make(getApplicationContext(), "TOuched outside the dialog", Toast.LENGTH_LONG).show();
this.dismiss();
}
return false;
}
});
And for back press you can do dialog.setCancelable(false); which will prevent dialog getting cancelled from backpress event.
OR you can alternatively override setOnKeyListener event and put your own code into it.
Edit
dialog.setOnKeyListener(new Dialog.OnKeyListener() {
#Override
public boolean onKey(DialogInterface arg0, int keyCode,
KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_BACK) {
finish();
dialog.dismiss();
}
return true;
}
});
Happy Coding!!!
You need to Override onBackPressed inside Dialog class. Also make sure to close dialog after override OnBackPressed .
Try this
public class MyCustomDialog extends Dialog {
public MyCustomDialog(Context context, int layoutResourceId) {
super(context);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(layoutResourceId);
}
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
dismiss(); // make sure to call dismiss to close dialog
// put your code here
}
}
If you want to trigger an event if user clicked/touched outside the dialog and close it or used the back button to close then use
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
//your trigger goes here
Toast.makeText(IntroductoryActivity.this, "on cancel", Toast.LENGTH_SHORT).show();
}
});
But if you want to trigger an event if something dismisses the dialog, like some other event then use
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
//your trigger goes here
Toast.makeText(IntroductoryActivity.this, "on dismiss", Toast.LENGTH_SHORT).show();
}
});

Handling back-key in custom view of a dialog

Okay so I have a custom view inside a dialog but its onKeyDown never get called. I tried onKeyPreIme too but didn't work and setting dialog's setCancelable to true didn't help either.
edit :
//Removed all unnecessary code
public class CustomView extends LinearLayout
{
#Override
public boolean onKeyDown (int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
{
//do stuff here
return true;
}
return super.onKeyDown(keyCode, event);
}
}
public class CustomDialog
{
Dialog dialog;
public class CustomDialog(Context context)
{
dialog = new Dialog(context);
dialog.setContentView(R.layout.test);// the test.xml has CustomView
}
}
Why don't you simply use :
public void onBackPressed() {
//desired functionality here
return;
}
Move your onKeyDown logics to an OnKeyListener implementation and register it in your View's constructor.

how to return back to parent activity while pressing back button on chlild activity in TAB Application

i have 4 tab with activity group..all tab contain list of item and on press of any item its discriptioo will be displayed in new activity..
i m using activitygroup to embedded child activity in tab.and i m using replace contentview to change the activitygroup view.
when i press back button i call finish() from child and i immediately get out of application..is there any way to return back to parent activity using activity group...???
i m using following code to chang activitygroup view..bt dont know how to come back to this activity..
public void replaceContentView(String id, Intent newIntent)
{
View mview = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)).getDecorView();
this.setContentView(mview);
}
I was also stuck with this problem but solved it have a look a t below code hope will help you also
Your activityGroup should be something like this
public class ABCGroup extends ActivityGroup{
public static ABCGroup group;
private ArrayList<View> history;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.history = new ArrayList<View>();
group = this;
View view = getLocalActivityManager().startActivity
("ParentActivity",
new Intent(this, ParentActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP))
.getDecorView();
replaceView(view);
}
public void replaceView(View v) {
// Adds the old one to history
history.add(v);
// Changes this Groups View to the new View.
setContentView(v);
}
public void back() {
if(history.size() > 0) {
history.remove(history.size()-1);
if(history.size()<=0){
finish();
}else{
setContentView(history.get(history.size()-1));
}
}else {
finish();
}
}
#Override
public void onBackPressed() {
ABCGroup.group.back();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_BACK){
ABCGroup.group.back();
return true;
}
return super.onKeyDown(keyCode, event);
}
}
In your parent activity
View mview = getLocalActivityManager().startActivity(id,newIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)).getDecorView();
ABCGroup.group.replaceView(v);
In your child activity use
public boolean onKeyDown(int keyCode, KeyEvent event){
if (keyCode == KeyEvent.KEYCODE_BACK){
ABCGroup.group.back();
return true;
}
return super.onKeyDown(keyCode, event);
}

Categories

Resources