├── README.md ├── TabController ├── .gitignore ├── .idea │ ├── compiler.xml │ ├── copyright │ │ └── profiles_settings.xml │ ├── encodings.xml │ ├── gradle.xml │ ├── inspectionProfiles │ │ ├── Project_Default.xml │ │ └── profiles_settings.xml │ ├── markdown-navigator.xml │ ├── markdown-navigator │ │ └── profiles_settings.xml │ ├── misc.xml │ ├── modules.xml │ ├── runConfigurations.xml │ └── vcs.xml ├── build.gradle ├── gradle.properties ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── sample │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ │ ├── androidTest │ │ └── java │ │ │ └── com │ │ │ └── appolica │ │ │ └── sample │ │ │ └── ExampleInstrumentedTest.java │ │ ├── main │ │ ├── AndroidManifest.xml │ │ ├── java │ │ │ └── com │ │ │ │ └── appolica │ │ │ │ └── sample │ │ │ │ ├── TabClickListener.java │ │ │ │ ├── Tabs.java │ │ │ │ ├── activity │ │ │ │ ├── ActivitiesAdapter.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── TabControllerActivity.java │ │ │ │ └── TabControllerFragmentActivity.java │ │ │ │ └── tabs │ │ │ │ ├── BottomBarListener.java │ │ │ │ ├── FlatFragment.java │ │ │ │ ├── NestedFragment.java │ │ │ │ ├── pager │ │ │ │ ├── PagerAdapter.java │ │ │ │ └── ViewPagerFragment.java │ │ │ │ └── stack │ │ │ │ ├── StackFragment.java │ │ │ │ └── StackFragmentClickListener.java │ │ └── res │ │ │ ├── drawable-hdpi │ │ │ ├── ic_tab_flat.png │ │ │ ├── ic_tab_pager.png │ │ │ └── ic_tab_stack.png │ │ │ ├── drawable-mdpi │ │ │ ├── ic_tab_flat.png │ │ │ ├── ic_tab_pager.png │ │ │ └── ic_tab_stack.png │ │ │ ├── drawable-xhdpi │ │ │ ├── ic_tab_flat.png │ │ │ ├── ic_tab_pager.png │ │ │ └── ic_tab_stack.png │ │ │ ├── drawable-xxhdpi │ │ │ ├── ic_tab_flat.png │ │ │ ├── ic_tab_pager.png │ │ │ └── ic_tab_stack.png │ │ │ ├── layout │ │ │ ├── activity_fragment_tab_controller.xml │ │ │ ├── activity_main.xml │ │ │ ├── activity_tab_controller.xml │ │ │ ├── fragment_stack_nested.xml │ │ │ ├── fragment_tab.xml │ │ │ ├── fragment_tab_flat.xml │ │ │ ├── fragment_tab_stack.xml │ │ │ ├── fragment_tab_view_pager.xml │ │ │ └── list_item.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-w820dp │ │ │ └── dimens.xml │ │ │ ├── values │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ │ └── xml │ │ │ └── controller_tabs.xml │ │ └── test │ │ └── java │ │ └── com │ │ └── appolica │ │ └── sample │ │ └── ExampleUnitTest.java ├── settings.gradle └── tab-controller │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── appolica │ │ └── tabcontroller │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── appolica │ │ │ └── tabcontroller │ │ │ ├── AttachDetachHandler.java │ │ │ ├── FragmentProvider.java │ │ │ ├── ShowHideFrHandler.java │ │ │ ├── ShowHideHandler.java │ │ │ ├── TabController.java │ │ │ ├── fragment │ │ │ └── TabControllerFragment.java │ │ │ └── listener │ │ │ ├── OnFragmentChangeListener.java │ │ │ └── SimpleFragmentChangeListener.java │ └── res │ │ ├── layout │ │ └── fragment_tab_controller.xml │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── appolica │ └── tabcontroller │ └── ExampleUnitTest.java └── doc_resources └── gif └── sample.gif /README.md: -------------------------------------------------------------------------------- 1 | # Deprecated. Please see https://developer.android.com/guide/navigation 2 | # TabControllerAndroid *by Appolica* 3 | This library provides an easy to use API for switching between fragments that share the same container. Implementing tabs, such as the ones Instagram has at the bottom of the layout, is a much simpler goal to achieve when using **TabController**.
4 | Tabs can be switched by using either show/hide or attach/detach. You can even provide your own implementation of the way tabs are being shown. 5 | 6 | The library is developed and maintained by [Appolica](http://www.appolica.com). 7 | 8 | 9 | 10 | *Note: The sample uses [BottomBar](https://github.com/roughike/BottomBar) in order to give a nice example of using this library. TabController is for managing fragments and does not provide any UI views.* 11 | 12 | ## Download 13 | [ ![Download](https://api.bintray.com/packages/appolica-ltd/maven/TabControllerAndroid/images/download.svg) ](https://bintray.com/appolica-ltd/maven/TabControllerAndroid/_latestVersion) 14 | 15 | ## Gradle 16 | ```gradle 17 | dependencies { 18 | ... 19 | compile 'com.appolica:tab-controller:1.0.3' 20 | } 21 | ``` 22 | 23 | ## Example 24 | 25 | There are two ways of using this library. One is to use `TabControllerFragment`. It encapsulates all the fragments and their container into a single fragment. 26 | 27 | You can use it like any other fragment by adding it to the xml layout: 28 | ```xml 29 | 34 | ``` 35 | 36 | or instantiating it and adding it by yourself: 37 | 38 | ```java 39 | final TabControllerFragment controllerFragment = new TabControllerFragment(); 40 | getSupportFragmentManager() 41 | .beginTransaction() 42 | .add(conainerId, controllerFragment) 43 | .commitNow(); 44 | ``` 45 | 46 | Obtain the TabController instance simply like this: 47 | ```java 48 | final TabController tabController = controllerFragment.getTabController(); 49 | ``` 50 | 51 | --- 52 | The other way is to provide your own fragment container. If you choose to use this, you have to create the TabController instance by yourself: 53 | 54 | ```java 55 | final TabController tabController = new TabController(getSupportFragmentManager(), R.id.container); 56 | ``` 57 | --- 58 | 59 | It doesn't matter whether you use your own container or TabControllerFragment. Once you obtain a TabController instance, everything is the same. 60 | 61 | In order to show your fragment you have to use `TabController::switchTo` method. This method accepts an implementation of `FragmentProvider`. 62 | Suppose you have multiple fragments and the first one is called `HomeFragment`. Then you would need something like `HomeFragmentProvider`, that implements `FragmentProvider`. 63 | 64 | ```java 65 | public class HomeFragment extends Fragment { 66 | public static final String TAG = "HomeFragment"; 67 | 68 | public static HomeFragment getInstance(int tabNum) { 69 | final HomeFragment fragment = new HomeFragment(); 70 | 71 | return tab; 72 | } 73 | 74 | ... 75 | } 76 | ``` 77 | ```java 78 | class HomeFragmentProvider implements FragmentProvider{ 79 | @Override 80 | public String getTag() { 81 | return HomeFragment.TAG; 82 | } 83 | 84 | @Override 85 | public Fragment getInstance() { 86 | return HomeFragment.getInstance(); 87 | } 88 | } 89 | ``` 90 | Create an instance of `HomeFragmentProvider` and pass it to `TabController::switchTo` in order to show your `HomeFragment`. 91 | ```java 92 | final HomeFragmentProvider homeProvider = new HomeFragmentProvider(); 93 | tabController.switchTo(homeProvider); 94 | ``` 95 | The `TabController` will create a new instance (by calling `FragmentProvider::getInstance`) of your fragment if it hasn't been already created. This depends on whether `FragmentManager::findFragmentByTag` returns `null` for the tag, given by `FragmentProvider::getTag`. 96 | 97 | ## API 98 | 99 | #### TabController 100 | 101 | ##### Constructors: 102 | * `TabController(FragmentManager fragmentManager, int containerId)` - Create a new instance of TabController with the default ShowHideHandler. 103 | * `TabController(FragmentManager fragmentManager, int containerId, ShowHideHandler showHideHandler)` - Create a new instance of TabController. 104 | 105 | ##### Public methods: 106 | * `void switchTo(FragmentProvider provider)` - Show the given fragment in the container, provided to the constructor. If `FragmentManager::findFragmentByTag` returns null for the tag, given by the provider, your fragment's instance will be obtained by calling `FragmentProvider::getInstance`. Otherwise it will be reused. If there is already a visible fragment, it will be hidden. How fragments are shown/hidden depends on ShowHideHandler. 107 | * `Fragment getVisibleFragment()` - Iterates through the fragments, returned by FragmentManager::getFragments. Returns the first visible fragment found in the list or null. 108 | * `Fragment getFragment(@NonNull FragmentProvider fragmentProvider)` - Find a fragment by it's `FragmentProvider`. Same as calling fragmentManager.findFragmentByTag(fragmentProvider.getTag()); 109 | * `void save(Bundle savedInstanceState)` - Save the state of the `TabController` in order to be able to restore your last visible fragment when your app restores. 110 | * `void restore(@Nullable Bundle savedInstanceState)` - Restore the state of the `TabController`. This will show the last visible fragment before saving the state. 111 | * `void setChangeListener(OnFragmentChangeListener changeListener)` - Set listener to be notified on one of the `TabController`'s events. 112 | 113 | #### ShowHideHandler 114 | Implementations of this interface determine how your fragments are going to be shown/hidden. It could be by using `FragmentTransaction.show(Fragment)`/`FragmentTransaction.hide(Fragment)` or `FragmentTransaction.attach(Fragment)`/`FragmentTransaction.detach(Fragment)`. 115 | 116 | ##### Public methods: 117 | * `FragmentTransaction show(FragmentTransaction transaction, Fragment fragment)` - Show the given fragment within the given transaction the way you want. 118 | * `FragmentTransaction hide(FragmentTransaction transaction, Fragment fragment)` - Hide the given fragment within the given transaction the way you want. 119 | * `void save(Bundle saveControllerState, Fragment fragment)` - Called when TabController is saving its state. In some cases (like when you show/hide your fragment by using `FragmentTransaction.show/hide`) you may want to save the visibility of your fragment. This is where you should do that. This method is called for each fragment, returned from `FragmentManager.getFragments()`. 120 | * `void restore(@Nullable Bundle savedControllerState, FragmentTransaction transaction, Fragment fragment)` - Called when `TabController` is restoring its state. In some cases (like when you show/hide your fragment by using `FragmentTransaction.show/hide`) in order to restore the visibility of your fragments you should implement this method. Your fragment will become visible or hidden depending on what action you add to the given `FragmentTransaction`. This method is called for each fragment returned from `FragmentManagegetFragments()`. 121 | * `boolean isVisible(Fragment fragment)` - Since Fragment.isVisible() and Fragment.isHidden() work different, `TabController` is using this abstract method, relying that the implementation will work properly. 122 | 123 | #### FragmentProvider 124 | Used by `TabController`. Implementation of this interface should provide a tag and an instance of the fragment that will be shown/hidden by the controller. 125 | 126 | ##### Public methods: 127 | * `String getTag()` - Provide the fragment's tag. 128 | * `Fragment getInstance()` - Provide fragment's instance. 129 | 130 | #### OnFragmentChangeListener 131 | Pass this listener to `TabController.setChangeListener(OnFragmentChangeListener)` to be notified for one of it's events. 132 | 133 | ##### Public methods: 134 | * `void onFragmentShown(FragmentProvider provider, Fragment shownFragment)` - Called when one of your fragments has been shown. 135 | * `void onFragmentAlreadyVisible(FragmentProvider provider, Fragment visibleFragment)` - Called on attempt to show an already visible fragment. 136 | * `void onFragmentCreated(FragmentProvider provider, Fragment createdFragment)` - Called when the fragment you want to show has been created by the TabController. 137 | 138 | #### TabControllerFragment 139 | An encapsulation for the fragments that are managed through the `TabController`. All of these fragments are switched between within this fragment using child fragment manager.
140 | We encourage you to use this fragment in order to restrict the access of the `TabController` to any other fragments, that aren't related to it and vice versa. 141 | 142 | ##### Public methods: 143 | * `TabController getTabController()` - Obtain the `TabController`. Its instance is created in `Fragment.onViewCreated(View, Bundle)`. 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | # License 152 | 153 | Copyright 2017 Appolica Ltd. 154 | 155 | Licensed under the Apache License, Version 2.0 (the "License"); 156 | you may not use this file except in compliance with the License. 157 | You may obtain a copy of the License at 158 | 159 | http://www.apache.org/licenses/LICENSE-2.0 160 | 161 | Unless required by applicable law or agreed to in writing, software 162 | distributed under the License is distributed on an "AS IS" BASIS, 163 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 164 | See the License for the specific language governing permissions and 165 | limitations under the License. 166 | -------------------------------------------------------------------------------- /TabController/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /TabController/.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 | 23 | -------------------------------------------------------------------------------- /TabController/.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /TabController/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /TabController/.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 18 | 19 | -------------------------------------------------------------------------------- /TabController/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | -------------------------------------------------------------------------------- /TabController/.idea/inspectionProfiles/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /TabController/.idea/markdown-navigator.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 33 | 34 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /TabController/.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /TabController/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 24 | 25 | 37 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 64 | 65 | 66 | 67 | 68 | 1.8 69 | 70 | 75 | 76 | 77 | 78 | 79 | 80 | -------------------------------------------------------------------------------- /TabController/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /TabController/.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /TabController/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /TabController/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.3.0' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | jcenter() 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /TabController/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | org.gradle.jvmargs=-Xmx1536m 13 | 14 | # When configured, Gradle will run in incubating parallel mode. 15 | # This option should only be used with decoupled projects. More details, visit 16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 17 | # org.gradle.parallel=true 18 | -------------------------------------------------------------------------------- /TabController/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /TabController/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu Mar 23 15:00:18 EET 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /TabController/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /TabController/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /TabController/sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /TabController/sample/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.2" 6 | 7 | defaultConfig { 8 | applicationId "com.appolica.sample" 9 | minSdkVersion 15 10 | targetSdkVersion 25 11 | versionCode 1 12 | versionName "1.0" 13 | 14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 15 | 16 | } 17 | buildTypes { 18 | release { 19 | minifyEnabled false 20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 21 | } 22 | } 23 | dataBinding { 24 | enabled true 25 | } 26 | } 27 | 28 | dependencies { 29 | compile fileTree(include: ['*.jar'], dir: 'libs') 30 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 31 | exclude group: 'com.android.support', module: 'support-annotations' 32 | }) 33 | testCompile 'junit:junit:4.12' 34 | 35 | compile 'com.android.support:support-fragment:25.3.1' 36 | 37 | compile 'com.android.support:recyclerview-v7:25.3.1' 38 | compile 'com.android.support:cardview-v7:25.3.1' 39 | compile 'com.android.support.constraint:constraint-layout:1.0.2' 40 | 41 | compile project(':tab-controller') 42 | 43 | compile 'com.roughike:bottom-bar:2.2.0' 44 | } 45 | -------------------------------------------------------------------------------- /TabController/sample/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 /home/bogomil/Development/SDK/android-sdk-linux/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 | -------------------------------------------------------------------------------- /TabController/sample/src/androidTest/java/com/appolica/sample/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.appolica.sample", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /TabController/sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/TabClickListener.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample; 2 | 3 | public interface TabClickListener { 4 | void onTab1Click(); 5 | 6 | void onTab2Click(); 7 | 8 | void onTab3Click(); 9 | 10 | void onTab4Click(); 11 | } 12 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/Tabs.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample; 2 | 3 | import android.support.v4.app.Fragment; 4 | 5 | import com.appolica.sample.tabs.FlatFragment; 6 | import com.appolica.sample.tabs.pager.ViewPagerFragment; 7 | import com.appolica.sample.tabs.stack.StackFragment; 8 | import com.appolica.tabcontroller.FragmentProvider; 9 | 10 | public enum Tabs implements FragmentProvider { 11 | TAB_1(StackFragment.class), 12 | TAB_2(ViewPagerFragment.class), 13 | TAB_3(FlatFragment.class) 14 | ; 15 | 16 | private Class fragmentClass; 17 | 18 | Tabs(Class fragmentClass) { 19 | this.fragmentClass = fragmentClass; 20 | } 21 | 22 | @Override 23 | public String getTag() { 24 | return name(); 25 | } 26 | 27 | @Override 28 | public Fragment getInstance() { 29 | try { 30 | return fragmentClass.newInstance(); 31 | } catch (InstantiationException e) { 32 | e.printStackTrace(); 33 | } catch (IllegalAccessException e) { 34 | e.printStackTrace(); 35 | } 36 | 37 | return null; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/activity/ActivitiesAdapter.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.activity; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.databinding.DataBindingUtil; 7 | import android.support.v7.widget.RecyclerView; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.appolica.sample.R; 13 | import com.appolica.sample.databinding.ListItemBinding; 14 | 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | 18 | public class ActivitiesAdapter extends RecyclerView.Adapter { 19 | 20 | private List> data = new ArrayList<>(); 21 | 22 | class ItemViewHolder extends RecyclerView.ViewHolder { 23 | 24 | ListItemBinding binding; 25 | 26 | public ItemViewHolder(ListItemBinding binding) { 27 | super(binding.getRoot()); 28 | this.binding = binding; 29 | } 30 | } 31 | 32 | @Override 33 | public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 34 | final LayoutInflater inflater = LayoutInflater.from(parent.getContext()); 35 | 36 | ListItemBinding binding = DataBindingUtil.inflate(inflater, R.layout.list_item, parent, false); 37 | 38 | return new ItemViewHolder(binding); 39 | } 40 | 41 | @Override 42 | public void onBindViewHolder(ItemViewHolder holder, final int position) { 43 | holder.binding.listItemTextView.setText(data.get(position).getSimpleName()); 44 | 45 | holder.itemView.setOnClickListener(new View.OnClickListener() { 46 | @Override 47 | public void onClick(View v) { 48 | final Context context = v.getContext(); 49 | 50 | context.startActivity(new Intent(context, data.get(position))); 51 | } 52 | }); 53 | } 54 | 55 | @Override 56 | public int getItemCount() { 57 | return data.size(); 58 | } 59 | 60 | public void addData(List> data) { 61 | this.data.addAll(data); 62 | notifyDataSetChanged(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/activity/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.activity; 2 | 3 | import android.app.Activity; 4 | import android.databinding.DataBindingUtil; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.os.Bundle; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | 9 | import com.appolica.sample.R; 10 | import com.appolica.sample.databinding.ActivityMainBinding; 11 | 12 | import java.util.ArrayList; 13 | 14 | public class MainActivity extends AppCompatActivity { 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | ActivityMainBinding binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 20 | 21 | binding.recyclerViewActivities.setLayoutManager(new LinearLayoutManager(this)); 22 | binding.recyclerViewActivities.setHasFixedSize(true); 23 | 24 | ActivitiesAdapter adapter = new ActivitiesAdapter(); 25 | binding.recyclerViewActivities.setAdapter(adapter); 26 | 27 | final ArrayList> activityClasses = new ArrayList<>(); 28 | activityClasses.add(TabControllerActivity.class); 29 | activityClasses.add(TabControllerFragmentActivity.class); 30 | 31 | adapter.addData(activityClasses); 32 | 33 | 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/activity/TabControllerActivity.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.activity; 2 | 3 | import android.databinding.DataBindingUtil; 4 | import android.os.Bundle; 5 | import android.os.PersistableBundle; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.util.Log; 9 | 10 | import com.appolica.sample.R; 11 | import com.appolica.sample.TabClickListener; 12 | import com.appolica.sample.Tabs; 13 | import com.appolica.sample.databinding.ActivityTabControllerBinding; 14 | import com.appolica.sample.tabs.BottomBarListener; 15 | import com.appolica.tabcontroller.AttachDetachHandler; 16 | import com.appolica.tabcontroller.FragmentProvider; 17 | import com.appolica.tabcontroller.ShowHideFrHandler; 18 | import com.appolica.tabcontroller.TabController; 19 | import com.appolica.tabcontroller.listener.OnFragmentChangeListener; 20 | 21 | public class TabControllerActivity 22 | extends AppCompatActivity 23 | implements OnFragmentChangeListener, BottomBarListener.BottomBarTabListener { 24 | 25 | private static final String BUNDLE_BOTTOM_BAR = TabControllerFragmentActivity.class.getName() + ":BottomBar"; 26 | private static final String TAG = "TabControllerActivity"; 27 | 28 | private TabController tabController; 29 | private ActivityTabControllerBinding binding; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | binding = DataBindingUtil.setContentView(this, R.layout.activity_tab_controller); 35 | 36 | tabController = new TabController(getSupportFragmentManager(), R.id.container, new AttachDetachHandler()); 37 | tabController.setChangeListener(this); 38 | 39 | if (savedInstanceState != null) { 40 | binding.bottomBar.onRestoreInstanceState(savedInstanceState.getParcelable(BUNDLE_BOTTOM_BAR)); 41 | tabController.restore(savedInstanceState); 42 | } 43 | 44 | binding.bottomBar.setOnTabSelectListener(new BottomBarListener(this), true); 45 | } 46 | 47 | @Override 48 | public void onFragmentShown(FragmentProvider provider, Fragment shownFragment) { 49 | Log.d(TAG, "onFragmentShown: " + provider.getTag()); 50 | } 51 | 52 | @Override 53 | public void onFragmentAlreadyVisible(FragmentProvider provider, Fragment visibleFragment) { 54 | Log.d(TAG, "onFragmentAlreadyVisible: " + provider.getTag()); 55 | } 56 | 57 | @Override 58 | public void onFragmentCreated(FragmentProvider provider, Fragment createdFragment) { 59 | Log.d(TAG, "onFragmentCreated: " + provider.getTag()); 60 | } 61 | 62 | @Override 63 | protected void onSaveInstanceState(Bundle outState) { 64 | super.onSaveInstanceState(outState); 65 | tabController.save(outState); 66 | } 67 | 68 | @Override 69 | public void onStackSelected() { 70 | tabController.switchTo(Tabs.TAB_1); 71 | } 72 | 73 | @Override 74 | public void onViewPagerSelected() { 75 | tabController.switchTo(Tabs.TAB_2); 76 | } 77 | 78 | @Override 79 | public void onFlatSelected() { 80 | tabController.switchTo(Tabs.TAB_3); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/activity/TabControllerFragmentActivity.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.activity; 2 | 3 | import android.databinding.DataBindingUtil; 4 | import android.os.Bundle; 5 | import android.os.Parcelable; 6 | import android.os.PersistableBundle; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v7.app.AppCompatActivity; 9 | import android.util.Log; 10 | 11 | import com.appolica.sample.R; 12 | import com.appolica.sample.Tabs; 13 | import com.appolica.sample.databinding.ActivityTabFragmentBinding; 14 | import com.appolica.sample.tabs.BottomBarListener; 15 | import com.appolica.tabcontroller.FragmentProvider; 16 | import com.appolica.tabcontroller.TabController; 17 | import com.appolica.tabcontroller.fragment.TabControllerFragment; 18 | import com.appolica.tabcontroller.listener.OnFragmentChangeListener; 19 | 20 | public class TabControllerFragmentActivity 21 | extends AppCompatActivity 22 | implements OnFragmentChangeListener, 23 | BottomBarListener.BottomBarTabListener { 24 | 25 | private static final String TAG = "TabControllerActivity"; 26 | private static final String BUNDLE_BOTTOM_BAR = TabControllerFragmentActivity.class.getName() + ":BottomBar"; 27 | 28 | private TabController tabController; 29 | private ActivityTabFragmentBinding binding; 30 | 31 | @Override 32 | protected void onCreate(Bundle savedInstanceState) { 33 | super.onCreate(savedInstanceState); 34 | binding = DataBindingUtil.setContentView(this, R.layout.activity_fragment_tab_controller); 35 | 36 | final TabControllerFragment tabControllerFragment = 37 | (TabControllerFragment) getSupportFragmentManager().findFragmentById(R.id.fragment); 38 | 39 | tabController = tabControllerFragment.getTabController(); 40 | tabController.setChangeListener(this); 41 | 42 | if (savedInstanceState != null) { 43 | binding.bottomBar.onRestoreInstanceState(savedInstanceState.getParcelable(BUNDLE_BOTTOM_BAR)); 44 | } 45 | 46 | binding.bottomBar.setOnTabSelectListener(new BottomBarListener(this), true); 47 | } 48 | 49 | @Override 50 | public void onFragmentShown(FragmentProvider fragmentType, Fragment shownFragment) { 51 | Log.d(TAG, "onFragmentShown: " + fragmentType.getTag()); 52 | } 53 | 54 | @Override 55 | public void onFragmentAlreadyVisible(FragmentProvider fragmentType, Fragment visibleFragment) { 56 | Log.d(TAG, "onFragmentAlreadyVisible: " + fragmentType.getTag()); 57 | } 58 | 59 | @Override 60 | public void onFragmentCreated(FragmentProvider fragmentType, Fragment addedFragment) { 61 | Log.d(TAG, "onFragmentCreated: " + fragmentType.getTag()); 62 | } 63 | 64 | @Override 65 | public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) { 66 | super.onSaveInstanceState(outState, outPersistentState); 67 | final Parcelable bottomBarParcelable = binding.bottomBar.onSaveInstanceState(); 68 | 69 | outState.putParcelable(BUNDLE_BOTTOM_BAR, bottomBarParcelable); 70 | } 71 | 72 | @Override 73 | public void onStackSelected() { 74 | tabController.switchTo(Tabs.TAB_1); 75 | } 76 | 77 | @Override 78 | public void onViewPagerSelected() { 79 | tabController.switchTo(Tabs.TAB_2); 80 | } 81 | 82 | @Override 83 | public void onFlatSelected() { 84 | tabController.switchTo(Tabs.TAB_3); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/BottomBarListener.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs; 2 | 3 | import android.support.annotation.IdRes; 4 | 5 | import com.appolica.sample.R; 6 | import com.roughike.bottombar.OnTabSelectListener; 7 | 8 | public class BottomBarListener implements OnTabSelectListener { 9 | 10 | private BottomBarTabListener listener; 11 | 12 | public BottomBarListener(BottomBarTabListener listener) { 13 | this.listener = listener; 14 | } 15 | 16 | @Override 17 | public void onTabSelected(@IdRes int tabId) { 18 | switch (tabId) { 19 | case R.id.tab_stack: 20 | listener.onStackSelected(); 21 | break; 22 | case R.id.tab_pager: 23 | listener.onViewPagerSelected(); 24 | break; 25 | case R.id.tab_flat: 26 | listener.onFlatSelected(); 27 | break; 28 | } 29 | } 30 | 31 | public interface BottomBarTabListener { 32 | void onStackSelected(); 33 | void onViewPagerSelected(); 34 | void onFlatSelected(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/FlatFragment.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs; 2 | 3 | import android.databinding.DataBindingUtil; 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 | 11 | import com.appolica.sample.R; 12 | import com.appolica.sample.databinding.FragmentTabFlatBinding; 13 | 14 | 15 | public class FlatFragment extends Fragment { 16 | 17 | private FragmentTabFlatBinding binding; 18 | 19 | @Nullable 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 22 | binding = DataBindingUtil.inflate(inflater, R.layout.fragment_tab_flat, container, false); 23 | return binding.getRoot(); 24 | } 25 | 26 | @Override 27 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 28 | super.onViewCreated(view, savedInstanceState); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/NestedFragment.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs; 2 | 3 | import android.databinding.DataBindingUtil; 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 | 11 | import com.appolica.sample.R; 12 | import com.appolica.sample.databinding.FragmentStackNestedBinding; 13 | 14 | 15 | public class NestedFragment extends Fragment { 16 | 17 | public static final String KEY_FRAGMENT_INDEX = NestedFragment.class.getName() + ":KEY_FRAGMENT_INDEX"; 18 | public static final String TAG = NestedFragment.class.getSimpleName(); 19 | private FragmentStackNestedBinding binding; 20 | 21 | public static NestedFragment getInstance(int index) { 22 | final Bundle args = new Bundle(); 23 | final NestedFragment fragment = new NestedFragment(); 24 | 25 | args.putInt(KEY_FRAGMENT_INDEX, index); 26 | fragment.setArguments(args); 27 | 28 | return fragment; 29 | } 30 | 31 | @Nullable 32 | @Override 33 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 34 | binding = DataBindingUtil.inflate(inflater, R.layout.fragment_stack_nested, container, false); 35 | return binding.getRoot(); 36 | } 37 | 38 | @Override 39 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 40 | super.onViewCreated(view, savedInstanceState); 41 | 42 | final int fragmentIndex = getArguments().getInt(KEY_FRAGMENT_INDEX); 43 | binding.setText(getString(R.string.stack_fragment_index, fragmentIndex)); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/pager/PagerAdapter.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs.pager; 2 | 3 | import android.support.v4.app.Fragment; 4 | import android.support.v4.app.FragmentManager; 5 | import android.support.v4.app.FragmentPagerAdapter; 6 | 7 | import com.appolica.sample.Tabs; 8 | import com.appolica.sample.tabs.NestedFragment; 9 | 10 | 11 | public class PagerAdapter extends FragmentPagerAdapter { 12 | public PagerAdapter(FragmentManager fm) { 13 | super(fm); 14 | } 15 | 16 | @Override 17 | public CharSequence getPageTitle(int position) { 18 | return Tabs.values()[position].name(); 19 | } 20 | 21 | @Override 22 | public Fragment getItem(int position) { 23 | final NestedFragment fragment = NestedFragment.getInstance(position); 24 | 25 | return fragment; 26 | } 27 | 28 | @Override 29 | public int getCount() { 30 | return PagerTabs.values().length; 31 | } 32 | 33 | public static enum PagerTabs { 34 | TAB_1(1), 35 | TAB_2(2); 36 | 37 | private int index; 38 | 39 | PagerTabs(int index) { 40 | this.index = index; 41 | } 42 | 43 | public int getIndex() { 44 | return index; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/pager/ViewPagerFragment.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs.pager; 2 | 3 | import android.databinding.DataBindingUtil; 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 | 11 | import com.appolica.sample.R; 12 | import com.appolica.sample.databinding.FragmentTabViewPagerBinding; 13 | 14 | 15 | public class ViewPagerFragment extends Fragment { 16 | 17 | private FragmentTabViewPagerBinding binding; 18 | 19 | @Nullable 20 | @Override 21 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 22 | 23 | binding = DataBindingUtil.inflate(inflater, R.layout.fragment_tab_view_pager, container, false); 24 | 25 | return binding.getRoot(); 26 | } 27 | 28 | @Override 29 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 30 | super.onViewCreated(view, savedInstanceState); 31 | 32 | final PagerAdapter pagerAdapter = new PagerAdapter(getChildFragmentManager()); 33 | 34 | binding.tabLayout.setupWithViewPager(binding.viewPager); 35 | 36 | binding.viewPager.setAdapter(pagerAdapter); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/stack/StackFragment.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs.stack; 2 | 3 | import android.databinding.DataBindingUtil; 4 | import android.os.Bundle; 5 | import android.support.annotation.Nullable; 6 | import android.support.v4.app.Fragment; 7 | import android.support.v4.app.FragmentManager; 8 | import android.view.LayoutInflater; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.appolica.sample.R; 13 | import com.appolica.sample.databinding.StackFragmentsBinding; 14 | import com.appolica.sample.tabs.NestedFragment; 15 | 16 | public class StackFragment extends Fragment implements StackFragmentClickListener { 17 | 18 | private StackFragmentsBinding binding; 19 | 20 | @Nullable 21 | @Override 22 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 23 | 24 | binding = 25 | DataBindingUtil.inflate(inflater, R.layout.fragment_tab_stack, container, false); 26 | 27 | return binding.getRoot(); 28 | } 29 | 30 | @Override 31 | public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 32 | super.onViewCreated(view, savedInstanceState); 33 | 34 | binding.setClickListener(this); 35 | } 36 | 37 | @Override 38 | public void onPopClick() { 39 | popFragment(); 40 | } 41 | 42 | @Override 43 | public void onPushClick() { 44 | final FragmentManager childFragmentManager = getChildFragmentManager(); 45 | final int stackCount = childFragmentManager.getBackStackEntryCount(); 46 | final NestedFragment fragment = NestedFragment.getInstance(stackCount); 47 | 48 | childFragmentManager.beginTransaction() 49 | .replace(R.id.container, fragment) 50 | .addToBackStack(String.format("%s:%d", NestedFragment.TAG, stackCount)) 51 | .commit(); 52 | 53 | childFragmentManager.executePendingTransactions(); 54 | } 55 | 56 | private void popFragment() { 57 | getChildFragmentManager().popBackStack(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /TabController/sample/src/main/java/com/appolica/sample/tabs/stack/StackFragmentClickListener.java: -------------------------------------------------------------------------------- 1 | package com.appolica.sample.tabs.stack; 2 | 3 | public interface StackFragmentClickListener { 4 | void onPopClick(); 5 | void onPushClick(); 6 | } 7 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-hdpi/ic_tab_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-hdpi/ic_tab_flat.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-hdpi/ic_tab_pager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-hdpi/ic_tab_pager.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-hdpi/ic_tab_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-hdpi/ic_tab_stack.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-mdpi/ic_tab_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-mdpi/ic_tab_flat.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-mdpi/ic_tab_pager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-mdpi/ic_tab_pager.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-mdpi/ic_tab_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-mdpi/ic_tab_stack.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xhdpi/ic_tab_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xhdpi/ic_tab_flat.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xhdpi/ic_tab_pager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xhdpi/ic_tab_pager.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xhdpi/ic_tab_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xhdpi/ic_tab_stack.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_flat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_flat.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_pager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_pager.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Appolica/TabControllerAndroid/8bea029dd5a6c4e35caabd96a038b7d7bec33572/TabController/sample/src/main/res/drawable-xxhdpi/ic_tab_stack.png -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/activity_fragment_tab_controller.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 27 | 28 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/activity_tab_controller.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 25 | 26 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/fragment_stack_nested.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 20 | 21 | 35 | 36 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/fragment_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 17 | 18 | 34 | 35 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/fragment_tab_flat.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 25 | 26 | -------------------------------------------------------------------------------- /TabController/sample/src/main/res/layout/fragment_tab_stack.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 10 | 13 | 14 | 15 | 16 | 20 | 21 | 31 | 32 | 33 | 34 |