diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/BaseActivity.java b/src/main/java/ru/touchin/roboswag/components/navigation/BaseActivity.java index 682968d..8123383 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/BaseActivity.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/BaseActivity.java @@ -6,12 +6,16 @@ import android.support.v7.app.AppCompatActivity; import android.view.View; import android.view.inputmethod.InputMethodManager; +import java.util.ArrayList; + /** * Created by Gavriil Sitnikov on 08/03/2016. * TODO: fill description */ public class BaseActivity extends AppCompatActivity { + private final ArrayList onBackPressedListeners = new ArrayList<>(); + /** * Hides device keyboard that is showing over {@link Activity}. * Do not use it if keyboard is over {@link android.app.Dialog} - it won't work as they have different {@link Activity#getWindow()}. @@ -28,6 +32,7 @@ public class BaseActivity extends AppCompatActivity { /** * Shows device keyboard over {@link Activity} and focuses {@link View}. * Do not use it if keyboard is over {@link android.app.Dialog} - it won't work as they have different {@link Activity#getWindow()}. + * * @param view View to get focus for input from keyboard. */ public void showSoftInput(@NonNull final View view) { @@ -36,4 +41,33 @@ public class BaseActivity extends AppCompatActivity { inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); } + public void addOnBackPressedListener(@NonNull final OnBackPressedListener onBackPressedListener) { + onBackPressedListeners.add(onBackPressedListener); + } + + public void removeOnBackPressedListener(@NonNull final OnBackPressedListener onBackPressedListener) { + onBackPressedListeners.remove(onBackPressedListener); + } + + @Override + public void onBackPressed() { + for (final OnBackPressedListener onBackPressedListener : onBackPressedListeners) { + if (onBackPressedListener.onBackPressed()) { + return; + } + } + + if (getSupportFragmentManager().getBackStackEntryCount() <= 1) { + supportFinishAfterTransition(); + } else { + getSupportFragmentManager().popBackStackImmediate(); + } + } + + public interface OnBackPressedListener { + + boolean onBackPressed(); + + } + } diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.java b/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.java index 101279d..8269495 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/FragmentNavigation.java @@ -64,6 +64,22 @@ public class FragmentNavigation { return context; } + /** + * Returns if last fragment in stack is top (added by setFragment) like fragment from sidebar menu. + * + * @return True if last fragment on stack has TOP_FRAGMENT_TAG_MARK. + */ + public boolean isCurrentFragmentTop() { + if (fragmentManager.getBackStackEntryCount() == 0) { + return true; + } + + final String topFragmentTag = fragmentManager + .getBackStackEntryAt(fragmentManager.getBackStackEntryCount() - 1) + .getName(); + return topFragmentTag != null && topFragmentTag.contains(TOP_FRAGMENT_TAG_MARK); + } + @SuppressLint("CommitTransaction") protected void addToStack(@NonNull final Class fragmentClass, @Nullable final Fragment targetFragment, diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/SidebarController.java b/src/main/java/ru/touchin/roboswag/components/navigation/SidebarController.java new file mode 100644 index 0000000..8860fed --- /dev/null +++ b/src/main/java/ru/touchin/roboswag/components/navigation/SidebarController.java @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov) + * + * This file is part of RoboSwag library. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package ru.touchin.roboswag.components.navigation; + +import android.content.res.Configuration; +import android.support.annotation.NonNull; +import android.support.v4.app.FragmentManager; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.view.MenuItem; +import android.view.View; + +/** + * Created by Gavriil Sitnikov on 11/03/16. + * TODO: descriptions + */ +public class SidebarController implements FragmentManager.OnBackStackChangedListener, BaseActivity.OnBackPressedListener { + + private final DrawerLayout drawerLayout; + private final ActionBarDrawerToggle drawerToggle; + private final View sidebar; + + private boolean isHamburgerShowed; + private boolean isSidebarDisabled; + + public SidebarController(@NonNull final BaseActivity activity, + @NonNull final DrawerLayout drawerLayout, + @NonNull final View sidebar) { + this.drawerLayout = drawerLayout; + this.sidebar = sidebar; + drawerToggle = new ActionBarDrawerToggle(activity, drawerLayout, 0, 0) { + + @Override + public void onDrawerClosed(final View view) { + activity.supportInvalidateOptionsMenu(); + } + + @Override + public void onDrawerOpened(final View drawerView) { + activity.hideSoftInput(); + activity.supportInvalidateOptionsMenu(); + } + + }; + drawerLayout.addDrawerListener(drawerToggle); + activity.getSupportFragmentManager().addOnBackStackChangedListener(this); + activity.addOnBackPressedListener(this); + } + + public void onConfigurationChanged(@NonNull final Configuration newConfig) { + drawerToggle.onConfigurationChanged(newConfig); + } + + public boolean onOptionsItemSelected(@NonNull final MenuItem item) { + return drawerToggle.onOptionsItemSelected(item); + } + + private void update() { + final boolean showHamburger = !isHamburgerShowed && !isSidebarDisabled; + drawerToggle.setDrawerIndicatorEnabled(!showHamburger); + drawerToggle.setDrawerIndicatorEnabled(showHamburger); + drawerToggle.syncState(); + drawerLayout.setDrawerLockMode(isSidebarDisabled ? DrawerLayout.LOCK_MODE_LOCKED_CLOSED : DrawerLayout.LOCK_MODE_UNLOCKED); + } + + public void disableSidebar() { + isSidebarDisabled = true; + closeSidebar(); + update(); + } + + public void enableSidebar() { + isSidebarDisabled = false; + update(); + } + + public void hideHamburger() { + isHamburgerShowed = true; + update(); + } + + public void showHamburger() { + isHamburgerShowed = false; + update(); + } + + public void closeSidebar() { + if (drawerLayout.isDrawerOpen(sidebar)) { + drawerLayout.closeDrawer(sidebar); + } + } + + @Override + public void onBackStackChanged() { + closeSidebar(); + } + + @Override + public boolean onBackPressed() { + if (drawerLayout.isDrawerOpen(sidebar)) { + closeSidebar(); + return true; + } + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/SimpleViewControllerFragment.java b/src/main/java/ru/touchin/roboswag/components/navigation/SimpleViewControllerFragment.java index a2d51e5..2752a65 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/SimpleViewControllerFragment.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/SimpleViewControllerFragment.java @@ -35,7 +35,7 @@ public class SimpleViewControllerFragment>> getViewControllerClass() { return viewControllerClass; } diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/ViewController.java b/src/main/java/ru/touchin/roboswag/components/navigation/ViewController.java index 011cb0c..7d65d38 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/ViewController.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/ViewController.java @@ -23,9 +23,7 @@ import android.os.Bundle; import android.os.Parcelable; import android.support.annotation.NonNull; import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; import android.util.SparseArray; -import android.view.View; import android.view.ViewGroup; import rx.Observable; @@ -61,8 +59,8 @@ public class ViewController savedState != null) .first() + .filter(savedState -> savedState != null) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::onRestoreSavedState); } @@ -117,7 +115,7 @@ public class ViewController>> getViewControllerClass(); @SuppressWarnings("unchecked") diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/ViewControllerNavigation.java b/src/main/java/ru/touchin/roboswag/components/navigation/ViewControllerNavigation.java index cb5e314..a6ca5fa 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/ViewControllerNavigation.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/ViewControllerNavigation.java @@ -110,6 +110,12 @@ public class ViewControllerNavigation extends FragmentNavigation { addViewControllerToStack(viewControllerClass, targetFragment, state, viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, transactionSetup); } + public void setViewControllerAsTop(@NonNull final Class, + ? extends SimpleViewControllerFragment>>> viewControllerClass) { + addViewControllerToStack(viewControllerClass, null, null, viewControllerClass.getName() + ' ' + TOP_FRAGMENT_TAG_MARK, null); + } + public void setViewControllerAsTop(@NonNull final Class, ? extends SimpleViewControllerFragment>>> viewControllerClass, @@ -125,6 +131,12 @@ public class ViewControllerNavigation extends FragmentNavigation { addViewControllerToStack(viewControllerClass, null, state, viewControllerClass.getName() + ' ' + TOP_FRAGMENT_TAG_MARK, transactionSetup); } + public void setInitialViewController(@NonNull final Class, + ? extends SimpleViewControllerFragment>>> viewControllerClass) { + setInitialViewController(viewControllerClass, null, null); + } + public void setInitialViewController(@NonNull final Class, ? extends SimpleViewControllerFragment>>> viewControllerClass, @@ -159,4 +171,9 @@ public class ViewControllerNavigation extends FragmentNavigation { SimpleViewControllerFragment.createState(viewControllerClass, state), backStackTag, transactionSetup); } + //TODO: remove somehow??? + public static class Mock implements Serializable { + // just mock class + } + } diff --git a/src/main/java/ru/touchin/roboswag/components/navigation/ViewFragment.java b/src/main/java/ru/touchin/roboswag/components/navigation/ViewFragment.java index 026f4e9..783fa27 100644 --- a/src/main/java/ru/touchin/roboswag/components/navigation/ViewFragment.java +++ b/src/main/java/ru/touchin/roboswag/components/navigation/ViewFragment.java @@ -36,7 +36,8 @@ import rx.functions.Action2; * Fragment that have specific activity as a parent and can't be background. * [phase 1] */ -public abstract class ViewFragment extends Fragment { +public abstract class ViewFragment extends Fragment + implements OnFragmentStartedListener { /** * Returns if fragment have parent fragment. @@ -75,6 +76,11 @@ public abstract class ViewFragment extends throw new IllegalStateException("Method onCreateView() should be overridden"); } + @Override + public void onFragmentStarted(@NonNull final Fragment fragment) { + //do nothing + } + @Deprecated @Override public void onActivityCreated(@Nullable final Bundle savedInstanceState) {