I am using navigation component to navigate between my fragments. I have 1 fragment where the user can edit some data. As soon as anything changes i set the flag "saved = false" and after user presses "save" button, flag goes to "saved = true". Now, what i want to do, is to add a usual popup message (Do u want to save the changes? Yes No Cancel) when the user pressed a back button, but did not save the changes. Also i want to add it to both buttons:
This one
And this one
I looked into this: https://developer.android.com/guide/navigation/navigation-custom-back
and it works only for (main) back button, but not for the one on the toolbar. When i need to go to previous fragment in code i use:
findNavController().popBackStack()
So do i need to somehow override this function or add a callback? Or maybe there is some entirely different (better) way of doing this?
Next time plz share your code.
I had the same problem and this is my solution, You need to override onOptionsItemSelected in your activity/fragment and to check when "back" arrow is pressed.
Code
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// put here what you would like to happen when u click on it
return true;
default:
return super.onOptionsItemSelected(item);
}
}
EDIT : I just notice that you are using Kotlin so i added a kotlin example:
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item.getItemId()){
android.R.id.home -> {
// put your code here
return true
}
}
return super.onOptionsItemSelected(item)
}
Feel free to ask anything:)
Related
I have an activity that has a recyclerview that populates its data based on the yearSelected string forwarded from the previous activity with an intent and put extra. then I choose a row and navigate to the next activity to show the week selected info. when I want to return to the previous activity using the action bars back button it crashes, I'm guessing because I'm no longer sending the intent info when I return back. is there a place I can use putExtra when it returns back or is there a way to set the back button to just return to the previous activity like the back button on the bottom does?
Actually, the action bar should behave like a menu.
You can listen for the "back" button and perform whatever action you need to in onOptionsItemSelected..
eg
public boolean onOptionsItemSelected(MenuItem item) {
...
switch (item.getItemId()) {
case android.R.id.home:
<set return result etc and finish>
return true;
...
Note that the back button item id is android.R.id.home .. because the same item is used for home as up (and hamburger menu from memory).
Also, finishing and activity in the middle of handling an event isn't great practice, but commonly done.
override fun onOptionsItemSelected(item: MenuItem): Boolean{
return when (item.itemId){
android.R.id.home -> {
finish()
true
}else -> super.onOptionsItemSelected(item)
}
}
My android application has the following activity flow
Listing -> Buy -> Sell
From the listing when an item is clicked/selected an id is passed to buy to pull the relevant data from the server. If a user owns a certain item there will be a sell option as well from the buy screen (which doubles as an overview of said item).
The problem I am facing is that when you are on the sell screen and press the android back button you are taken back to the buy screen in it's original state, however when you click the back arrow (up) from the activity in the toolbar, it seems that it is actually trying to launch a new activity and throws an exception (since the activity cannot know what the id was). The buy activity is listed as a parent to the sell activity in the manifest.
I need to somehow make the up button to act the same as the back button on this particular activity, or at least pass the id back somehow.
Any suggestions would be appreciated.
If you're using an ActionBar (either platform or AppCompat) override the following method in the activity from which you wish to go back.
#Override
public boolean onOptionsItemSelected(#NonNull final MenuItem item) {
final int id = item.getItemId();
if (id == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
This should be safe to use in a simple navigation hierarchy such as yours.
Just yesterday i did this for my app. This is what I did:
In manifest file I removed
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.example.app.MainActivity" />
that was part of my DetailsActivity.
In the DetailsActivity I added this line to onCreate
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
and in onOptionsItemSelected() method I added these lines
if (item.getItemId() == android.R.id.home) {
onBackPressed();
}
Not sure if it is the best way to handle this but oh well it works :)
In your Activity, onOptionsItemSelected() method get the clicked item id, if the id is android.R.id.home then just finish() current activity.
Try this:
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case android.R.id.home:
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
I have an app where I'm doing activity transitions for a company directory. When a search result is selected, the animation of their photo to the detail screen works. And if I hit the back button, the reverse animation occurs. However, if I hit the back arrow from the Toolbar, the reverse animation never occurs.
The detail screen is a new DetailActivity with a single fragment in it called DetailFragment. I'm not doing anything special on "onBackPressed". Should I be?
If you want the return transition to play, you'll need to listen for the up-navigation button click and call finishAfterTransition() directly:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finishAfterTransition();
return true;
}
return super.onOptionsItemSelected(item);
}
I have a Xamarin Android project that contains a menu bar. I'm almost certain this was working correctly yesterday, but since then, every time I click on a menu bar item such as 'settings', which takes me to the Settings Activity, then go back to the Main activity, the menu bar items are repeating themselves.
So where i just had 'Settings' and 'help', i not have 2 settings, and 2 help items. If i do it again, i will have 3 of each.
I'm assuming this is something to do with the onPause() and onResume() methods as the app goes to another activity. But i can't see where i'm going wrong (i'm new to Android)
My code for generating the menu bar in the Main Activity is:
public override bool OnPrepareOptionsMenu(IMenu menu1)
{
MenuInflater.Inflate(Resource.Menu.myMenuBar, menu1);
return base.OnPrepareOptionsMenu(menu1);
}
public override bool OnOptionsItemSelected(IMenuItem item) //do something when an options item is pressed
{
switch (item.ItemId)
{
case Resource.Id.settingsItem:
showSettings ();
return true;
case Resource.Id.helpItem:
//do something
return true;
}
return base.OnOptionsItemSelected(item);
}
Any ideas on this would be appreciated. I'm sure it's something fairly simple but I don't know what.
You should probably have to clear the menu
public override bool OnPrepareOptionsMenu(IMenu menu1)
{
menu1.clear();
MenuInflater.Inflate(Resource.Menu.myMenuBar, menu1);
return base.OnPrepareOptionsMenu(menu1);
}
And perhaps you should inflate the menu in the OnCreateOptionsMenu(IMenu, MenuInflater) method. OnPrepareOptionsMenu(IMenu) is meant for enabling/disabling and dynamically modifying items.
I'm using the Actionbar and it's "up" button to return from a detail activity to the main activity, which works fine. Similarly, the user can press the system "back" button to return to the main activity.
In my main activity, in onCreate() data is downloaded from the internet to display upon app start. I noticed that when I use the Actionbar "up" button to go from detail to main activity, onCreate() is run, re-downloading the data. But onCreate() is not run when I use the system "back" button, therefore immediately showing the main activity view.
The code I use in the detail activity to implement the "up" button is:
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
I would like the "up" button to behave like the "back" button and not rerun onCreate(). But I'm unsure how to make this happen, or which code path the "back" button implements to return to the main activity.
Thanks!
Instead of starting a whole new activity simply finish the details activity you are in
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
Then you will return to the previous activity on the activity stack (your main activity) and onCreate shouldn't be called
If you want Up to do exactly what Back does, you can do this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case android.R.id.home:
onBackPressed();
return true;
default:
break;
}
return super.onOptionsItemSelected(item);
}
Note that the default implementation of onBackPressed() just calls finish(), but onBackPressed can be overridden.
I think a better solution can be found in this post.
Calling finish() works in specific situations but may not always produce the behavior described in the documentation e.g:
By calling
Intent intent = NavUtils.getParentActivityIntent(this);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
NavUtils.navigateUpTo(this, intent);
you'll return to the parent activity in the state in which you left it. If you have a flat app structure, it'll still act just like the Back button.
for a real "home" functionality , you should see the api demos ,under "App/Activity/Reorder Activities" .
the reason : what if you have something like this : activity1->activity2->activity3 , and now you wish to go to activity1 by pressing the home button on the action bar?
I believe the simplest way is to override the "getParentActivityIntent" method of the detail activity adding the flag "Intent.FLAG_ACTIVITY_CLEAR_TOP":
#Nullable
#Override
public Intent getParentActivityIntent() {
Intent intent = super.getParentActivityIntent();
if (intent != null) {
return super.getParentActivityIntent().addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
}
return intent;
}
There is another solution which can be in hand for somebody. I had the same double-behavior when user pressed Back and ActionbarBack buttons. I was fine with Back btn behaviour. I didn't want an activity to be recreated. So I overrode the method
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
Works fine for me