Navigation drawer implementation with list fragments - android

I want to implement a navigation drawer with multiple listfragments, how can i do this? I spent time searching online but couldnt find anything related to it. Any help would be appreciated!

When implementing the NavigationDrawer, use its onDrawerItemSelected method to switch Fragments:
#Override
public void onDrawerItemSelected(final int pos) {
// update the main content by replacing fragments
Fragment fragment = null;
switch (pos) {
case 0:
fragment = new ListFragmentOne();
break;
case 1:
fragment = new ListFragmentTwo();
break;
case 2:
fragment = new ListFragmentThree();
break;
}
// content_frame is a FrameLayout inside the layout of your activity - this is where the fragment will be put
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
mDrawerList.setItemChecked(pos, true);
// do stuff like closing the drawer...
}
I am not sure though if the NavigationDrawer even supports ListFragments. If not, simply use normal Fragments containing a ListView.

Related

How to save fragment state : Bottom Navigation View with fragments android

Im creating a app with three sections home,color,profile I'm using bottom navigation view with fragments to achieve this.
App UI
Here is my code:
Main Activity on create method:
final HomeFragment homeFragment = new HomeFragment();
final ColorFragment colorFragment = new ColorFragment();
final ProfileFragment profileFragment = new ProfileFragment();
bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
Fragment active = homeFragment;
switch (item.getItemId()){
case R.id.action_home:
active = homeFragment;
break;
//return true;
case R.id.action_color:
active = colorFragment;
break;
case R.id.action_profile:
active = profileFragment;
break;
default:
active = homeFragment;
break;
}
//Loading the fragment on click
fragmentManager.beginTransaction().replace(R.id.fragment_container,active).commit();
return true;
}
});
Im using fragment manager to load the fragment in my Main Activity which comes with below problem.
1.It reloads the fragment each time I click on the bottom navigation icon.(Im getting data from firebase this will be costly )
I have read many articles regarding this,i found solutions like below:
Using hiding the fragments on creation of activity
fragmentManager.beginTransaction().add(R.id.fragment_container, profileFragment, "3").hide(profileFragment).commit();
fragmentManager.beginTransaction().add(R.id.fragment_container, colorFragment, "2").hide(colorFragment).commit();
fragmentManager.beginTransaction().add(R.id.fragment_container,homeFragment, "1").commit();
Above solution loads all the fragments on the creation of activity which isn't a efficient scnario
Using NavHost :
It refresh the fragment every time.
This also not working for me.
Please Help:
What I want to acheive:
1.The fragment should only load when I click on the icon for the first time.
2.All the fragments should not load at the time of activity creation.
3.When I revist the fragment It should not load again, I should stay at previous state ex. scrolled till 25th card
//Its should be like playstore,youtube where when we click on icon it loads the data, when we revisit the state will be there.
You either need to use extension function provided by Google for BottomNavigationView or use a ViewPager/ViewPager2 to have each fragment have it's own back stack and going back to exact same fragment instead of creating root fragment over and over again. Both solutions require you to have NavHostFragment as root of each tab. You can check out the samples in this repo.
You can either use a FragmentPagerAdapter or ViewPager2. I refer you to two answers for a similar question:
1- FragmentPagerAdapter
2- ViewPager2

Correct Activity/Fragment Architecture for Android Bottom Navigation View

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.

how to effectively implement ViewPager with different fragments?

So far I have only implemented ViewPager with one type of fragment.
Now I want to add navigation tabs and be able to slide sideways from fragment of type A to fragment of type B . Do I need to contain both types of fragments in one activity ? If so , does it matter which fragment will have the view pager?
thank you.
Neither of the fragments contain the ViewPager. That would be contained in this case in your activity. The navigation tabs sit above the Viewager. Look at this tutorial: https://github.com/codepath/android_guides/wiki/Sliding-Tabs-with-PagerSlidingTabStrip . You can specify what fragments go in the ViewPager in the getItem method of a FragmentPagerAdater.
#Override
public Fragment getItem(int position) {
Fragment fragment =null;
switch (position) {
case 0:
fragment = fragment1.newInstance();
break;
case 1:
fragment = fragment2.newInstance();
break;
case 2:
fragment = fragment3.newInstance();
break; }
return fragment;
}

Save the state of navigation drawer fragments

I am trying to save the state on the navigation drawer fragments as I toggle between different fragments within the navigation drawer. For Example: I start at Fragment A fire some events, then toggle to Fragment B. Then I want to see the same state of Fragment A when I toggle back to Fragment A from Fragment B.
I tried using the onSavedInstanceState(Bundle savedInstanceState) but it only gets called when the orientation changes in the fragment life cycle. A new fragment gets created whenever I toggle to a new fragment and I can't figure out how to save data from a fragment and reload it on another visit.
I don't want to use backstack() either because it removes all the fragments up to the fragment that I want to restore.
Below is how I call the fragments on the drawer toggle.
private void selectItem(int position) {
Fragment fragment;
String TAG;
switch (position) {
case 0:
fragment = new FragmntA();
TAG = "A";
break;
case 1:
fragment = new FragmentB();
TAG = "B";
break;
case 2:
fragment = new FragmentC();
TAG = "C";
break;
case 3:
fragment = new FragmentD();
TAG = "D";
break;
case 4:
fragment = new FragmentE();
TAG = "E";
break;
default:
fragment = new FragmentA();
TAG = "A";
}
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction ft = fragmentManager.beginTransaction();
ft.replace(R.id.content_frame, fragment, TAG);
ft.commit()
I don't know if there is any point in the fragment life cycle where I can save its state. Any help would be appreciated. Thanks.
To not loose the state of your fragments when switching from one to another you should do "new Fragment()" only once, and keep the instance in a global variable.
But this will not fix the rotation problem.
For the rotation problem, you should read this => http://blog.sqisland.com/2014/06/navigationdrawer-creates-fragment-twice.html
Not easy but I haven't found another way yet.
define fragment object as static in the class and in newInstance method only initialise is fragment is null otherwise just return the fragment.
This will solve your problem.
but for orientation change you will have to use on saveinstancestate method.

Replace Activity to Fragment

I have a drawer navigation with:
private void DisplayView (int position) {
Fragment fragment = null;
switch (position) {
case 0:
fragment = new Fragment1();
break;
case 1:
fragment = new Fragment2();
break;
case 2:
       ...  
From an activity I can throw that fragment (fragment2 for example)? With BeginTransaction?
Thanks
A Fragment cannot exist in it's own, eg. without an Activity. It cannot be fired up with an Intent like Activities do. You have to either create a new Activity to hold your new Fragment or replace the Fragment of your current Activity with the new one.
You cannot start fragment as an activity, they need to be added to activities.
Read more in the docs here
Also, see this

Categories

Resources