In my application, I defined 2 activities in the Manifest file like this:
<activity android:name=".event.EventDetailsActivity"
android:launchMode="singleTop"
android:parentActivityName=".main.MainActivity"
android:theme="#style/AppTheme.WithActionBar"/>
<activity
android:name=".main.MainActivity"
android:launchMode="singleTop"/>
In the MainActivity, I have 4 fragments. In one fragment, I start the EventDetailsActivity in one fragment using:
Intent intent = new Intent(new Intent(getContext(), EventDetailsActivity.class));
intent.putExtra(EventDetailsActivity.ID_KEY, id);
intent.putExtra(EventDetailsActivity.TYPE_KEY, true);
startActivityForResult(intent, DETAILS_REQUEST);
How I handle the back navigation in EventDetailsActivity:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
}
#Override
public void onBackPressed() {
Log.d(TAG, "Back pressed " + isChanged);
if (isChanged) {
Log.d(TAG, "Set result");
setResult(RESULT_OK);
finish();
}
super.onBackPressed();
}
The problem is onActivityResult get called in the calling Fragment but the result code is always 0 (RESULT_CANCELED). Also, onSupportNavigateUp never gets called if I press the back arrow button. Is there any workaround for this problem?
Remove : android:launchMode="singleTop"
and remove super.onBackpressed in on onBackpressed function
because you used finish()
As you're getting the onActivityResult callback from your Fragment correctly I assume the problem is about setting the proper result to the starting Activity. So here's I'm proposing some edit you might consider in your code.
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
setResult(RESULT_OK);
return true;
}
return super.onOptionsItemSelected(item);
}
// No longer necessary
/* #Override
public boolean onSupportNavigateUp() {
Log.d(TAG, "Navigate up");
onBackPressed();
return true;
} */
/* #Override
public void onBackPressed() {
// Super call needs to be the first line
super.onBackPressed();
if (isChanged) {
setResult(RESULT_OK);
}
} */
So I've omitted the onBackPressed function because by default, if the user presses the back button, the result will be Activity.RESULT_CANCELED.
So there's a hacky solution here is to implement the key event callback listener like this.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
setResult(RESULT_OK);
finish();
}
return super.onKeyDown(keyCode, event);
}
Hope that helps!
Related
in action bar when back button is pressed how do I know in the previous activity that back button was pressed , onCreate() does not get called when back button is pressed
I know from the code below that on current activity that back button was pressed but I need to know on previous activity that back button was pressed
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
You can navigate between activities using registerForActivityResult() API, and put some extra data in the returned intent that can show you from where it came from.
At source activity:
ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
result -> {
if (result.getResultCode() == AppCompatActivity.RESULT_OK) {
if (result.getData() != null) {
String data = result.getData().getStringExtra("ACTIVITY_FROM");
if (data != null)
switch (data) {
case "ACTIVITY2":
// Returned from Activity2
Log.d(TAG, "onCreate: Returned from Activity2");
break;
case "ACTIVITY3":
// Returned from Activity3
Log.d(TAG, "onCreate: Returned from Activity3");
break;
}
}
}
}
);
// Go to Activity 2:
auncher.launch(new Intent(this, Activity2.class));
At the destination activity:
Then put the data when you need to return back from Activity2:
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if (item.getItemId() == android.R.id.home) {
setIntent();
this.finish();
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onBackPressed() {
setIntent();
finish();
super.onBackPressed();
}
private void setIntent() {
Intent intent = new Intent();
intent.putExtra("ACTIVITY_FROM", "ACTIVITY2");
setResult(Activity.RESULT_OK, intent);
}
I'm trying to make my app not close when the user pressed the back button and remain in the same state at least for a while, like the home button. I searched and some people suggested to do this.
#Override
public void onBackPressed() {
super.onBackPressed();
this.moveTaskToBack(true);
}
but this didn't help. I have to mention the activity I'm using this code on is not the LAUNCHER activity and before this activity, there is a splash screen.
what am I doing wrong?
Try my code in your activity.
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
Log.d(TAG, "onKeyDown: ");
if(keyCode == KeyEvent.KEYCODE_BACK){
goHome();
return true;
}
return super.onKeyDown(keyCode, event);
}
private void goHome() {
Intent i = new Intent(Intent.ACTION_MAIN);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.addCategory(Intent.CATEGORY_HOME);
startActivity(i);
}
Do start the home screen when key back down.
You should not call super method in onBackPressed(). It should be simply like this
#Override
public void onBackPressed() {
moveTaskToBack(true);
}
I have activity ActivityProfile, have getSupportActionBar().setDisplayHomeAsUpEnabled(true); implemented, onBackPressed() as well, search all over the internet and still no help.
#Override
public void onBackPressed() {
Toast.makeText(this, "OnBackpressed fired", Toast.LENGTH_SHORT).show();
super.onBackPressed();
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//replaces the default 'Back' button action
if(keyCode== KeyEvent.KEYCODE_BACK) {
// something here
onBackPressed();
}
return true;
}
using the device's back button works, but not on the app...
To implement Up navigation, declare a parent of that particular activity in manifest and setDisplayHomeAsUpEnabled as true.
<activity
android:name="com.example.myfirstapp.DisplayMessageActivity"
android:label="#string/title_activity_display_message"
android:parentActivityName="com.example.myfirstapp.MainActivity" >
<!-- Parent activity meta-data to support 4.0 and lower -->
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.myfirstapp.MainActivity" />
</activity>
Read More https://developer.android.com/training/implementing-navigation/ancestral.html
you should use onOptionItemSelected to handle click on the bottom on action bar :
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Try this
setSupportActionBar(toolbar);
toolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
This should work
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
}
return super.onOptionsItemSelected(item);
}
hi add this code in your activity. when you press back button in toolbar following code execute.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.your_view);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case android.R.id.home:
finish();
break;
default:
return super.onOptionsItemSelected(item);
}
return super.onOptionsItemSelected(item);
}
so i have Activity A,B, and C. Activity A & B both go to activity C. When i am on activity C and I press the back home button on mySupportActionBar, I want to return to the state of activity (from the state i left it in) I came from. How would i accomplish this?
Here is my onOptionsItemSelected(). So currently, it goes back to the designated parent activity i assigned in manifest to avoid my app from crashing. Because the parent activites require strings from intents.
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
int id = item.getItemId();
if(id == android.R.id.home)
{
NavUtils.navigateUpFromSameTask(this);
}
return super.onOptionsItemSelected(item);
}
I would also love to accomplish this onBackPressed().
The back arrow button is the "home" button when you're in a inner activity so you could finish the inner activity or maybe just call the back button
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Use android.R.id.home
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
You also can use setNavigationOnClickListener on toolbar to trigger back button.
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filter_category);
setSupportActionBar(toolbar);
if (getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowTitleEnabled(false);
//back button action
toolbar.setNavigationOnClickListener(view -> finish());
}
}
I have an activity that loads a Fragment onCreate. And I have a toolbar on that activity that has a button that when clicked will add a new Fragment on top of the one that got created first.
Now on that toolbar, when clicked, I want to remove the newer fragment so that it just displaces the fragment that is in the bottom (older one). I've searched and I kinda have figured it out except for one thing.
I did this so that it tries to see if the toolbar button is pressed:
#Override
public boolean onKeyUp(int keyCode, KeyEvent objEvent) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
onBackPressed();
return true;
}
return super.onKeyUp(keyCode, objEvent);
}
#Override
public void onBackPressed() {
FragmentManager mFM = getSupportFragmentManager();
if(mFM.findFragmentByTag("NewFragment") != null){
mFM.beginTransaction().remove(mFM.findFragmentByTag("NewFragment")).commit();
}
}
The problem is, "keyCode" is only equals to KEYCODE_BACK when you click the "hardware's back button" and not the back button of the toolbar. What it gives me is keycode 58 and not 4 (KEYCODE_BACK).
I believe what your looking for is the NavigationListener for the Toolbar Widget:
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onBackPressed();
}
});
but if your using a Theme with an ActionBar and setting a supportActionBar then do something :
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
onBackPressed();
break;
}
return true;
}
It's not clear from your question whether you're asking a Fragment management question (FragmentTransaction remove vs. replace), or a Toolbar button question. I assume the latter...
An Android Toolbar or ActionBar should have actions handled using:
#Override
public Boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case MY_BACK_BUTTON:
myBackPressedHandler();
return (true);
}
return (false);
}
this assumes that your Back button is added as a MenuItem and was given an ID of MY_BACK_BUTTON.
For a Toolbar, you can use a MenuItemClickListener to handle the click events:
mToolbar.setOnMenuItemClickListener(MenuItem menuItem)
{
#Override
public Boolean onMenuItemClick(MenuItem menuItem)
{
// call onOptionsItemSelected, or handle the click here directly
return (thisFragment.onOptionsItemSelected(menuItem));
}
});
If you're referring to the "Up" button on the Toolbar/ActionBar, i.e. setDisplayHomeAsUpEnabled(true), this will have a getItemId() of android.R.id.home and can be handled in a similar fashion:
case android.R.id.home:
myBackPressedHandler();
return (true);