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();
}
}
Related
i have four fragments Home, Warning, Donate, and About, Home is the first one shown on launch, what i need is that when users are on any of these fragments (Donate, About, and Caution), and when they go back to the Home fragment using backstack only, I want to show an interstitial ad before showing the home fragment.
I don't want to show the ad when the home fragment launch for first time
Main Activity
public class MainActivity extends AppCompatActivity {
public BottomNavigationView bottomNavigationView;
Deque<Integer> integerDeque = new ArrayDeque<>(3);
boolean flag = true;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Window window = this.getWindow();
window.setStatusBarColor(this.getResources().getColor(R.color.black));
bottomNavigationView = findViewById(R.id.bottomNavigationView);
bottomNavigationView.setItemIconTintList(null);
integerDeque.push(R.id.home_icon);
loadFragments(new Home_Fragment());
bottomNavigationView.setSelectedItemId(R.id.home_icon);
bottomNavigationView.setOnNavigationItemSelectedListener(
item -> {
int id = item.getItemId();
if (integerDeque.contains(id)) {
if (id == R.id.home_icon) {
integerDeque.size();
if (flag) {
integerDeque.addFirst(R.id.home_icon);
flag = false;
}
}
integerDeque.remove(id);
}
integerDeque.push(id);
loadFragments(getFragment(item.getItemId()));
return true;
}
);
}
#SuppressLint("NonConstantResourceId")
private Fragment getFragment(int itemId) {
switch (itemId) {
case R.id.home_icon:
bottomNavigationView.getMenu().getItem(0).setChecked(true);
return new Home_Fragment();
case R.id.guide_icon:
bottomNavigationView.getMenu().getItem(1).setChecked(true);
return new Cuation_Fragment();
case R.id.donate_icon:
bottomNavigationView.getMenu().getItem(2).setChecked(true);
return new Donate_Fragment();
case R.id.about_icon:
bottomNavigationView.getMenu().getItem(3).setChecked(true);
return new About_Fragment();
}
bottomNavigationView.getMenu().getItem(0).setChecked(true);
return new Home_Fragment();
}
public void loadFragments(Fragment fragment) {
if (fragment != null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, fragment, fragment.getClass().getSimpleName())
.commit();
}
}
#Override
public void onBackPressed() {
integerDeque.pop();
if (!integerDeque.isEmpty()) {
bottomNavigationView.setSelectedItemId(integerDeque.peek());
} else {
finish();
}
}
}
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 have bottom navigation and set each item load a fragment. When my application load Home fragment default selected. My application fragment Backstack work when navigate for example click Posts > Search > Favor and after press back it's work and back to Search > Post > Home But my problem in select again Previous fragment for example when navigate Post > Search > Post now when press back first press not working and not back any fragment and second press back to Home. I want work this format when navigate Post > Search > Post on press back navigate Search > Home.
I have pushFragments method and Override onBackPressed. My codes this is:
pushFragments method:
public void pushFragments(String tag, Fragment fragment){
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction fTransaction = manager.beginTransaction();
if (manager.findFragmentByTag(tag)==null){
fTransaction.add(R.id.frame_fragmentMain_container,fragment,tag);
fTransaction.addToBackStack(tag);
}
Fragment homeFragment = manager.findFragmentByTag(TAG_FRAGMENT_HOME);
Fragment postsFragment = manager.findFragmentByTag(TAG_FRAGMENT_POSTS);
Fragment usersFragment = manager.findFragmentByTag(TAG_FRAGMENT_USERS);
Fragment searchFragment = manager.findFragmentByTag(TAG_FRAGMENT_SEARCH);
Fragment favorFragment = manager.findFragmentByTag(TAG_FRAGMENT_FAVOR);
// Hide all Fragment
if(homeFragment!=null){
fTransaction.hide(homeFragment);
}
if(postsFragment!=null){
fTransaction.hide(postsFragment);
}
if(usersFragment!=null){
fTransaction.hide(usersFragment);
}
if(searchFragment!=null){
fTransaction.hide(searchFragment);
}
if(favorFragment!=null){
fTransaction.hide(favorFragment);
}
switch (tag){
case TAG_FRAGMENT_HOME:
if(homeFragment!=null){
fTransaction.show(homeFragment);
setToolbarTitle("Home Page");
disableNavigationToolbarIcon();
}
break;
case TAG_FRAGMENT_POSTS:
if(postsFragment!=null){
fTransaction.show(postsFragment);
setToolbarTitle("Posts List");
enabledNavigationToolbarIcon();
}
break;
case TAG_FRAGMENT_USERS:
if(usersFragment!=null){
fTransaction.show(usersFragment);
setToolbarTitle("Authors List");
enabledNavigationToolbarIcon();
}
break;
case TAG_FRAGMENT_SEARCH:
if(searchFragment!=null){
fTransaction.show(searchFragment);
setToolbarTitle("Search Page");
enabledNavigationToolbarIcon();
}
break;
case TAG_FRAGMENT_FAVOR:
if(favorFragment!=null){
fTransaction.show(favorFragment);
setToolbarTitle("Favor Posts");
enabledNavigationToolbarIcon();
}
break;
}
fTransaction.commitAllowingStateLoss();
}
and Override onBackPressed:
#Override
public void onBackPressed() {
FragmentManager manager = getSupportFragmentManager();
if(manager.getBackStackEntryCount()>1){
for (Fragment fragment : manager.getFragments()){
if(fragment.isVisible()){
FragmentManager childManager = fragment.getChildFragmentManager();
if(childManager.getBackStackEntryCount()>0){
if(fragment instanceof UsersFragment){
setToolbarTitle("Authors List");
}
childManager.popBackStack();
return;
}
}
}
manager.popBackStack();
}else{
new AlertDialog.Builder(this)
.setTitle("Really Exit?")
.setMessage("Are you sure you want to exit?")
.setNegativeButton(android.R.string.no, null)
.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
finish();
moveTaskToBack(true);
}
}).create().show();
}
}
Try this out..It will definitely work..
public void pushFragments(Fragment fragment) {
try {
String backStateName = fragment.getClass().getName();
FragmentManager fragmentManager = getSupportFragmentManager();
boolean fragmentPop = fragmentManager.popBackStackImmediate(backStateName, 0);
if (!fragmentPop) {
try {
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(R.id.frame_layout, fragment);
fragmentTransaction.addToBackStack(backStateName);
fragmentTransaction.commit();
} catch (Exception e) {
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
and in OnBackPress ---
#Override
public void onBackPressed() {
if (getSupportFragmentManager().getBackStackEntryCount() == 1) {
finish();
return;
}
super.onBackPressed();
}
Im using BottomNavigation Bar Library of (roughike)
Please check SnapShot attached as shown there gallery is currently select i want to de select it. and dnt want to show any selected item when i want.
please help.
SnapShot
mBottomBar = BottomBar.attach(this, savedInstanceState);
mBottomBar.useDarkTheme();
mBottomBar.setItemsFromMenu(R.menu.bottom_tab, new OnMenuTabClickListener() {
#Override
public void onMenuTabSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.HomeTab) {
displayView(0);
}
if (menuItemId == R.id.ProfileTab) {
displayView(1);
}
if (menuItemId == R.id.GalleryTab) {
displayView(2);
}
if (menuItemId == R.id.FriendsTab) {
displayView(3);
}
if (menuItemId == R.id.SettingTab) {
displayView(4);
}
}
#Override
public void onMenuTabReSelected(#IdRes int menuItemId) {
if (menuItemId == R.id.HomeTab) {
displayView(0);
}
if (menuItemId == R.id.ProfileTab) {
displayView(1);
}
if (menuItemId == R.id.GalleryTab) {
displayView(2);
}
if (menuItemId == R.id.FriendsTab) {
displayView(3);
}
if (menuItemId == R.id.SettingTab) {
displayView(4);
}
}
});
public void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 0:
fragment = new MainWall();
break;
case 1:
fragment = new Profile();
break;
case 2:
fragment = new Gallery();
break;
case 3:
fragment = new Friends();
break;
case 4:
fragment = new Settings();
break;
case 5:
fragment = new Messages();
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Necessary to restore the BottomBar's state, otherwise we would
// lose the current tab on orientation change.
mBottomBar.onSaveInstanceState(outState);
}
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();