Is it really necessary to always recreate fragments when navigating the bottom nav menu like in this code?
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_home:
selectedFragment = new HomeFragment();
break;
case R.id.nav_favorites:
selectedFragment = new FavoritesFragment();
break;
case R.id.nav_search:
selectedFragment = new SearchFragment();
break;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container,
selectedFragment).commit();
return true;
}
};
I would rather like to create all my Fragments once in onCreate of the surrounding MainActivity and store them there as member variables. Then i could in the onNavigationItemSelected just use the references to my fragments instead of creating new fragments.
Is it okay to do it as described and not use the code above? Or could doing it as described cause complications somewhere?
Actually, creating them on create would be the best way. Also, sometimes people tend to add a lot of initializations on their on create and in the long run ur app might use too much memory when initializing the fragments every time you need them.
You would have to be responsible for saving your fragments state, so on recreation, your data would be readily available. You could try something like this
https://proandroiddev.com/fragments-swapping-with-bottom-bar-ffbd265bd742
Although there are many approaches you could attempt.
You could create all the fragments at once and swap them with your bottom navigation. But I wouldn't recommend that for obvious navigation and performance reasons.
Related
I'm having a problem, with fragments, after inserting them into a package, when I instantiate an object I get FragmentAssumiPersonaleBinding, I do not understand why it comes out this way, when I do the replace of the fragment it gives me error. I tried to remove the fragments from the package but from the same problem, while with the previous fragments this thing does not happen and work normally.
public void navigaNavigationBar(){
NavigationBarView navigationBarView = findViewById(R.id.bottomNavigationView);
navigationBarView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
//Quando viene cliccato sulla navigationBar viene preso l'id dell'item cliccato
switch (item.getItemId()){
case R.id.navigation_bar_acquisisci_lavoro:
FragmentAssumiPersonaleBinding fragmentAssumiPersonaleBinding = new FragmentAssumiPersonaleBinding();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.FrameLayout_home_azienda,fragmentAssumiPersonaleBinding);
transaction.addToBackStack(null);
transaction.commit();
return true;
case R.id.navigation_bar_assumi_personale:
case R.id.navigation_bar_home_azienda:
return true;
case R.id.navigation_bar_gestisci_azienda:
}
return false;
}
});
}
I'm also not understanding how to manage the click of the navigation bar, because I tried to use navigationBarView.setOnItemSelectedListener(new NavigationBarView.OnItemSelectedListener() but it does not work, while the other method with the navigationBarView is deprecated, although it is not deprecated on the documentation, but I have not found an alternative. thank you :)
I wanted to add that the fragmentbinding I did not call it so but it is written automatically so, and the error is in fragmentAssumiPersonaleBinding because required a type of Fragment not a FragmentBinding
I solved the problem, practically when you create a new package, rightly the fragment ends up in the new package, which is completely separate from the main package, so when you try to create the object you call it object name + binding and in the case of fragment s they give problems. I solved by deleting the class from the project folder, if you do it from the IDE it doesn't solve the problem, I put the class in the same package manually and it works. Anyway this forum is absurd, I can not post an answer
This question already has answers here:
Fragment with multiple backstack
(4 answers)
Closed last year.
Hello i want to manage BackStack in fragment i have implemented a method but im not happy with it becuase if i switch to multiple fragments again and again ,then i want that backstack dont switch to the same fragment again and again and just goes to each fragments one time backward and in the last to the Home_Fragment and then exit
For Eg : if i switch from notification to profile and make it like a loop by pressing it again and again ,and when i start pressing back it also follows the same loop that i dont want ,i want that even user do a thing like this the back stack only goes to each fragment only once and at the last goes to the Home Fragment and exit
Just like a big app like instagram or pintrest
here is a code
private final BottomNavigationView.OnNavigationItemSelectedListener navigationItemSelectedListener =
item -> {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.nav_home:
selectedFragment = new Home_Fragment();
break;
case R.id.nav_following:
selectedFragment = new Following_Fragment();
break;
case R.id.nav_upload:
selectedFragment = new Upload_Fragment();
break;
case R.id.nav_notification:
selectedFragment = new Notification_Fragment();
break;
case R.id.nav_profile:
selectedFragment = new Profile_Fragment();
break;
}
assert selectedFragment != null;
getSupportFragmentManager().beginTransaction().addToBackStack(String.valueOf(selectedFragment)).replace(R.id.fragment_container,
selectedFragment).commit();
return true;
};
I'm having difficulty understanding the question/problem, but if you want to avoid re-adding a fragment that is already added then you could check the stack before adding a new fragment is it is already there. This article might be helpful.
use popBackStackImmediate("your-tag",0)
or findFragmentByTag in fragmentManager and replace it(be careful about adding to back stack again and again).
My code works very well
But sometimes layouts overlap
The reason for this code is that the first fragment should not be reloaded.
And the second and third fragments should always be reloaded
Have you ever had problems with layout overlapping code?
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem menuItem)
{
Fragment selectedFragment = null;
switch (menuItem.getItemId())
{
case R.id.timer:
fm.beginTransaction().hide(active).show(fragment1).commit();
active = fragment1;
break;
case R.id.favorite:
fm.beginTransaction().hide(active).commit();
fm.beginTransaction().detach(fragment2).attach(fragment2).commit();
fm.beginTransaction().show(fragment2).commit();
active = fragment2;
break;
case R.id.calendar:
fm.beginTransaction().hide(active).commit();
fm.beginTransaction().detach(fragment3).attach(fragment3).commit();
fm.beginTransaction().show(fragment3).commit();
active = fragment3;
break;
}
return true;
}
As per my understanding you have to show one screen based on menu click so why not you're using FrameLayout in xml and based on click or any event just add or replace the fragment. Make 3 different Fragment class and use interface or any latest arch component provide by Google.
I would like to get some input on the best way to structure my app's architecture when using Android's Bottom Navigation View.
Currently I define my BottomNavigationView in my MainActivity. It looks something like this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BottomNavigationView bottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_navigation);
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()){
case R.id.action_home:
selectedFragment = HomeFragment.newInstance();
break;
case R.id.action_search:
selectedFragment = SearchFragment.newInstance();
break;
case R.id.action_message:
selectedFragment = MessageFragment.newInstance();
break;
case R.id.action_profile:
selectedFragment = ProfileFragment.newInstance();
break;
}
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
return true;
}
});
//Manually displaying the first fragment - one time only
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, HomeFragment.newInstance());
transaction.commit();
}
The problem is that once I click on one tab, it opens up a fragment, and I would like to have those Fragments open up other Fragments/Activities (i.e:
I open the profile tab (`ProfileFragment` loads)
I click on a button from `ProfileFragment`, and from this the `SignUpFragment` or `SignUpActivity` loads
After running into many bugs, I've researched on how to architect my app, but i've found mixed results. Would anyone know the correct way of using a BottomNavigationView with Fragments, and in those fragments I can load more Activities/fragments. A huge thanks in advance.
Every approach depends on the project and what you pretend to achieve. I had to code a Bottom Navigation app that works with over 20 Bottom Navigation layouts, meaning one single Activity. The process you wish to achieve is pretty much the same of setting the desired fragment in the desired tab on tab selected, the difference is that, instead of taping on a tab, you will tap on a button inside a fragment, which you will replace with the new desired fragment.
tap tab -> replace fragment -> button click inside fragment -> replace fragment -> and so on.
Since you are using replace, you will have to carefully handle your onBackPress event, since I'm assuming that on every back press you wish to go back to the previous fragment. Myself, I've implemented an interface in the Main Activity that listens to the visible fragment onBackPress.
I created an activity with a bottom navigation bar.
I googled a lot things about it but now I don't know how to handle this exactly.
Before, I just started another activity when the user clicks the bottom navigation but I think it's not good.
How can I switch between the tabs?
Do I have to work with fragments? And what about 'setContentView(int layoutResID)'? How can I do that? I'm confused...
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener = new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
return true;
case R.id.navigation_dashboard:
startActivity(dashboardActivity);
return true;
case R.id.navigation_notifications:
startActivity(dashboardActivity);
return true;
}
return false;
}
};
Thank you very much for your help - I hope, you understood what I mean.
Activity transition is always expensive and we should switch from one activity to another only when we are switching the context. A fragment is a portion of UI in an activity. Same fragment can be used with multiple activities. Just like activity a fragment has its own lifecycle and setContentView(int layoutResID) can be set to different layout in OnCreate of fragment.
This link explains more on when to use activity or fragment.
Android developer guide on Fragments
Code path tutorial on bottom navigation views.
Please refer to :-
https://github.com/waleedsarwar86/BottomNavigationDemo
and complete explanation in
http://waleedsarwar.com/posts/2016-05-21-three-tabs-bottom-navigation/
You will get a running code with the explanation here.
Bottom Navigation View is a navigation bar introduced in android library to make it easy to switch between views with a single tap. It can although be used for almost any purpose, but is most commonly used to switch between fragments with a single tap. Its use for opening activities is somewhat absurd, since it ignores its most important functionality of switching the views with a single tap. There are many good articles and blogs out there in this regard, one of which is:
https://medium.com/#hitherejoe/exploring-the-android-design-support-library-bottom-navigation-drawer-548de699e8e0
Hope this solves your doubt..
bottomNavigationView.setOnNavigationItemSelectedListener
(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment selectedFragment = null;
switch (item.getItemId()) {
case R.id.action_item1:
selectedFragment = ItemOneFragment.newInstance();
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, selectedFragment);
transaction.commit();
// selectedFragment.getChildFragmentManager().beginTransaction();
break;
case R.id.action_item2:
selectedFragment = ItemTwoFragment.newInstance();
FragmentTransaction transactiona = getSupportFragmentManager().beginTransaction();
transactiona.replace(R.id.frame_layout, selectedFragment);
transactiona.commit();
// selectedFragment = ItemThreeFragment.newInstance();
break;
case R.id.action_item3:
// selectedFragment = ItemOneFragment.newInstance();
Intent intent=new Intent(MainView.this, YoutActivityLive.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
// selectedFragment = ItemTwoFragment.newInstance();
break;
case R.id.action_item5:
selectedFragment = ItemOneFragment.newInstance();
FragmentTransaction transactionb = getSupportFragmentManager().beginTransaction();
transactionb.replace(R.id.frame_layout, selectedFragment);
transactionb.commit();
// selectedFragment = ItemFiveFragment.newInstance();
break;
}
return true;
}
});