I have implemented a ´NavigationView´ which has a few menu options that when user selects one, it changes the "main fragment" view to anothers...
My problem is, I'd like that when the user presses the back button, unless he is on the "main fragment" the screen returns to the "main fragment", otherwise close the app (regular onBackPressed() behaviour when there is no activity or backStack).
What I've done so far:
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
switch (menuItem.getItemId()) {
case R.id.debitsNavId:
getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container, new MainFragment(), "main_fragment").commit();
break;
case R.id.friendsNavId:
getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container, new FriendFragment(), "friend_fragment").commit();
break;
case R.id.notificationsNavId:
getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container, new RequestFragment(), "request_fragment").commit();
break;
case R.id.configurationsNavId:
Intent i = new Intent(MainActivity.this,
SettingsActivity.class);
startActivity(i);
break;
case R.id.logoutNavId:
logout();
break;
default:
return false;
}
menuItem.setChecked(true);
drawer_layout.closeDrawers();
return false;
}
The problem is, if the user navigates from 'FriendFragment' to 'RequestFragment' or vice-versa, the fragment that gets "backstacked" is the previous one (either FriendFragment or RequestFragment) and I'd like to still be "MainFragment".
How can I achieve that ?
Hope I made myself clear and thanks for your time !
So basically what you would need to do is that when the MainFrag is visible set a boolean to true and if you navigate away set it to false.
Then override the onBackPressed, in your main activity, like the following method:
#Override
public void onBackPressed() {
if (!isMainFragVisible) {
getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container, new MainFragment(), "main_fragment").commit();
}
}
You can set the isMainFragVisible to true in this method:
case R.id.debitsNavId:
getSupportFragmentManager().beginTransaction().replace(R.id.main_fragment_container, new MainFragment(), "main_fragment").commit();
isMainFragVisible = true
break;
And set it to false in any other navigation method.
do it this way
getSupportFragmentManager().beginTransaction().addToBackStack(fragment.getClass().getSimpleName()).replace(R.id.main_fragment_container, new MainFragment(), "main_fragment").commit();
Related
I have a bottom navigation bar with 4 fragments and 1 activity inside another activity(in which all fragment will be displayed). I want my first fragment to be displayed on the starting of the activity(in which all fragment will be displayed) along with the matching item of bottom navigation bar. My fragment 1 is getting displayed on starting but with wrong item of the bottom navigation bar.
This is what, I am getting on starting. Selected item should be Home(middle)
I have this under OnCreate
btmNav = findViewById(R.id.btmnav);
btmNav.setOnNavigationItemSelectedListener((navListner));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new RecViewFragment()).commit();
and this outside Oncreate
private BottomNavigationView.OnNavigationItemSelectedListener navListner = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()){
case R.id.navprofile:
getSupportFragmentManager().beginTransaction().
replace(R.id.fragment_container,new Fragment2()).commit();
break;
case R.id.navmap:
Intent intent = new Intent(MainActivityBuses.this, MapActivity.class);
startActivity(intent);
break;
case R.id.navhome:
getSupportFragmentManager().beginTransaction().
replace(R.id.fragment_container,new Fragment2()).commit();
break;
case R.id.navmybus:
getSupportFragmentManager().beginTransaction().
replace(R.id.fragment_container,new Fragment3()).commit();
break;
case R.id.navinfo:
getSupportFragmentManager().beginTransaction().
replace(R.id.fragment_container,new Fragment4()).commit();
break;
}
return true;
}
i got the answer,
just need to add this
btmNav.getMenu().findItem(R.id.navhome).setChecked(true);
below this
btmNav = findViewById(R.id.btmnav);
btmNav.setOnNavigationItemSelectedListener((navListner));
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,new RecViewFragment()).commit();
I'm using a BottomNavigationView with 5 items, 4 Fragments and 1 Activity as in the image below
When any fragment is clicked I want it to act normally getting clicked and checked, but when the "+" item is clicked I'm opening an Activity but I don't want it to be checked, so I want it to be clickable so it can open the Activity, but I don't want to be checked, because when the user return back from the activity will see it selected even though it's the wrong selected item.
How can I do this?
Here's my code:
bottomNavigationView = findViewById(R.id.bottom_nav_view);
bottomNavigationView.setOnNavigationItemSelectedListener(this);
.
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
Fragment fragment = null;
switch (id) {
case R.id.home_nav_menu:
fragment = new HomeFragment();
break;
case R.id.inbox_nav_menu:
fragment = new InboxFragment();
break;
case R.id.add_nav_menu:
Intent intent = new Intent(this, AddActivity.class);
startActivity(intent);
return true;
case R.id.history_nav_menu:
fragment = new HistoryFragment();
break;
case R.id.profile_nav_menu:
fragment = new ProfileFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_place_holder, fragment).commit();
return true;
}
Seeing at the source code of the listener for the bottom navigation, you just need to return false when you don't want to display item as selected.
/**
* Listener for handling selection events on bottom navigation items.
*/
public interface OnNavigationItemSelectedListener {
/**
* Called when an item in the bottom navigation menu is selected.
*
* #param item The selected item
*
* #return true to display the item as the selected item and false if the item should not
* be selected. Consider setting non-selectable items as disabled preemptively to
* make them appear non-interactive.
*/
boolean onNavigationItemSelected(#NonNull MenuItem item);
}
So you simply return false in your case R.id.add_nav_menu: and it will work.
User MenuItem#setCheckable(boolean) API in order to play with menu item's checkable state.
MenuItem menuItem = navigation.getMenu().getItem(1);
menuItem.setCheckable(false);
Try like this:
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem) {
int id = menuItem.getItemId();
Fragment fragment = null;
switch (id) {
case R.id.home_nav_menu:
fragment = new HomeFragment();
break;
case R.id.inbox_nav_menu:
fragment = new InboxFragment();
break;
case R.id.add_nav_menu:
menuItem.setCheckable(false);
Intent intent = new Intent(this, AddActivity.class);
startActivity(intent);
return true;
case R.id.history_nav_menu:
fragment = new HistoryFragment();
break;
case R.id.profile_nav_menu:
fragment = new ProfileFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_place_holder, fragment).commit();
return true;
}
is this possible ? I use framelayout to display the contents of my fragment with the use of navigation drawer. What i want to happen is to keep the state of the fragment even if i go to another fragment.
I have a vague idea on whats causing the reload which is this.
private Fragment getProfileFragment() {
switch (navItemIndex) {
case 0:
// home
ProfileLO profileLO = new ProfileLO();
return profileLO;
case 1:
LocationLO locationLO = new LocationLO();
return locationLO;
case 2:
FarmGoodsLO farmGoodsLO = new FarmGoodsLO();
return farmGoodsLO;
case 3:
RentEquipLO rentEquipLO = new RentEquipLO();
return rentEquipLO;
default:
return new ProfileLO();
}
}
Is there any hack out there?
Let's say I have a ListFragment A that is rooted from MainActivity A. User presses a list from List A and go to the FragmentActivity B. FragmentActivity holds 3 tabs of fragments.
So, I want to put an up navigation to the FragmentActivity B, so that it goes back to ListFragment A. How do I go about that?
This is my try, so far no luck:
public class ItemDetailActivity extends FragmentActivity implements ActionBar.TabListener {
...
actionBar.setDisplayHomeAsUpEnabled(true);
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
LatestFragment fragment = new LatestFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.pager, fragment).addToBackStack(null)
.commit();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
}
LatestFragment is the ListFragment A I want to go back to.
However, I got an error that says I have to implement OnLatestSelectedListener because in LatestFragment, I already put an interface to pass values.
What else can I go inside onOptionsItemSelected?
Assuming you started ItemDetailActivity with a standard intent, you should just be able to use back action like this:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
super.onBackPressed();
finish();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
If fragment A is in your main activity then you can also look in to using ActionBar. Back button takes you to the main activity. It is quite easy to implement as well.
I assume your FragmentActivityB has got the back button.
if not you can get it by
getActionBar().setDisplayHomeAsUpEnabled(true);
<meta-data android:name="android.support.PARENT_ACTIVITY"
android:value="#######" />
Now you can just identify fragments rooted with MainActivity using some flags like ViewNumber(1,2,3).
Implement the method onMenuItemSelected(....) and pass the viewNumber ie; the Fragment Which you want to show.
#Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
//We are implementing this method to respond to the back button on the action bar.
int itemId = item.getItemId();
switch (itemId) {
case android.R.id.home:
Intent i = new Intent(this,MainActivity.class);
i.putExtra("viewNumber",2);
startActivity(i);
break;
}
return true;
}//onMenuItemSelected
In MainActivity get the viewNumber using Bundles, and you can have some method like this to work out and display the desired Fragment.
private void displayView(int position) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (position) {
case 1:
fragment = new ListFragmentB();
break;
case 2:
fragment = new ListFragmentA();
break;
default:
break;
}
if (fragment != null) {
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
}
}
}
I hope it will solve your problem.
I have a Optionsmenu in my Android App, in which is a Button to Go Back to the Apps Dashboad and remove all Activities laying upon that, also removing the History. How is this possible?
thx
Got the Answer:
That's what does the Trick:
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.dashboard:
Intent myIntent = new Intent(this, DashBoard.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(myIntent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
That's what does the Trick:
myIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);