view controllers now working

This commit is contained in:
Gavriil Sitnikov 2016-03-11 21:24:02 +03:00
parent 2a3e1429e1
commit bd4b8f45f1
9 changed files with 202 additions and 8 deletions

View File

@ -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<OnBackPressedListener> 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();
}
}

View File

@ -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<? extends Fragment> fragmentClass,
@Nullable final Fragment targetFragment,

View File

@ -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;
}
}

View File

@ -35,7 +35,7 @@ public class SimpleViewControllerFragment<TState extends Serializable, TLogicBri
@NonNull
@Override
protected Class<? extends ViewController<TLogicBridge, TActivity,
public Class<? extends ViewController<TLogicBridge, TActivity,
? extends ViewControllerFragment<TState, TLogicBridge, TActivity>>> getViewControllerClass() {
return viewControllerClass;
}

View File

@ -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<TLogicBridge,
this.container = creationContext.container;
savedStateSubscription = getRestoreSavedStateObservable(creationContext, savedInstanceState)
.filter(savedState -> savedState != null)
.first()
.filter(savedState -> savedState != null)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onRestoreSavedState);
}
@ -117,7 +115,7 @@ public class ViewController<TLogicBridge,
* @return Returns view;
*/
@NonNull
public View getContainer() {
public ViewGroup getContainer() {
return container;
}

View File

@ -1,7 +1,6 @@
package ru.touchin.roboswag.components.navigation;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import ru.touchin.roboswag.components.services.LogicService;
import ru.touchin.roboswag.core.utils.android.RxAndroidUtils;

View File

@ -89,7 +89,7 @@ public abstract class ViewControllerFragment<TState extends Serializable, TLogic
* @return Returns class of specific ViewController.
*/
@NonNull
protected abstract Class<? extends ViewController<TLogicBridge, TActivity,
public abstract Class<? extends ViewController<TLogicBridge, TActivity,
? extends ViewControllerFragment<TState, TLogicBridge, TActivity>>> getViewControllerClass();
@SuppressWarnings("unchecked")

View File

@ -110,6 +110,12 @@ public class ViewControllerNavigation<TLogicBridge> extends FragmentNavigation {
addViewControllerToStack(viewControllerClass, targetFragment, state, viewControllerClass.getName() + ';' + WITH_TARGET_FRAGMENT_TAG_MARK, transactionSetup);
}
public void setViewControllerAsTop(@NonNull final Class<? extends ViewController<TLogicBridge,
? extends ViewControllerActivity<TLogicBridge>,
? extends SimpleViewControllerFragment<Mock, TLogicBridge, ? extends ViewControllerActivity<TLogicBridge>>>> viewControllerClass) {
addViewControllerToStack(viewControllerClass, null, null, viewControllerClass.getName() + ' ' + TOP_FRAGMENT_TAG_MARK, null);
}
public <TState extends Serializable> void setViewControllerAsTop(@NonNull final Class<? extends ViewController<TLogicBridge,
? extends ViewControllerActivity<TLogicBridge>,
? extends SimpleViewControllerFragment<TState, TLogicBridge, ? extends ViewControllerActivity<TLogicBridge>>>> viewControllerClass,
@ -125,6 +131,12 @@ public class ViewControllerNavigation<TLogicBridge> extends FragmentNavigation {
addViewControllerToStack(viewControllerClass, null, state, viewControllerClass.getName() + ' ' + TOP_FRAGMENT_TAG_MARK, transactionSetup);
}
public void setInitialViewController(@NonNull final Class<? extends ViewController<TLogicBridge,
? extends ViewControllerActivity<TLogicBridge>,
? extends SimpleViewControllerFragment<Mock, TLogicBridge, ? extends ViewControllerActivity<TLogicBridge>>>> viewControllerClass) {
setInitialViewController(viewControllerClass, null, null);
}
public <TState extends Serializable> void setInitialViewController(@NonNull final Class<? extends ViewController<TLogicBridge,
? extends ViewControllerActivity<TLogicBridge>,
? extends SimpleViewControllerFragment<TState, TLogicBridge, ? extends ViewControllerActivity<TLogicBridge>>>> viewControllerClass,
@ -159,4 +171,9 @@ public class ViewControllerNavigation<TLogicBridge> extends FragmentNavigation {
SimpleViewControllerFragment.createState(viewControllerClass, state), backStackTag, transactionSetup);
}
//TODO: remove somehow???
public static class Mock implements Serializable {
// just mock class
}
}

View File

@ -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<TActivity extends AppCompatActivity> extends Fragment {
public abstract class ViewFragment<TActivity extends AppCompatActivity> extends Fragment
implements OnFragmentStartedListener {
/**
* Returns if fragment have parent fragment.
@ -75,6 +76,11 @@ public abstract class ViewFragment<TActivity extends AppCompatActivity> 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) {