I would like my application to quit if the user presses back at a certain activity. The following is the code for that activity.
public class MainActivity extends FragmentActivity implements DenkoListFragment.ListSelectListener {
private SlidingMenu menu;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
displayView(0);
menu = new SlidingMenu(this);
menu.setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
menu.setShadowWidthRes(R.dimen.shadow_width);
menu.setShadowDrawable(R.drawable.shadow);
menu.setBehindOffsetRes(R.dimen.slidingmenu_offset);
menu.setFadeDegree(0.35f);
menu.attachToActivity(this, SlidingMenu.SLIDING_CONTENT);
menu.setMenu(R.layout.menu_frame);
menu.setSelected(true);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.menu_frame, new DenkoListFragment())
.commit();
}
private void displayView(int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MainViewFragment();
break;
case 1:
fragment = new StationViewFragment();
break;
case 2:
fragment = new MapViewFragment();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).commit();
} else {
}
}
#Override
public void select(int index) {
displayView(index);
menu.showContent();
}
#Override
public void onBackPressed() {
if (menu.isMenuShowing()) {
menu.showContent();
} else {
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Exit")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
System.exit(0);
}
}).setNegativeButton("No", null).show();
}
}
}
It takes the app two back presses (and two confirmations) to exit. What explains this behaviour and is there any way to resolve this?
Remove below snippet from onBackPress() Method. It will handle by SlideMenu only.
if (menu.isMenuShowing()) {
menu.showContent();
}
Code from SlidingFragmentActivity call onBackPress:
#Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
boolean b = mHelper.onKeyUp(keyCode, event);
if (b) return b;
return super.onKeyUp(keyCode, event);
}
mHelper.onKeyUp(keyCode, event) will call a Method of SlidingActivityHelper:
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && mSlidingMenu.isMenuShowing()) {
showContent(); //Close the SlidingMenu and show the content view.
return true;
}
return false;
}
super.onBackPressed(); will do what ever you want,just include super.onBackPressed(); instead of System.exit(0);,because it will call the onBackpressed method of Activity.So,onDestroy method get call properly.
new AlertDialog.Builder(this).setIcon(android.R.drawable.ic_dialog_alert).setTitle("Exit")
.setMessage("Are you sure you want to exit?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
super.onBackPressed();
}
}).setNegativeButton("No", null).show();
Related
I want to show AlertDialog before fragment changes from StageZeroFragment to any other. I change fragments with my BottomNavigationView:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.stages);
util = new Util(this);
bottomNavigationView = findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
displayView(item.getItemId());
return true;
}
});
}
public void displayView(int viewId) {
Fragment fragment = null;
String title = getString(R.string.app_name);
switch (viewId) {
case R.id.navigation_stage_zero:
fragment = new StageZeroFragment();
break;
case R.id.navigation_stage_one:
fragment = new StageOneFragment();
break;
case R.id.navigation_stage_two:
fragment = new StageTwoFragment();
break;
case R.id.navigation_stage_three:
fragment = new StageThreeFragment();
break;
}
if (fragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.content_frame, fragment);
ft.commit();
}
}
I was trying to write something like this in my StageZeroFragment:
#Override
public void onPause() {
new AlertDialog.Builder(getActivity(), R.style.MojStyl).setIcon(android.R.drawable.ic_dialog_info)
.setCancelable(false).setTitle(R.string.hide_dialog_title)
.setMessage(R.string.stage_zero_confirmation)
.setPositiveButton((R.string.no), null)
.setNegativeButton((R.string.yes), (dialog, which) -> {
editor.putBoolean("correctionDone", true);
editor.apply();
super.onPause();
}).show();
}
but there was en error saying that super.onPause() is not called. So how can I achieve possibility to show AlertDialog when StageZeroFragment is shown and before fragment is changed to another from BottomNavigationView? Thank you in advance!
You don't need onPause for this. You can show dialog in onNavigationItemSelected and perform fragment transaction displayView on button click of AlertDialog.
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
if(bottomNavigationView.getSelectedItemId() == R.id.navigation_stage_zero){
new AlertDialog.Builder(getActivity(), R.style.MojStyl).setIcon(android.R.drawable.ic_dialog_info)
.setCancelable(false).setTitle(R.string.hide_dialog_title)
.setMessage(R.string.stage_zero_confirmation)
.setPositiveButton((R.string.no), null)
.setNegativeButton((R.string.yes), (dialog, which) -> {
editor.putBoolean("correctionDone", true);
editor.apply();
displayView(R.id.navigation_stage_one);
}).show();
} else {
displayView(item.getItemId());
}
return true;
}
});
i use three fragment in dashbordActivity on bottom navigation bar. On back button press previous fragment view properly but bottom navigation button not changing.
in first image home fragment is already selected after i select profile from bottom navigation and press backbutton. fragment changes but bottom navigation item does not change.
this is my bottom navigation view .....
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
setTitle("Home");
fragment = new FirstFragment();
loadFragment(fragment);
return true;
case R.id.navigation_favorite:
setTitle("favourite");
fragment = new MyFavoriteAdsFragment();
loadFragment(fragment);
return true;
case R.id.navigation_profile:
setTitle("Profile");
fragment = new ProfileFragment();
loadFragment(fragment);
return true;
case R.id.navigation_myads:
setTitle("Chat");
fragment = new MyAdsFragment();
loadFragment(fragment);
return true;
case R.id.navigation_chat:
// mTextMessage.setText(R.string.title_chat);
setTitle("Chat");
fragment = new TabFragmentChatUserList();
loadFragment(fragment);
/* Intent i=new Intent(getApplicationContext(),Chat.class);
startActivity(i);*/
return true;
}
return false;
}
};
private void loadFragment(Fragment fragment) {
// load fragment
transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, fragment);
transaction.addToBackStack("TAG");
transaction.commit();
/* fragmentManager.beginTransaction().replace(R.id.home_container, frag).addToBackStack(null).commit();*/
}
ob back press i tryed...
#Override
public void onBackPressed()
{
// if your using fragment then you can do this way
int fragments
=getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.setNegativeButton("No", null)
.show();
} else {
if (getFragmentManager().getBackStackEntryCount() > 1) {
getFragmentManager().popBackStack();
if(navigation.getSelectedItemId () != R.id.navigation_favorite)
{
navigation.setSelectedItemId(R.id.navigation_favorite);
}
else if(navigation.getSelectedItemId () != R.id.navigation_chat)
{
navigation.setSelectedItemId(R.id.navigation_chat);
}
else if(navigation.getSelectedItemId () != R.id.navigation_profile)
{
navigation.setSelectedItemId(R.id.navigation_profile);
}
else
{
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
You need to check your backstack and add listener to your fragment manager, after that based on your fragment you need to set particular button check based on your fragment.
fragmentManager.addOnBackStackChangedListener(new FragmentManager.OnBackStackChangedListener() {
#Override
public void onBackStackChanged() {
// If the stack decreases it means I clicked the back button
if( fragmentManager.getBackStackEntryCount() <= count){
//check your position based on selected fragment and set it accordingly.
navigation.getMenu().getItem(your_pos).setChecked(true);
}
}
});
You can customize your onBackPressed in this way:
#Override
public void onBackPressed() {
// if your using fragment then you can do this way
int fragments
= getSupportFragmentManager().getBackStackEntryCount();
if (fragments == 1) {
new AlertDialog.Builder(this)
.setMessage("Are you sure you want to exit?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
finish();
}
})
.setNegativeButton("No", null)
.show();
} else {
if (getSupportFragmentManager().getBackStackEntryCount() > 1) {
getSupportFragmentManager().popBackStack();
Fragment selectedFragment = null;
List<Fragment> fragments = getSupportFragmentManager.getFragments();
for (Fragment fragment : fragments) {
if (fragment != null && fragment.isVisible()) {
selectedFragment = fragment;
break;
}
}
if (selectedFragment instanceof yourFirstFragment) {
navigation.setSelectedItemId(R.id.your_first_item);
} if (selectedFragment instanceof yourSecondFragment) {
navigation.setSelectedItemId(R.id.your_second_item);
} if (selectedFragment instanceof yourThirdFragment) {
navigation.setSelectedItemId(R.id.your_third_item);
} else {
super.onBackPressed();
}
} else {
super.onBackPressed();
}
}
Imagine Instagram, when the camera button/add photo button is pressed on the TabLayout,pressing the back button will take me back to the feed fragment.
I am having problem of returning to the HomeFragment from a full screen activity.
What I did: When the camera button on the tablayout is pressed, it will prompt an alert dialog to ask user to choose whether from gallery or camera. Both will prompt a full screen activity. And when back button is pressed, it is stuck at the camera button screen, where I am not planning to design.
What I plan on doing: When back button is pressed from the alert dialog box or gallery or camera, it will return to the HomeFragment. Below is my code:
onCreate
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
// Set up the ViewPager with the sections adapter.
mViewPager = (CustomViewPager) findViewById(R.id.container);
mViewPager.setAdapter(mSectionsPagerAdapter);
mViewPager.setPagingEnabled(false);
final TabLayout tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(mViewPager);
tabLayout.setOnTabSelectedListener(
new TabLayout.ViewPagerOnTabSelectedListener(mViewPager) {
#Override
public void onTabSelected(TabLayout.Tab tab) {
super.onTabSelected(tab);
switch (tabLayout.getSelectedTabPosition()) {
case 2:
//do what you want when tab 2 is selected
AlertDialog alertDialog = new AlertDialog.Builder(SniffsTabActivity.this).create();
alertDialog.setTitle("Choose Food");
alertDialog.setButton(AlertDialog.BUTTON_POSITIVE, "Gallery",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(SniffsTabActivity.this, MediaActivity.class);
startActivity(intent);
dialog.dismiss();
}
});
alertDialog.setButton(AlertDialog.BUTTON_NEGATIVE, "Camera",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(SniffsTabActivity.this, MediaActivity.class);
startActivity(intent);
dialog.dismiss();
}
});
alertDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
// When back button pressed perform something
dialog.dismiss();
}
});
alertDialog.show();
break;
}
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
showing of fragments:
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
#Override
public Fragment getItem(int position) {
switch (position) {
case 0:
return HomeFragment.newInstance();
case 1:
return SearchFragment.newInstance();
case 2:
return ChooseImageFragment.newInstance();
case 3:
return FeedActivityFragment.newInstance();
default:
return ProfileFragment.newInstance();
}
}
#Override
public int getCount() {
return 5;
}
}
In your MediaActivity.class override the onBackPressed method or onKeyDown to finish the activity.
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
or
public boolean onKeyDown(int keyCode, KeyEvent event) {
if(keyCode == KeyEvent.KEYCODE_BACK) {
finish();
return true;
}
return true;
}
I use MaterialDrawer and code MainActivity is:
public class MainActivity extends AppCompatActivity implements KitchenFragment.CallbackOne {
public static final String TAG = "myLogTag";
private Toolbar mToolbar;
private Drawer drawer;
private FragmentManager fm;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "CLICK NOCL");
}
});
setSupportActionBar(mToolbar);
// getSupportActionBar().setDisplayHomeAsUpEnabled(false);
fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.content_frame);
if (fragment == null) {
fragment = MenuFragment.newInstance();
fm.beginTransaction()
.add(R.id.content_frame, fragment)
.commit();
}
drawer = new DrawerBuilder()
.withActivity(this)
.withToolbar(mToolbar)
.withActionBarDrawerToggle(true)
.withHeader(R.layout.drawer_header)
.addDrawerItems(
new PrimaryDrawerItem().withName(R.string.menu).withIdentifier(1),
new PrimaryDrawerItem().withName(R.string.kitchen_title).withIdentifier(2),
new PrimaryDrawerItem().withName(R.string.information_title).withEnabled(false)
).withOnDrawerItemClickListener(new Drawer.OnDrawerItemClickListener() {
#Override
public boolean onItemClick(View view, int position, IDrawerItem drawerItem) {
Log.d(TAG, "position clicked: " + position);
Fragment fragment = MenuFragment.newInstance();
switch (position) {
case 1:
fragment = MenuFragment.newInstance();
break;
case 2:
fragment = KitchenFragment.newInstance();
break;
default:
fragment = new Fragment();
}
fm.beginTransaction().replace(R.id.content_frame, fragment).commit();
return false;
}
})
.withFireOnInitialOnClick(true)
.withSavedInstance(savedInstanceState)
.withOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
#Override
public boolean onNavigationClickListener(View view) {
Log.d(TAG, "CLICK in DNL");
if (!drawer.getActionBarDrawerToggle().isDrawerIndicatorEnabled()) {
onBackPressed();
return true;
} else
return false;
}
})
.build();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(TAG, "CLICK OIS");
switch (item.getItemId()) {
case R.id.action_settings:
return true;
case android.R.id.home:
getFragmentManager().popBackStackImmediate();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState = drawer.saveInstanceState(outState);
super.onSaveInstanceState(outState);
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen())
drawer.closeDrawer();
else if (getFragmentManager().getBackStackEntryCount() == 1) {
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
drawer.getActionBarDrawerToggle().syncState();
getFragmentManager().popBackStack();
} else if (getFragmentManager().getBackStackEntryCount() > 0)
getFragmentManager().popBackStack();
else
super.onBackPressed();
}
#Override
public void setFirstSelected() {
drawer.setSelection(1);
}
}
I'm trying to trace a Click in mToolbar.setNavigationOnClickListener
and withOnDrawerNavigationListener and onOptionsItemSelected.
None of the listeners not reacted for clicking.
How you see i use Activity that launches Fragment (1), which in turn lets Fragment (2 and 3). In 2 and 3 Fragment in OnCreate i use ((AppCompatActivity)getActivity()).getSupportActionBar().setDisplayHomeAsUpEnabled(true); , and I need to by pressing the back button (in toolbar), returning the previous fragment, and not open Drawer
The MaterialDrawer already handles all the listeners for you. If you need to do an action after the drawer opens or closes you can provide the listener via the DrawerBuilder
For the icon you have this listener:
OnDrawerNavigationListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1158
For drawer close / open this listener:
OnDrawerListener
https://github.com/mikepenz/MaterialDrawer/blob/develop/library/src/main/java/com/mikepenz/materialdrawer/DrawerBuilder.java#L1116
I suggest you to create new Activity using android studio wizard. File->New->Activity->Navigation Drawer Activity.
In that case ActionBarDrawerToaggle is used
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
This toggle contains click listener which handle open/close drawer functionality for you.
Also you can that item clicks implemented through OnNavigationItemSelectedListener.onNavigationItemSelected(MenuItem item)
I'm trying to handle the back button in a fragment. I want it to go back to the fragment it came from, but the #Override I've doesn't override from its superclass, but I don't why. Futhermore the method onBackPressed() is never used. I think it's weird as it works in my activities.
public class RateFrag extends Fragment implements View.OnClickListener {
private RatingBar ratingBar;
private Button rateknap;
private Forslag forslag;
#Override
public View onCreateView(LayoutInflater i, ViewGroup container, Bundle savedInstanceState) {
View rod = i.inflate(R.layout.activity_rate, container, false);
setHasOptionsMenu(true);
forslag = ((AnnonceDisplay) this.getActivity()).getForslag();
getActivity().setTitle(forslag.getTitle());
ratingBar = (RatingBar) rod.findViewById(R.id.ratingBar);
rateknap = (Button) rod.findViewById(R.id.rateknap);
rateknap.setOnClickListener(this);
return rod;
}
#Override
public void onClick(View v) {
if (v == rateknap) {
AlertDialog alert = new AlertDialog.Builder(getActivity())
.setMessage("Vil du give " + ratingBar.getRating() + " stjerner?")
.setPositiveButton("Ja", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
launchintent();
}
}
)
.setNegativeButton("Nej", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
}
).show();
}
}
private void launchintent() {
FragmentManager fm = getFragmentManager();
Fragment f = fm.findFragmentById(R.id.fragment);
if(fm.getBackStackEntryCount() > 0){
fm.popBackStack();
} else{
getActivity().finish();
}
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
super.onCreateOptionsMenu(menu, inflater);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.Forside) {
Intent intent = new Intent(this.getActivity(), Forside.class);
startActivity(intent);
}
else if (id == R.id.Logud){
Intent intent = new Intent(this.getActivity(), LogInd.class);
startActivity(intent);
}
return true;
}
#Override //Method does not override method from its superclass
public void onBackPressed() { //Method onBackPressed is never used
if (getFragmentManager().getBackStackEntryCount() == 0) {
getActivity().finish();
} else {
getFragmentManager().popBackStack();
}
return;
}
}
Before anyone says it's a possible duplicate, I've searched here on Stackoverflow and Google. I actually got this Override from here, so please tell me what is wrong, and how I fix it.
Thanks :)
Override the onBackPress on your Activity like this
#Override
public void onBackPressed() {
int count = getFragmentManager().getBackStackEntryCount();
if (count == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}