├── .gitignore ├── .idea ├── .name ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── .travis.yml ├── CHANGELOG.md ├── FragNavDemo.gif ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── ncapdevi │ │ │ └── sample │ │ │ ├── activities │ │ │ ├── BottomTabsActivity.java │ │ │ ├── MainActivity.java │ │ │ └── NavDrawerActivity.java │ │ │ └── fragments │ │ │ ├── BaseFragment.java │ │ │ ├── FavoritesFragment.java │ │ │ ├── FoodFragment.java │ │ │ ├── FriendsFragment.java │ │ │ ├── NearbyFragment.java │ │ │ └── RecentsFragment.java │ └── res │ │ ├── anim │ │ ├── slide_in_from_left.xml │ │ ├── slide_in_from_right.xml │ │ ├── slide_out_to_left.xml │ │ └── slide_out_to_right.xml │ │ ├── drawable-hdpi │ │ ├── ic_favorites.png │ │ ├── ic_friends.png │ │ ├── ic_nearby.png │ │ ├── ic_recents.png │ │ └── ic_restaurants.png │ │ ├── drawable-mdpi │ │ ├── ic_favorites.png │ │ ├── ic_friends.png │ │ ├── ic_nearby.png │ │ ├── ic_recents.png │ │ └── ic_restaurants.png │ │ ├── drawable-xhdpi │ │ ├── ic_favorites.png │ │ ├── ic_friends.png │ │ ├── ic_nearby.png │ │ ├── ic_recents.png │ │ └── ic_restaurants.png │ │ ├── drawable-xxhdpi │ │ ├── ic_favorites.png │ │ ├── ic_friends.png │ │ ├── ic_nearby.png │ │ ├── ic_recents.png │ │ └── ic_restaurants.png │ │ ├── drawable-xxxhdpi │ │ ├── ic_favorites.png │ │ ├── ic_friends.png │ │ ├── ic_nearby.png │ │ ├── ic_recents.png │ │ └── ic_restaurants.png │ │ ├── drawable │ │ └── side_nav_bar.xml │ │ ├── layout │ │ ├── activity_bottom_tabs.xml │ │ ├── activity_main.xml │ │ ├── activity_nav_drawer.xml │ │ ├── app_bar_nav_drawer.xml │ │ ├── content_nav_drawer.xml │ │ ├── fragment_main.xml │ │ └── nav_header_nav_drawer.xml │ │ ├── menu │ │ └── activity_nav_drawer_drawer.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values-w820dp │ │ └── dimens.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ └── menu_bottombar.xml │ └── test │ └── java │ └── com │ └── ncapdevi │ └── sample │ └── AppUnitTests.java ├── build.gradle ├── frag-nav ├── .gitignore ├── build.gradle ├── pom.xml ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── ncapdevi │ │ │ └── fragnav │ │ │ ├── FragNavController.java │ │ │ ├── FragNavLogger.java │ │ │ ├── FragNavPopController.java │ │ │ ├── FragNavSwitchController.java │ │ │ ├── FragNavTransactionOptions.java │ │ │ └── tabhistory │ │ │ ├── BaseFragNavTabHistoryController.java │ │ │ ├── CollectionFragNavTabHistoryController.java │ │ │ ├── CurrentTabHistoryController.java │ │ │ ├── FragNavTabHistoryController.java │ │ │ ├── UniqueTabHistoryController.java │ │ │ └── UnlimitedTabHistoryController.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── ncapdevi │ └── fragnav │ ├── FragNavTransactionOptionsTest.java │ ├── MockTest.java │ └── tabhistory │ ├── CurrentTabHistoryControllerTest.java │ ├── UniqueTabHistoryControllerTest.java │ └── UnlimitedTabHistoryControllerTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .idea 10 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | FragNav -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 26 | 27 | 28 | 29 | 30 | 31 | 33 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | android: 4 | components: 5 | # use the latest revision of Android SDK Tools 6 | - platform-tools 7 | - tools 8 | 9 | # The BuildTools version used by your project 10 | - build-tools-27.0.3 11 | 12 | # The SDK version used to compile your project 13 | - android-27 14 | 15 | # Additional components 16 | - extra-android-m2repository 17 | - extra-android-support 18 | 19 | licenses: 20 | - 'android-sdk-preview-license-.+' 21 | - 'android-sdk-license-.+' 22 | - 'google-gdk-license-.+' 23 | 24 | jdk: 25 | - oraclejdk8 26 | 27 | 28 | 29 | 30 | notifications: 31 | email: false 32 | 33 | 34 | cache: 35 | directories: 36 | - $HOME/.m2 37 | - $HOME/.gradle 38 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | All changelogs are in the release section 2 | 3 | https://github.com/ncapdevi/FragNav/releases 4 | -------------------------------------------------------------------------------- /FragNavDemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/FragNavDemo.gif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://travis-ci.org/ncapdevi/FragNav.svg?branch=master)](https://travis-ci.org/ncapdevi/FragNav) 2 | 3 | # FragNav 4 | Android library for managing multiple stacks of fragments (e.g., [Bottom Navigation ](https://www.google.com/design/spec/components/bottom-navigation.html), [Navigation Drawer](https://www.google.com/design/spec/patterns/navigation-drawer.html)). This library does NOT include the UI for bottom tab bar layout. For that, I recommend either [BottomBar](https://github.com/roughike/BottomBar) (which is the library shown in the demo) or [AHBottomNavigation](https://github.com/aurelhubert/ahbottomnavigation). This library helps maintain order after pushing onto and popping from multiple stacks(tabs). It also helps with switching between desired tabs and clearing the stacks. 5 | 6 | 7 | 8 | ## Sample 9 | With [Material Design Bottom Navigation pattern](https://www.google.com/design/spec/components/bottom-navigation.html), and other tabbed navigation, managing multiple stacks of fragments can be a real headache. The example file shows best practice for navigating deep within a tab stack. 10 | 11 | ## Gradle 12 | 13 | ```groovy 14 | implementation 'com.ncapdevi:frag-nav:2.4.0' //or or `compile` if on older gradle version 15 | ``` 16 | 17 | ## How do I implement it? 18 | 19 | ### Initialize using a builder and one of two methods 20 | ```java 21 | builder = FragNavController.newBuilder(savedInstanceState, getSupportFragmentManager(), R.id.container); 22 | ``` 23 | #### 1. 24 | Create a list of fragments and pass them in 25 | ```java 26 | List fragments = new ArrayList<>(5); 27 | 28 | fragments.add(RecentsFragment.newInstance()); 29 | fragments.add(FavoritesFragment.newInstance()); 30 | fragments.add(NearbyFragment.newInstance()); 31 | fragments.add(FriendsFragment.newInstance()); 32 | fragments.add(FoodFragment.newInstance()); 33 | 34 | builder.rootFragments(fragments); 35 | ``` 36 | #### 37 | 38 | 39 | Allow for dynamically creating the base class by implementing the NavListener in your class and overriding the getRootFragment method 40 | 41 | ```java 42 | public class YourActivity extends AppCompatActivity implements FragNavController.RootFragmentListener { 43 | ``` 44 | 45 | ```java 46 | builder.rootFragmentListener(this, 5) 47 | ``` 48 | 49 | ```java 50 | 51 | @Override 52 | public Fragment getRootFragment(int index) { 53 | switch (index) { 54 | case INDEX_RECENTS: 55 | return RecentsFragment.newInstance(0); 56 | case INDEX_FAVORITES: 57 | return FavoritesFragment.newInstance(0); 58 | case INDEX_NEARBY: 59 | return NearbyFragment.newInstance(0); 60 | case INDEX_FRIENDS: 61 | return FriendsFragment.newInstance(0); 62 | case INDEX_FOOD: 63 | return FoodFragment.newInstance(0); 64 | } 65 | throw new IllegalStateException("Need to send an index that we know"); 66 | } 67 | ``` 68 | 69 | #### 3. 70 | ```java 71 | mFragNavController = builder.build(); 72 | ``` 73 | 74 | ### SaveInstanceState 75 | 76 | Send in the supportFragment Manager, a list of base fragments, the container that you'll be using to display fragments. 77 | After that, you have four main functions that you can use 78 | In your activity, you'll also want to override your onSaveInstanceState like so 79 | 80 | ```java 81 | @Override 82 | protected void onSaveInstanceState(Bundle outState) { 83 | super.onSaveInstanceState(outState); 84 | if (mNavController != null) { 85 | mNavController.onSaveInstanceState(outState); 86 | } 87 | } 88 | ``` 89 | 90 | ### Switch tabs 91 | Tab switching is indexed to try to prevent you from sending in wrong indices. It also will throw an error if you try to switch to a tab you haven't defined a base fragment for. 92 | 93 | ```java 94 | fragNavController.switchTab(NavController.TAB1); 95 | ``` 96 | 97 | ### Push a fragment 98 | You can only push onto the currently selected index 99 | ```java 100 | fragNavController.pushFragment(FoodFragment.newInstance()) 101 | ``` 102 | 103 | ### Pop a fragment 104 | You can only pop from the currently selected index. This can throw an UnsupportedOperationException if trying to pop the root fragment 105 | ```java 106 | fragNavController.popFragment(); 107 | ``` 108 | ### Pop multiple fragments 109 | You can pop multiple fragments at once, with the same rules as above applying. If the pop depth is deeper than possible, it will stop when it gets to the root fragment 110 | ```java 111 | fragNavController.popFragments(3); 112 | ``` 113 | ### Replacing a fragment 114 | You can only replace onto the currently selected index 115 | ```java 116 | fragNavController.replaceFragment(Fragment fragment); 117 | ``` 118 | ### You can also clear the stack to bring you back to the base fragment 119 | ```java 120 | fragNavController.clearStack(); 121 | ``` 122 | ### You can also navigate your DialogFragments using 123 | ```java 124 | showDialogFragment(dialogFragment); 125 | clearDialogFragment(); 126 | getCurrentDialogFrag() 127 | ``` 128 | 129 | ### Transaction Options 130 | All of the above transactions can also be done with defined transaction options. 131 | The FragNavTransactionOptions have a builder that can be used. 132 | ```java 133 | public class FragNavTransactionOptions { 134 | List> sharedElements; 135 | @FragNavController.Transit 136 | int transition = FragmentTransaction.TRANSIT_NONE; 137 | @AnimRes 138 | int enterAnimation = 0; 139 | @AnimRes 140 | int exitAnimation = 0; 141 | @AnimRes 142 | int popEnterAnimation = 0; 143 | @AnimRes 144 | int popExitAnimation = 0; 145 | @StyleRes 146 | int transitionStyle = 0; 147 | String breadCrumbTitle; 148 | String breadCrumbShortTitle; 149 | } 150 | ``` 151 | 152 | ### Get informed of fragment transactions 153 | Have your activity implement FragNavController.TransactionListener 154 | and you will have methods that inform you of tab switches or fragment transactions 155 | 156 | A sample application is in the repo if you need to see how it works. 157 | 158 | ### Fragment Transitions 159 | 160 | Use FragNavController.setTransitionMode(); 161 | 162 | ### Helper functions 163 | ```java 164 | /** 165 | * Get the number of fragment stacks 166 | * 167 | * @return the number of fragment stacks 168 | */ 169 | @CheckResult 170 | public int getSize() { 171 | return mFragmentStacks.size(); 172 | } 173 | 174 | /** 175 | * Get a copy of the stack at a given index 176 | * 177 | * @return requested stack 178 | */ 179 | @SuppressWarnings("unchecked") 180 | @CheckResult 181 | @Nullable 182 | public Stack getStack(@TabIndex int index) { 183 | if (index == NO_TAB) { 184 | return null; 185 | } 186 | if (index >= mFragmentStacks.size()) { 187 | throw new IndexOutOfBoundsException("Can't get an index that's larger than we've setup"); 188 | } 189 | return (Stack) mFragmentStacks.get(index).clone(); 190 | } 191 | 192 | /** 193 | * Get a copy of the current stack that is being displayed 194 | * 195 | * @return Current stack 196 | */ 197 | @SuppressWarnings("unchecked") 198 | @CheckResult 199 | @Nullable 200 | public Stack getCurrentStack() { 201 | return getStack(mSelectedTabIndex); 202 | } 203 | 204 | /** 205 | * Get the index of the current stack that is being displayed 206 | * 207 | * @return Current stack index 208 | */ 209 | @CheckResult 210 | @TabIndex 211 | public int getCurrentStackIndex() { 212 | return mSelectedTabIndex; 213 | } 214 | 215 | /** 216 | * @return If true, you are at the bottom of the stack 217 | * (Consider using replaceFragment if you need to change the root fragment for some reason) 218 | * else you can popFragment as needed as your are not at the root 219 | */ 220 | @CheckResult 221 | public boolean isRootFragment() { 222 | Stack stack = getCurrentStack(); 223 | 224 | return stack == null || stack.size() == 1; 225 | } 226 | 227 | /** 228 | * Helper function to get wether the fragmentManger has gone through a stateSave, if this is true, you probably want to commit allowing stateloss 229 | * 230 | * @return if fragmentManger isStateSaved 231 | */ 232 | public boolean isStateSaved() { 233 | return mFragmentManager.isStateSaved(); 234 | } 235 | 236 | /** 237 | * Use this if you need to make sure that pending transactions occur immediately. This call is safe to 238 | * call as often as you want as there's a check to prevent multiple executePendingTransactions at once 239 | * 240 | */ 241 | public void executePendingTransactions() { 242 | if (!mExecutingTransaction) { 243 | mExecutingTransaction = true; 244 | mFragmentManager.executePendingTransactions(); 245 | mExecutingTransaction = false; 246 | } 247 | } 248 | 249 | 250 | ``` 251 | 252 | ## Restoring Fragment State 253 | Fragments transitions in this library use attach()/detch() (http://daniel-codes.blogspot.com/2012/06/fragment-transactions-reference.html). This is a delibrate choice in order to maintain the fragment's lifecycle, as well as being optimal for memory. This means that fragments will go through their proper lifecycle https://developer.android.com/guide/components/fragments.html#Lifecycle . This lifecycle includes going through `OnCreateView` which means that if you want to maintain view states, that is outside the scope of this library, and is up to the indiviudal fragment. There are plenty of resources out there that will help you design your fragments in such a way that their view state can be restored https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en and there are libraries that can help restore other states https://github.com/frankiesardo/icepick 254 | 255 | ## Apps Using FragNav 256 | Feel free to send me a pull request with your app and I'll link you here: 257 | 258 | ## Contributions 259 | If you have any problems, feel free to create an issue or pull request. 260 | 261 | The sample app in the repository uses [BottomBar](https://github.com/roughike/BottomBar) library. 262 | 263 | ## License 264 | 265 | ``` 266 | FragNav Android Fragment Navigation Library 267 | Copyright (c) 2016 Nic Capdevila (http://github.com/ncapdevi). 268 | 269 | Licensed under the Apache License, Version 2.0 (the "License"); 270 | you may not use this file except in compliance with the License. 271 | You may obtain a copy of the License at 272 | 273 | http://www.apache.org/licenses/LICENSE-2.0 274 | 275 | Unless required by applicable law or agreed to in writing, software 276 | distributed under the License is distributed on an "AS IS" BASIS, 277 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 278 | See the License for the specific language governing permissions and 279 | limitations under the License. 280 | ``` 281 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | lintOptions { 7 | abortOnError false 8 | } 9 | defaultConfig { 10 | applicationId "com.ncapdevi.sample" 11 | minSdkVersion rootProject.ext.minSdkVersion 12 | targetSdkVersion rootProject.ext.compileSdkVersion 13 | versionCode 1 14 | versionName "1.0" 15 | } 16 | buildTypes { 17 | release { 18 | minifyEnabled false 19 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 20 | } 21 | } 22 | } 23 | repositories { 24 | jcenter() 25 | } 26 | 27 | dependencies { 28 | implementation project(':frag-nav') 29 | // implementation 'com.ncapdevi:frag-nav:2.2.1' 30 | implementation project(':frag-nav') 31 | implementation "com.android.support:appcompat-v7:$rootProject.ext.supportVersion" 32 | implementation "com.android.support:design:$rootProject.ext.supportVersion" 33 | implementation "com.roughike:bottom-bar:2.3.1" 34 | testImplementation "junit:junit:$rootProject.ext.junitVersion" 35 | } 36 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/niccapdevila/.android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/activities/BottomTabsActivity.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.IdRes; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.MenuItem; 8 | 9 | import com.ncapdevi.fragnav.FragNavController; 10 | import com.ncapdevi.fragnav.FragNavSwitchController; 11 | import com.ncapdevi.fragnav.FragNavTransactionOptions; 12 | import com.ncapdevi.fragnav.tabhistory.FragNavTabHistoryController; 13 | import com.ncapdevi.sample.R; 14 | import com.ncapdevi.sample.fragments.BaseFragment; 15 | import com.ncapdevi.sample.fragments.FavoritesFragment; 16 | import com.ncapdevi.sample.fragments.FoodFragment; 17 | import com.ncapdevi.sample.fragments.FriendsFragment; 18 | import com.ncapdevi.sample.fragments.NearbyFragment; 19 | import com.ncapdevi.sample.fragments.RecentsFragment; 20 | import com.roughike.bottombar.BottomBar; 21 | import com.roughike.bottombar.OnTabReselectListener; 22 | import com.roughike.bottombar.OnTabSelectListener; 23 | 24 | public class BottomTabsActivity extends AppCompatActivity implements BaseFragment.FragmentNavigation, FragNavController.TransactionListener, FragNavController.RootFragmentListener { 25 | //Better convention to properly name the indices what they are in your app 26 | private final int INDEX_RECENTS = FragNavController.TAB1; 27 | private final int INDEX_FAVORITES = FragNavController.TAB2; 28 | private final int INDEX_NEARBY = FragNavController.TAB3; 29 | private final int INDEX_FRIENDS = FragNavController.TAB4; 30 | private final int INDEX_FOOD = FragNavController.TAB5; 31 | private FragNavController mNavController; 32 | 33 | @Override 34 | protected void onCreate(Bundle savedInstanceState) { 35 | super.onCreate(savedInstanceState); 36 | setContentView(com.ncapdevi.sample.R.layout.activity_bottom_tabs); 37 | 38 | final BottomBar bottomBar = findViewById(R.id.bottomBar); 39 | boolean initial = savedInstanceState == null; 40 | if (initial) { 41 | bottomBar.selectTabAtPosition(INDEX_NEARBY); 42 | } 43 | mNavController = FragNavController.newBuilder(savedInstanceState, getSupportFragmentManager(), R.id.container) 44 | .transactionListener(this) 45 | .rootFragmentListener(this, 5) 46 | .popStrategy(FragNavTabHistoryController.UNIQUE_TAB_HISTORY) 47 | .switchController(new FragNavSwitchController() { 48 | @Override 49 | public void switchTab(int index, FragNavTransactionOptions transactionOptions) { 50 | bottomBar.selectTabAtPosition(index); 51 | } 52 | }) 53 | .build(); 54 | 55 | 56 | bottomBar.setOnTabSelectListener(new OnTabSelectListener() { 57 | @Override 58 | public void onTabSelected(@IdRes int tabId) { 59 | switch (tabId) { 60 | case R.id.bb_menu_recents: 61 | mNavController.switchTab(INDEX_RECENTS); 62 | break; 63 | case R.id.bb_menu_favorites: 64 | mNavController.switchTab(INDEX_FAVORITES); 65 | break; 66 | case R.id.bb_menu_nearby: 67 | mNavController.switchTab(INDEX_NEARBY); 68 | break; 69 | case R.id.bb_menu_friends: 70 | mNavController.switchTab(INDEX_FRIENDS); 71 | break; 72 | case R.id.bb_menu_food: 73 | mNavController.switchTab(INDEX_FOOD); 74 | break; 75 | } 76 | } 77 | }, initial); 78 | 79 | bottomBar.setOnTabReselectListener(new OnTabReselectListener() { 80 | @Override 81 | public void onTabReSelected(@IdRes int tabId) { 82 | mNavController.clearStack(); 83 | } 84 | }); 85 | 86 | } 87 | 88 | @Override 89 | public void onBackPressed() { 90 | if (!mNavController.popFragment()) { 91 | super.onBackPressed(); 92 | } 93 | } 94 | 95 | @Override 96 | protected void onSaveInstanceState(Bundle outState) { 97 | super.onSaveInstanceState(outState); 98 | if (mNavController != null) { 99 | mNavController.onSaveInstanceState(outState); 100 | } 101 | } 102 | 103 | @Override 104 | public void pushFragment(Fragment fragment) { 105 | if (mNavController != null) { 106 | mNavController.pushFragment(fragment); 107 | } 108 | } 109 | 110 | @Override 111 | public void onTabTransaction(Fragment fragment, int index) { 112 | // If we have a backstack, show the back button 113 | if (getSupportActionBar() != null && mNavController != null) { 114 | getSupportActionBar().setDisplayHomeAsUpEnabled(!mNavController.isRootFragment()); 115 | } 116 | } 117 | 118 | 119 | @Override 120 | public void onFragmentTransaction(Fragment fragment, FragNavController.TransactionType transactionType) { 121 | //do fragmentty stuff. Maybe change title, I'm not going to tell you how to live your life 122 | // If we have a backstack, show the back button 123 | if (getSupportActionBar() != null && mNavController != null) { 124 | getSupportActionBar().setDisplayHomeAsUpEnabled(!mNavController.isRootFragment()); 125 | } 126 | } 127 | 128 | @Override 129 | public Fragment getRootFragment(int index) { 130 | switch (index) { 131 | case INDEX_RECENTS: 132 | return RecentsFragment.newInstance(0); 133 | case INDEX_FAVORITES: 134 | return FavoritesFragment.newInstance(0); 135 | case INDEX_NEARBY: 136 | return NearbyFragment.newInstance(0); 137 | case INDEX_FRIENDS: 138 | return FriendsFragment.newInstance(0); 139 | case INDEX_FOOD: 140 | return FoodFragment.newInstance(0); 141 | } 142 | throw new IllegalStateException("Need to send an index that we know"); 143 | } 144 | 145 | @Override 146 | public boolean onOptionsItemSelected(MenuItem item) { 147 | switch (item.getItemId()) { 148 | case android.R.id.home: 149 | mNavController.popFragment(); 150 | break; 151 | } 152 | return true; 153 | } 154 | } 155 | 156 | 157 | 158 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/activities/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.activities; 2 | 3 | import android.content.Intent; 4 | import android.os.Bundle; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.view.View; 7 | import android.widget.Button; 8 | 9 | import com.ncapdevi.sample.R; 10 | 11 | public class MainActivity extends AppCompatActivity { 12 | 13 | 14 | @Override 15 | protected void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | setContentView(com.ncapdevi.sample.R.layout.activity_main); 18 | 19 | 20 | Button btnBottomTabs = (Button) findViewById(R.id.btnBottomTabs); 21 | if (btnBottomTabs != null) { 22 | btnBottomTabs.setOnClickListener(new View.OnClickListener() { 23 | @Override 24 | public void onClick(View v) { 25 | 26 | startActivity(new Intent(MainActivity.this, BottomTabsActivity.class)); 27 | } 28 | }); 29 | } 30 | 31 | Button btnNavDrawer = (Button) findViewById(R.id.btnNavDrawer); 32 | if (btnNavDrawer != null) { 33 | btnNavDrawer.setOnClickListener(new View.OnClickListener() { 34 | @Override 35 | public void onClick(View v) { 36 | startActivity(new Intent(MainActivity.this, NavDrawerActivity.class)); 37 | } 38 | }); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/activities/NavDrawerActivity.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.NavigationView; 5 | import android.support.v4.app.Fragment; 6 | import android.support.v4.view.GravityCompat; 7 | import android.support.v4.widget.DrawerLayout; 8 | import android.support.v7.app.ActionBarDrawerToggle; 9 | import android.support.v7.app.AppCompatActivity; 10 | import android.support.v7.widget.Toolbar; 11 | import android.view.MenuItem; 12 | 13 | import com.ncapdevi.fragnav.FragNavController; 14 | import com.ncapdevi.fragnav.FragNavTransactionOptions; 15 | import com.ncapdevi.sample.R; 16 | import com.ncapdevi.sample.fragments.BaseFragment; 17 | import com.ncapdevi.sample.fragments.FavoritesFragment; 18 | import com.ncapdevi.sample.fragments.FoodFragment; 19 | import com.ncapdevi.sample.fragments.FriendsFragment; 20 | import com.ncapdevi.sample.fragments.NearbyFragment; 21 | import com.ncapdevi.sample.fragments.RecentsFragment; 22 | 23 | import java.util.ArrayList; 24 | import java.util.List; 25 | 26 | public class NavDrawerActivity extends AppCompatActivity 27 | implements NavigationView.OnNavigationItemSelectedListener, BaseFragment.FragmentNavigation { 28 | //Better convention to properly name the indices what they are in your app 29 | private final int INDEX_RECENTS = FragNavController.TAB1; 30 | private final int INDEX_FAVORITES = FragNavController.TAB2; 31 | private final int INDEX_NEARBY = FragNavController.TAB3; 32 | private final int INDEX_FRIENDS = FragNavController.TAB4; 33 | private final int INDEX_FOOD = FragNavController.TAB5; 34 | private final int INDEX_RECENTS2 = FragNavController.TAB6; 35 | private final int INDEX_FAVORITES2 = FragNavController.TAB7; 36 | private final int INDEX_NEARBY2 = FragNavController.TAB8; 37 | private final int INDEX_FRIENDS2 = FragNavController.TAB9; 38 | private final int INDEX_FOOD2 = FragNavController.TAB10; 39 | private final int INDEX_RECENTS3 = FragNavController.TAB11; 40 | private final int INDEX_FAVORITES3 = FragNavController.TAB12; 41 | 42 | private FragNavController mNavController; 43 | 44 | @Override 45 | protected void onCreate(Bundle savedInstanceState) { 46 | super.onCreate(savedInstanceState); 47 | setContentView(R.layout.activity_nav_drawer); 48 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 49 | setSupportActionBar(toolbar); 50 | 51 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 52 | ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( 53 | this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); 54 | drawer.addDrawerListener(toggle); 55 | 56 | toggle.syncState(); 57 | 58 | NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view); 59 | navigationView.setNavigationItemSelectedListener(this); 60 | 61 | List fragments = new ArrayList<>(12); 62 | 63 | fragments.add(RecentsFragment.newInstance(0)); 64 | fragments.add(FavoritesFragment.newInstance(0)); 65 | fragments.add(NearbyFragment.newInstance(0)); 66 | fragments.add(FriendsFragment.newInstance(0)); 67 | fragments.add(FoodFragment.newInstance(0)); 68 | fragments.add(RecentsFragment.newInstance(0)); 69 | fragments.add(FavoritesFragment.newInstance(0)); 70 | fragments.add(NearbyFragment.newInstance(0)); 71 | fragments.add(FriendsFragment.newInstance(0)); 72 | fragments.add(FoodFragment.newInstance(0)); 73 | fragments.add(RecentsFragment.newInstance(0)); 74 | fragments.add(FavoritesFragment.newInstance(0)); 75 | 76 | mNavController = 77 | FragNavController.newBuilder(savedInstanceState, getSupportFragmentManager(), R.id.container) 78 | .rootFragments(fragments) 79 | .defaultTransactionOptions(FragNavTransactionOptions.newBuilder().customAnimations(R.anim.slide_in_from_right, R.anim.slide_out_to_left, R.anim.slide_in_from_left, R.anim.slide_out_to_right).build()) 80 | .build(); 81 | 82 | } 83 | 84 | @Override 85 | public void onBackPressed() { 86 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 87 | if (drawer.isDrawerOpen(GravityCompat.START)) { 88 | drawer.closeDrawer(GravityCompat.START); 89 | } else if (mNavController.getCurrentStack().size() > 1) { 90 | mNavController.popFragment(); 91 | } else { 92 | super.onBackPressed(); 93 | } 94 | } 95 | 96 | @Override 97 | protected void onSaveInstanceState(Bundle outState) { 98 | super.onSaveInstanceState(outState); 99 | mNavController.onSaveInstanceState(outState); 100 | } 101 | 102 | @Override 103 | public boolean onNavigationItemSelected(MenuItem item) { 104 | switch (item.getItemId()) { 105 | case R.id.bb_menu_recents: 106 | mNavController.switchTab(INDEX_RECENTS); 107 | break; 108 | case R.id.bb_menu_favorites: 109 | mNavController.switchTab(INDEX_FAVORITES); 110 | break; 111 | case R.id.bb_menu_nearby: 112 | mNavController.switchTab(INDEX_NEARBY); 113 | break; 114 | case R.id.bb_menu_friends: 115 | mNavController.switchTab(INDEX_FRIENDS); 116 | break; 117 | case R.id.bb_menu_food: 118 | mNavController.switchTab(INDEX_FOOD); 119 | break; 120 | case R.id.bb_menu_recents2: 121 | mNavController.switchTab(INDEX_RECENTS2); 122 | break; 123 | case R.id.bb_menu_favorites2: 124 | mNavController.switchTab(INDEX_FAVORITES2); 125 | break; 126 | case R.id.bb_menu_nearby2: 127 | mNavController.switchTab(INDEX_NEARBY2); 128 | break; 129 | case R.id.bb_menu_friends2: 130 | mNavController.switchTab(INDEX_FRIENDS2); 131 | break; 132 | case R.id.bb_menu_food2: 133 | mNavController.switchTab(INDEX_FOOD2); 134 | break; 135 | case R.id.bb_menu_recents3: 136 | mNavController.switchTab(INDEX_RECENTS3); 137 | break; 138 | case R.id.bb_menu_favorites3: 139 | mNavController.switchTab(INDEX_FAVORITES3); 140 | break; 141 | } 142 | DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout); 143 | drawer.closeDrawer(GravityCompat.START); 144 | return true; 145 | } 146 | 147 | @Override 148 | public void pushFragment(Fragment fragment) { 149 | mNavController.pushFragment(fragment); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/BaseFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.content.Context; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.view.LayoutInflater; 8 | import android.view.View; 9 | import android.view.ViewGroup; 10 | import android.widget.Button; 11 | 12 | import com.ncapdevi.sample.R; 13 | 14 | /** 15 | * Created by niccapdevila on 3/26/16. 16 | */ 17 | public class BaseFragment extends Fragment { 18 | public static final String ARGS_INSTANCE = "com.ncapdevi.sample.argsInstance"; 19 | 20 | Button btn; 21 | FragmentNavigation mFragmentNavigation; 22 | int mInt = 0; 23 | private View cachedView; 24 | 25 | @Override 26 | public void onCreate(@Nullable Bundle savedInstanceState) { 27 | super.onCreate(savedInstanceState); 28 | Bundle args = getArguments(); 29 | if (args != null) { 30 | mInt = args.getInt(ARGS_INSTANCE); 31 | } 32 | } 33 | 34 | 35 | @Override 36 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 37 | if (cachedView == null) { 38 | cachedView = inflater.inflate(R.layout.fragment_main, container, false); 39 | btn = cachedView.findViewById(R.id.button); 40 | } 41 | return cachedView; 42 | } 43 | @Override 44 | public void onAttach(Context context) { 45 | super.onAttach(context); 46 | if (context instanceof FragmentNavigation) { 47 | mFragmentNavigation = (FragmentNavigation) context; 48 | } 49 | } 50 | 51 | public interface FragmentNavigation { 52 | void pushFragment(Fragment fragment); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/FavoritesFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.view.View; 7 | 8 | /** 9 | * Created by niccapdevila on 3/26/16. 10 | */ 11 | public class FavoritesFragment extends BaseFragment { 12 | 13 | public static FavoritesFragment newInstance(int instance) { 14 | Bundle args = new Bundle(); 15 | args.putInt(ARGS_INSTANCE, instance); 16 | FavoritesFragment fragment = new FavoritesFragment(); 17 | fragment.setArguments(args); 18 | return fragment; 19 | } 20 | 21 | @Override 22 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 23 | super.onViewCreated(view, savedInstanceState); 24 | if (btn != null) { 25 | btn.setOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View v) { 28 | if (mFragmentNavigation != null) { 29 | mFragmentNavigation.pushFragment(FavoritesFragment.newInstance(mInt+1)); 30 | } 31 | } 32 | }); 33 | btn.setText(getClass().getSimpleName() + " " + mInt); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/FoodFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.view.View; 7 | 8 | /** 9 | * Created by niccapdevila on 3/26/16. 10 | */ 11 | public class FoodFragment extends BaseFragment { 12 | 13 | public static FoodFragment newInstance(int instance) { 14 | Bundle args = new Bundle(); 15 | args.putInt(ARGS_INSTANCE, instance); 16 | FoodFragment fragment = new FoodFragment(); 17 | fragment.setArguments(args); 18 | return fragment; 19 | } 20 | 21 | @Override 22 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 23 | super.onViewCreated(view, savedInstanceState); 24 | btn.setOnClickListener(new View.OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | if (mFragmentNavigation != null) { 28 | mFragmentNavigation.pushFragment(FoodFragment.newInstance(mInt+1)); 29 | } 30 | } 31 | }); 32 | btn.setText(getClass().getSimpleName() + " " + mInt); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/FriendsFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.view.View; 7 | 8 | /** 9 | * Created by niccapdevila on 3/26/16. 10 | */ 11 | public class FriendsFragment extends BaseFragment { 12 | 13 | public static FriendsFragment newInstance(int instance) { 14 | Bundle args = new Bundle(); 15 | args.putInt(ARGS_INSTANCE, instance); 16 | FriendsFragment fragment = new FriendsFragment(); 17 | fragment.setArguments(args); 18 | return fragment; 19 | } 20 | 21 | 22 | @Override 23 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 24 | super.onViewCreated(view, savedInstanceState); 25 | btn.setOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View v) { 28 | if (mFragmentNavigation != null) { 29 | mFragmentNavigation.pushFragment(FriendsFragment.newInstance(mInt + 1)); 30 | } 31 | } 32 | }); 33 | btn.setText(getClass().getSimpleName() + " " + mInt); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/NearbyFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.view.View; 7 | 8 | /** 9 | * Created by niccapdevila on 3/26/16. 10 | */ 11 | public class NearbyFragment extends BaseFragment { 12 | 13 | public static NearbyFragment newInstance(int instance) { 14 | Bundle args = new Bundle(); 15 | args.putInt(ARGS_INSTANCE, instance); 16 | NearbyFragment fragment = new NearbyFragment(); 17 | fragment.setArguments(args); 18 | return fragment; 19 | } 20 | 21 | @Override 22 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 23 | super.onViewCreated(view, savedInstanceState); 24 | btn.setOnClickListener(new View.OnClickListener() { 25 | @Override 26 | public void onClick(View v) { 27 | if (mFragmentNavigation != null) { 28 | mFragmentNavigation.pushFragment(NearbyFragment.newInstance(mInt+1)); 29 | } 30 | } 31 | }); 32 | btn.setText(getClass().getSimpleName() + " " + mInt); 33 | } 34 | 35 | @Override 36 | public void onViewStateRestored(@Nullable Bundle savedInstanceState) { 37 | super.onViewStateRestored(savedInstanceState); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /app/src/main/java/com/ncapdevi/sample/fragments/RecentsFragment.java: -------------------------------------------------------------------------------- 1 | package com.ncapdevi.sample.fragments; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.NonNull; 5 | import android.support.annotation.Nullable; 6 | import android.view.View; 7 | 8 | /** 9 | * Created by niccapdevila on 3/26/16. 10 | */ 11 | public class RecentsFragment extends BaseFragment { 12 | 13 | public static RecentsFragment newInstance(int instance) { 14 | Bundle args = new Bundle(); 15 | args.putInt(ARGS_INSTANCE, instance); 16 | RecentsFragment fragment = new RecentsFragment(); 17 | fragment.setArguments(args); 18 | return fragment; 19 | } 20 | 21 | 22 | @Override 23 | public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { 24 | super.onViewCreated(view, savedInstanceState); 25 | btn.setOnClickListener(new View.OnClickListener() { 26 | @Override 27 | public void onClick(View v) { 28 | if (mFragmentNavigation != null) { 29 | mFragmentNavigation.pushFragment(RecentsFragment.newInstance(mInt + 1)); 30 | } 31 | } 32 | }); 33 | btn.setText(getClass().getSimpleName() + " " + mInt); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_from_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_from_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-hdpi/ic_favorites.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-hdpi/ic_friends.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_nearby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-hdpi/ic_nearby.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-hdpi/ic_recents.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_restaurants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-hdpi/ic_restaurants.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-mdpi/ic_favorites.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-mdpi/ic_friends.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_nearby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-mdpi/ic_nearby.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-mdpi/ic_recents.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_restaurants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-mdpi/ic_restaurants.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xhdpi/ic_favorites.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xhdpi/ic_friends.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_nearby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xhdpi/ic_nearby.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xhdpi/ic_recents.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_restaurants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xhdpi/ic_restaurants.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxhdpi/ic_favorites.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxhdpi/ic_friends.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_nearby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxhdpi/ic_nearby.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxhdpi/ic_recents.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_restaurants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxhdpi/ic_restaurants.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxxhdpi/ic_favorites.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_friends.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxxhdpi/ic_friends.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_nearby.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxxhdpi/ic_nearby.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_recents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxxhdpi/ic_recents.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_restaurants.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/prashant31191/FragNav/87def8b102e9c61059cf773c4d2db2fef8d03263/app/src/main/res/drawable-xxxhdpi/ic_restaurants.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_bottom_tabs.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 14 | 15 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 |