Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ced094ea55 | |||
| ecd214fa36 | |||
| dcfe1a32b8 | |||
| 4120ce878d | |||
| c9ca3f76da | |||
| 9a7b4421c2 | |||
| 81774d2d12 | |||
| 30f2f736c0 | |||
| 0f59f588b8 | |||
| 68bc8c809c | |||
| 37d5818413 | |||
| 7344926349 | |||
| 357f8d9670 | |||
| d8266b02b8 | |||
| 7337901f19 | |||
| 2e647aec0e | |||
| e10725955b | |||
| f357e9db3a | |||
| 5ed9df5409 | |||
| b493cf5a7b | |||
| 2be8ac0db2 | |||
| b317498d95 | |||
| 230d7ba064 | |||
| b5c2d20ea3 | |||
| 1647377fb1 | |||
| f6b8c0bfe1 | |||
| 5a4eeef49f | |||
| 340e659502 | |||
| f88ab56ee9 | |||
| 3e26610157 | |||
| 906baccdfe | |||
| 72d100197a | |||
| 10918fd759 | |||
| c02d5a1ff8 |
@@ -1,18 +1,18 @@
|
||||
# Cicerone
|
||||
[](https://bintray.com/terrakok/terramaven/cicerone/_latestVersion)
|
||||
[](https://opensource.org/licenses/MIT)
|
||||
|
||||
[](https://gitter.im/terrakok/Cicerone)
|
||||
|
||||
[](https://android-arsenal.com/details/1/4700)
|
||||
[](http://androidweekly.net/issues/issue-250)
|
||||
[](https://t.me/Cicerone_ENG)
|
||||
[](https://t.me/Cicerone_RUS)
|
||||
[](http://androidweekly.net/issues/issue-250)
|
||||
[](http://androidweekly.net/issues/issue-271)
|
||||
|
||||

|
||||
|
||||
Cicerone (a guide, one who conducts sightseers) is a lightweight library that makes the navigation in an Android app easy.
|
||||
It was designed to be used with the MVP pattern (try [Moxy](https://github.com/Arello-Mobile/Moxy)), but will work great with any architecture.
|
||||
|
||||
[Russian version readme](https://github.com/terrakok/Cicerone/blob/develop/README_RUS.md)
|
||||
|
||||
## Main advantages
|
||||
+ is not tied to Fragments
|
||||
+ not a framework
|
||||
@@ -21,6 +21,11 @@ It was designed to be used with the MVP pattern (try [Moxy](https://github.com/A
|
||||
+ functionality is simple to extend
|
||||
+ suitable for Unit Testing
|
||||
|
||||
## Version 2.+
|
||||
+ easy screen result subscription
|
||||
+ predefined navigator ready for setup transition animation
|
||||
**See the sample application**
|
||||
|
||||
## How to add
|
||||
Add the dependency in your build.gradle:
|
||||
```groovy
|
||||
@@ -140,30 +145,39 @@ This commands set will fulfill the needs of the most applications. But if you ne
|
||||
The library provides predefined navigators for _Fragments_ to use inside _Activity_.
|
||||
To use, just provide it with the container and _FragmentManager_ and override few simple methods.
|
||||
```java
|
||||
private Navigator navigator = new SupportFragmentNavigator(
|
||||
getSupportFragmentManager(), R.id.main_container) {
|
||||
private Navigator navigator = new SupportAppNavigator(this, R.id.container) {
|
||||
@Override
|
||||
protected Intent createActivityIntent(String screenKey, Object data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Fragment createFragment(String screenKey, Object data) {
|
||||
return SampleFragment.getNewInstance((int) data);
|
||||
switch (screenKey) {
|
||||
case Screens.PROFILE_SCREEN:
|
||||
return new ProfileFragment();
|
||||
case Screens.SELECT_PHOTO_SCREEN:
|
||||
return SelectPhotoFragment.getNewInstance((int) data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void showSystemMessage(String message) {
|
||||
Toast.makeText(MainActivity.this, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exit() {
|
||||
finish();
|
||||
protected void setupFragmentTransactionAnimation(
|
||||
Command command,
|
||||
Fragment currentFragment,
|
||||
Fragment nextFragment,
|
||||
FragmentTransaction fragmentTransaction) {
|
||||
//setup animation
|
||||
}
|
||||
};
|
||||
```
|
||||
## Sample
|
||||
To see how to add, initialize and use the library and predefined navigators check out the sample.
|
||||
|
||||

|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Participants
|
||||
+ idea and code - Konstantin Tskhovrebov (@terrakok)
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Cicerone
|
||||
|
||||
[](https://t.me/Cicerone_RUS)
|
||||
|
||||

|
||||
|
||||
Cicerone (_"чи-че-ро́-не"_ - устар. гид) - легкая библиотека для простой реализации навигации в андроид приложении.
|
||||
Разработана для использования в MVP архитектуре (попробуйте [Moxy](https://github.com/Arello-Mobile/Moxy)), но легко встраивается в любые решения.
|
||||
|
||||
|
||||
+1
-1
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
|
||||
|
||||
@@ -15,7 +15,7 @@ ext {
|
||||
bintrayName = 'cicerone'
|
||||
publishedGroupId = 'ru.terrakok.cicerone'
|
||||
artifact = 'cicerone'
|
||||
libraryVersion = '1.2.1'
|
||||
libraryVersion = '2.1.0'
|
||||
gitUrl = 'https://github.com/terrakok/Cicerone'
|
||||
allLicenses = ['MIT']
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package ru.terrakok.cicerone;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import ru.terrakok.cicerone.commands.Back;
|
||||
import ru.terrakok.cicerone.commands.BackTo;
|
||||
import ru.terrakok.cicerone.commands.Forward;
|
||||
import ru.terrakok.cicerone.commands.Replace;
|
||||
import ru.terrakok.cicerone.commands.SystemMessage;
|
||||
import ru.terrakok.cicerone.result.ResultListener;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tckhovrebov (aka @terrakok)
|
||||
@@ -19,10 +22,49 @@ import ru.terrakok.cicerone.commands.SystemMessage;
|
||||
*/
|
||||
public class Router extends BaseRouter {
|
||||
|
||||
private HashMap<Integer, ResultListener> resultListeners = new HashMap<>();
|
||||
|
||||
public Router() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Subscribe to the screen result.<br>
|
||||
* <b>Note:</b> only one listener can subscribe to a unique resultCode!<br>
|
||||
* You must call a <b>removeResultListener()</b> to avoid a memory leak.
|
||||
*
|
||||
* @param resultCode key for filter results
|
||||
* @param listener result listener
|
||||
*/
|
||||
public void setResultListener(Integer resultCode, ResultListener listener) {
|
||||
resultListeners.put(resultCode, listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unsubscribe from the screen result.
|
||||
*
|
||||
* @param resultCode key for filter results
|
||||
*/
|
||||
public void removeResultListener(Integer resultCode) {
|
||||
resultListeners.remove(resultCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send result data to subscriber.
|
||||
*
|
||||
* @param resultCode result data key
|
||||
* @param result result data
|
||||
* @return TRUE if listener was notified and FALSE otherwise
|
||||
*/
|
||||
protected boolean sendResult(Integer resultCode, Object result) {
|
||||
ResultListener resultListener = resultListeners.get(resultCode);
|
||||
if (resultListener != null) {
|
||||
resultListener.onResult(result);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open new screen and add it to the screens chain.
|
||||
*
|
||||
@@ -138,6 +180,17 @@ public class Router extends BaseRouter {
|
||||
executeCommand(new Back());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return to the previous screen in the chain and send result data.
|
||||
*
|
||||
* @param resultCode result data key
|
||||
* @param result result data
|
||||
*/
|
||||
public void exitWithResult(Integer resultCode, Object result) {
|
||||
exit();
|
||||
sendResult(resultCode, result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return to the previous screen in the chain and show system message.
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@ package ru.terrakok.cicerone.android;
|
||||
import android.app.Activity;
|
||||
import android.app.FragmentManager;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.widget.Toast;
|
||||
|
||||
import ru.terrakok.cicerone.commands.BackTo;
|
||||
@@ -34,6 +35,17 @@ public abstract class AppNavigator extends FragmentNavigator {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to create option for start activity
|
||||
*
|
||||
* @param command current navigation command. Will be only {@link Forward} or {@link Replace}
|
||||
* @param activityIntent activity intent
|
||||
* @return transition options
|
||||
*/
|
||||
protected Bundle createStartActivityOptions(Command command, Intent activityIntent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
if (command instanceof Forward) {
|
||||
@@ -42,7 +54,8 @@ public abstract class AppNavigator extends FragmentNavigator {
|
||||
|
||||
// Start activity
|
||||
if (activityIntent != null) {
|
||||
activity.startActivity(activityIntent);
|
||||
Bundle options = createStartActivityOptions(command, activityIntent);
|
||||
activity.startActivity(activityIntent, options);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -52,7 +65,8 @@ public abstract class AppNavigator extends FragmentNavigator {
|
||||
|
||||
// Replace activity
|
||||
if (activityIntent != null) {
|
||||
activity.startActivity(activityIntent);
|
||||
Bundle options = createStartActivityOptions(command, activityIntent);
|
||||
activity.startActivity(activityIntent, options);
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.terrakok.cicerone.android;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.app.FragmentManager;
|
||||
import android.app.FragmentTransaction;
|
||||
|
||||
import ru.terrakok.cicerone.Navigator;
|
||||
import ru.terrakok.cicerone.commands.Back;
|
||||
@@ -42,6 +43,21 @@ public abstract class FragmentNavigator implements Navigator {
|
||||
this.containerId = containerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to setup custom fragment transaction animation.
|
||||
*
|
||||
* @param command current navigation command. Will be only {@link Forward} or {@link Replace}
|
||||
* @param currentFragment current fragment in container
|
||||
* (for {@link Replace} command it will be screen previous in new chain, NOT replaced screen)
|
||||
* @param nextFragment next screen fragment
|
||||
* @param fragmentTransaction fragment transaction
|
||||
*/
|
||||
protected void setupFragmentTransactionAnimation(Command command,
|
||||
Fragment currentFragment,
|
||||
Fragment nextFragment,
|
||||
FragmentTransaction fragmentTransaction) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
if (command instanceof Forward) {
|
||||
@@ -51,8 +67,16 @@ public abstract class FragmentNavigator implements Navigator {
|
||||
unknownScreen(command);
|
||||
return;
|
||||
}
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.addToBackStack(forward.getScreenKey())
|
||||
.commit();
|
||||
@@ -71,14 +95,29 @@ public abstract class FragmentNavigator implements Navigator {
|
||||
}
|
||||
if (fragmentManager.getBackStackEntryCount() > 0) {
|
||||
fragmentManager.popBackStackImmediate();
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.addToBackStack(replace.getScreenKey())
|
||||
.commit();
|
||||
} else {
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.commit();
|
||||
}
|
||||
@@ -106,10 +145,7 @@ public abstract class FragmentNavigator implements Navigator {
|
||||
}
|
||||
|
||||
private void backToRoot() {
|
||||
for (int i = 0; i < fragmentManager.getBackStackEntryCount(); i++) {
|
||||
fragmentManager.popBackStack();
|
||||
}
|
||||
fragmentManager.executePendingTransactions();
|
||||
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -147,4 +183,4 @@ public abstract class FragmentNavigator implements Navigator {
|
||||
protected void unknownScreen(Command command) {
|
||||
throw new RuntimeException("Can't create a screen for passed screenKey.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.terrakok.cicerone.android;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentActivity;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.widget.Toast;
|
||||
@@ -35,6 +36,17 @@ public abstract class SupportAppNavigator extends SupportFragmentNavigator {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to create option for start activity
|
||||
*
|
||||
* @param command current navigation command. Will be only {@link Forward} or {@link Replace}
|
||||
* @param activityIntent activity intent
|
||||
* @return transition options
|
||||
*/
|
||||
protected Bundle createStartActivityOptions(Command command, Intent activityIntent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
if (command instanceof Forward) {
|
||||
@@ -43,7 +55,8 @@ public abstract class SupportAppNavigator extends SupportFragmentNavigator {
|
||||
|
||||
// Start activity
|
||||
if (activityIntent != null) {
|
||||
activity.startActivity(activityIntent);
|
||||
Bundle options = createStartActivityOptions(command, activityIntent);
|
||||
activity.startActivity(activityIntent, options);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -53,7 +66,8 @@ public abstract class SupportAppNavigator extends SupportFragmentNavigator {
|
||||
|
||||
// Replace activity
|
||||
if (activityIntent != null) {
|
||||
activity.startActivity(activityIntent);
|
||||
Bundle options = createStartActivityOptions(command, activityIntent);
|
||||
activity.startActivity(activityIntent, options);
|
||||
activity.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package ru.terrakok.cicerone.android;
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
|
||||
import ru.terrakok.cicerone.Navigator;
|
||||
import ru.terrakok.cicerone.commands.Back;
|
||||
@@ -42,6 +43,21 @@ public abstract class SupportFragmentNavigator implements Navigator {
|
||||
this.containerId = containerId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to setup custom fragment transaction animation.
|
||||
*
|
||||
* @param command current navigation command. Will be only {@link Forward} or {@link Replace}
|
||||
* @param currentFragment current fragment in container
|
||||
* (for {@link Replace} command it will be screen previous in new chain, NOT replaced screen)
|
||||
* @param nextFragment next screen fragment
|
||||
* @param fragmentTransaction fragment transaction
|
||||
*/
|
||||
protected void setupFragmentTransactionAnimation(Command command,
|
||||
Fragment currentFragment,
|
||||
Fragment nextFragment,
|
||||
FragmentTransaction fragmentTransaction) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
if (command instanceof Forward) {
|
||||
@@ -51,8 +67,16 @@ public abstract class SupportFragmentNavigator implements Navigator {
|
||||
unknownScreen(command);
|
||||
return;
|
||||
}
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.addToBackStack(forward.getScreenKey())
|
||||
.commit();
|
||||
@@ -71,14 +95,29 @@ public abstract class SupportFragmentNavigator implements Navigator {
|
||||
}
|
||||
if (fragmentManager.getBackStackEntryCount() > 0) {
|
||||
fragmentManager.popBackStackImmediate();
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.addToBackStack(replace.getScreenKey())
|
||||
.commit();
|
||||
} else {
|
||||
fragmentManager
|
||||
.beginTransaction()
|
||||
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
|
||||
setupFragmentTransactionAnimation(
|
||||
command,
|
||||
fragmentManager.findFragmentById(containerId),
|
||||
fragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
|
||||
fragmentTransaction
|
||||
.replace(containerId, fragment)
|
||||
.commit();
|
||||
}
|
||||
@@ -106,10 +145,7 @@ public abstract class SupportFragmentNavigator implements Navigator {
|
||||
}
|
||||
|
||||
private void backToRoot() {
|
||||
for (int i = 0; i < fragmentManager.getBackStackEntryCount(); i++) {
|
||||
fragmentManager.popBackStack();
|
||||
}
|
||||
fragmentManager.executePendingTransactions();
|
||||
fragmentManager.popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,4 +182,4 @@ public abstract class SupportFragmentNavigator implements Navigator {
|
||||
protected void unknownScreen(Command command) {
|
||||
throw new RuntimeException("Can't create a screen for passed screenKey.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package ru.terrakok.cicerone.result;
|
||||
|
||||
/**
|
||||
* @author Konstantin Tskhovrebov (aka terrakok) on 04.07.17.
|
||||
*/
|
||||
|
||||
public interface ResultListener {
|
||||
|
||||
/**
|
||||
* Received result from screen.
|
||||
*
|
||||
* @param resultData
|
||||
*/
|
||||
void onResult(Object resultData);
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package android.app;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
@@ -11,6 +12,10 @@ public class Activity extends Context {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void startActivity(Intent intent, Bundle options) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public FragmentManager getFragmentManager() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ package android.app;
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class FragmentManager {
|
||||
public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
|
||||
|
||||
public FragmentTransaction beginTransaction() {
|
||||
throw new RuntimeException("Stub!");
|
||||
@@ -33,6 +34,10 @@ public class FragmentManager {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public Fragment findFragmentById(int id) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public interface BackStackEntry {
|
||||
int getId();
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ package android.support.v4.app;
|
||||
*/
|
||||
|
||||
public class FragmentManager {
|
||||
public static final int POP_BACK_STACK_INCLUSIVE = 1<<0;
|
||||
|
||||
public FragmentTransaction beginTransaction() {
|
||||
throw new RuntimeException("Stub!");
|
||||
@@ -35,6 +36,9 @@ public class FragmentManager {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public Fragment findFragmentById(int id) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public interface BackStackEntry {
|
||||
int getId();
|
||||
|
||||
+1
-1
@@ -9,7 +9,7 @@ android {
|
||||
buildToolsVersion '25.0.2'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 16
|
||||
minSdkVersion 19
|
||||
targetSdkVersion 25
|
||||
versionCode 1
|
||||
versionName "1.0.0"
|
||||
|
||||
@@ -20,5 +20,6 @@
|
||||
|
||||
<activity android:name=".ui.main.MainActivity"/>
|
||||
<activity android:name=".ui.bottom.BottomNavigationActivity"/>
|
||||
<activity android:name=".ui.animations.ProfileActivity"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -18,4 +18,7 @@ public class Screens {
|
||||
|
||||
public static final String FORWARD_SCREEN = "forward screen";
|
||||
public static final String GITHUB_SCREEN = "github screen";
|
||||
|
||||
public static final String PROFILE_SCREEN = "profile screen";
|
||||
public static final String SELECT_PHOTO_SCREEN = "select photo screen";
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import javax.inject.Singleton;
|
||||
import dagger.Component;
|
||||
import ru.terrakok.cicerone.sample.dagger.module.LocalNavigationModule;
|
||||
import ru.terrakok.cicerone.sample.dagger.module.NavigationModule;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.ProfileActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.photos.SelectPhotoFragment;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.profile.ProfileFragment;
|
||||
import ru.terrakok.cicerone.sample.ui.bottom.BottomNavigationActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.bottom.TabContainerFragment;
|
||||
import ru.terrakok.cicerone.sample.ui.main.MainActivity;
|
||||
@@ -31,4 +34,10 @@ public interface AppComponent {
|
||||
void inject(BottomNavigationActivity activity);
|
||||
|
||||
void inject(TabContainerFragment fragment);
|
||||
|
||||
void inject(ProfileFragment fragment);
|
||||
|
||||
void inject(SelectPhotoFragment fragment);
|
||||
|
||||
void inject(ProfileActivity activity);
|
||||
}
|
||||
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.animation.photos;
|
||||
|
||||
import com.arellomobile.mvp.InjectViewState;
|
||||
import com.arellomobile.mvp.MvpPresenter;
|
||||
|
||||
import ru.terrakok.cicerone.Router;
|
||||
import ru.terrakok.cicerone.sample.R;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
@InjectViewState
|
||||
public class SelectPhotoPresenter extends MvpPresenter<SelectPhotoView> {
|
||||
private Router router;
|
||||
private final int RESULT_CODE;
|
||||
|
||||
public SelectPhotoPresenter(Router router, int resultCode) {
|
||||
this.router = router;
|
||||
RESULT_CODE = resultCode;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFirstViewAttach() {
|
||||
super.onFirstViewAttach();
|
||||
|
||||
getViewState().showPhotos(new int[] {
|
||||
R.drawable.ava_1,
|
||||
R.drawable.ava_2,
|
||||
R.drawable.ava_3,
|
||||
R.drawable.ava_4
|
||||
});
|
||||
}
|
||||
|
||||
public void onPhotoClick(int photoRes) {
|
||||
router.exitWithResult(RESULT_CODE, photoRes);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
router.exit();
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.animation.photos;
|
||||
|
||||
import com.arellomobile.mvp.MvpView;
|
||||
import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy;
|
||||
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
@StateStrategyType(AddToEndSingleStrategy.class)
|
||||
public interface SelectPhotoView extends MvpView {
|
||||
void showPhotos(int[] resurceIds);
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.animation.profile;
|
||||
|
||||
import com.arellomobile.mvp.InjectViewState;
|
||||
import com.arellomobile.mvp.MvpPresenter;
|
||||
|
||||
import ru.terrakok.cicerone.Router;
|
||||
import ru.terrakok.cicerone.result.ResultListener;
|
||||
import ru.terrakok.cicerone.sample.Screens;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
@InjectViewState
|
||||
public class ProfilePresenter extends MvpPresenter<ProfileView> {
|
||||
private static final int PHOTO_RESULT_CODE = 42;
|
||||
|
||||
private Router router;
|
||||
private int currentPhoto;
|
||||
|
||||
public ProfilePresenter(int defaultPhoto, Router router) {
|
||||
currentPhoto = defaultPhoto;
|
||||
this.router = router;
|
||||
|
||||
router.setResultListener(PHOTO_RESULT_CODE, new ResultListener() {
|
||||
@Override
|
||||
public void onResult(Object resultData) {
|
||||
currentPhoto = (int) resultData;
|
||||
updatePhoto();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onFirstViewAttach() {
|
||||
super.onFirstViewAttach();
|
||||
updatePhoto();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
router.removeResultListener(PHOTO_RESULT_CODE);
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
private void updatePhoto() {
|
||||
getViewState().showPhoto(currentPhoto);
|
||||
}
|
||||
|
||||
public void onPhotoClicked() {
|
||||
router.navigateTo(Screens.SELECT_PHOTO_SCREEN, PHOTO_RESULT_CODE);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
router.exit();
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.animation.profile;
|
||||
|
||||
import com.arellomobile.mvp.MvpView;
|
||||
import com.arellomobile.mvp.viewstate.strategy.AddToEndSingleStrategy;
|
||||
import com.arellomobile.mvp.viewstate.strategy.StateStrategyType;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
@StateStrategyType(AddToEndSingleStrategy.class)
|
||||
public interface ProfileView extends MvpView {
|
||||
void showPhoto(int resId);
|
||||
}
|
||||
@@ -60,6 +60,7 @@ public class SamplePresenter extends MvpPresenter<SampleView> {
|
||||
future = executorService.schedule(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//WARNING! Navigation must be only in UI thread. this method works only for sample :)
|
||||
router.navigateTo(Screens.SAMPLE_SCREEN + (screenNumber + 1), screenNumber + 1);
|
||||
}
|
||||
}, 5, TimeUnit.SECONDS);
|
||||
|
||||
@@ -23,6 +23,10 @@ public class StartActivityPresenter extends MvpPresenter<StartActivityView> {
|
||||
router.navigateTo(Screens.BOTTOM_NAVIGATION_ACTIVITY_SCREEN);
|
||||
}
|
||||
|
||||
public void onResultWithAnimationPressed() {
|
||||
router.navigateTo(Screens.PROFILE_SCREEN);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
router.exit();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
package ru.terrakok.cicerone.sample.ui.animations;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.transition.ChangeBounds;
|
||||
import android.view.View;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import ru.terrakok.cicerone.Navigator;
|
||||
import ru.terrakok.cicerone.NavigatorHolder;
|
||||
import ru.terrakok.cicerone.android.SupportAppNavigator;
|
||||
import ru.terrakok.cicerone.commands.Command;
|
||||
import ru.terrakok.cicerone.commands.Forward;
|
||||
import ru.terrakok.cicerone.commands.Replace;
|
||||
import ru.terrakok.cicerone.sample.R;
|
||||
import ru.terrakok.cicerone.sample.SampleApplication;
|
||||
import ru.terrakok.cicerone.sample.Screens;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.photos.SelectPhotoFragment;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.profile.ProfileFragment;
|
||||
import ru.terrakok.cicerone.sample.ui.common.BackButtonListener;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
public class ProfileActivity extends AppCompatActivity {
|
||||
public static final String PHOTO_TRANSITION = "photo_trasition";
|
||||
|
||||
@Inject
|
||||
NavigatorHolder navigatorHolder;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
SampleApplication.INSTANCE.getAppComponent().inject(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_container);
|
||||
|
||||
if (savedInstanceState == null) {
|
||||
navigator.applyCommand(new Replace(Screens.PROFILE_SCREEN, null));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResumeFragments() {
|
||||
super.onResumeFragments();
|
||||
navigatorHolder.setNavigator(navigator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
navigatorHolder.removeNavigator();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
private Navigator navigator = new SupportAppNavigator(this, R.id.container) {
|
||||
@Override
|
||||
protected Intent createActivityIntent(String screenKey, Object data) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Fragment createFragment(String screenKey, Object data) {
|
||||
switch (screenKey) {
|
||||
case Screens.PROFILE_SCREEN:
|
||||
return new ProfileFragment();
|
||||
case Screens.SELECT_PHOTO_SCREEN:
|
||||
return SelectPhotoFragment.getNewInstance((int) data);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setupFragmentTransactionAnimation(Command command, Fragment currentFragment, Fragment nextFragment, FragmentTransaction fragmentTransaction) {
|
||||
if (command instanceof Forward
|
||||
&& currentFragment instanceof ProfileFragment
|
||||
&& nextFragment instanceof SelectPhotoFragment) {
|
||||
setupSharedElementForProfileToSelectPhoto(
|
||||
(ProfileFragment) currentFragment,
|
||||
(SelectPhotoFragment) nextFragment,
|
||||
fragmentTransaction
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private void setupSharedElementForProfileToSelectPhoto(ProfileFragment profileFragment,
|
||||
SelectPhotoFragment selectPhotoFragment,
|
||||
FragmentTransaction fragmentTransaction) {
|
||||
ChangeBounds changeBounds = new ChangeBounds();
|
||||
selectPhotoFragment.setSharedElementEnterTransition(changeBounds);
|
||||
selectPhotoFragment.setSharedElementReturnTransition(changeBounds);
|
||||
profileFragment.setSharedElementEnterTransition(changeBounds);
|
||||
profileFragment.setSharedElementReturnTransition(changeBounds);
|
||||
|
||||
View view = profileFragment.getAvatarViewForAnimation();
|
||||
fragmentTransaction.addSharedElement(view, PHOTO_TRANSITION);
|
||||
selectPhotoFragment.setAnimationDestinationId((Integer) view.getTag());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
Fragment fragment = getSupportFragmentManager().findFragmentById(R.id.container);
|
||||
if (fragment != null
|
||||
&& fragment instanceof BackButtonListener
|
||||
&& ((BackButtonListener) fragment).onBackPressed()) {
|
||||
return;
|
||||
} else {
|
||||
super.onBackPressed();
|
||||
}
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
package ru.terrakok.cicerone.sample.ui.animations.photos;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.arellomobile.mvp.MvpAppCompatFragment;
|
||||
import com.arellomobile.mvp.presenter.InjectPresenter;
|
||||
import com.arellomobile.mvp.presenter.ProvidePresenter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import ru.terrakok.cicerone.Router;
|
||||
import ru.terrakok.cicerone.sample.R;
|
||||
import ru.terrakok.cicerone.sample.SampleApplication;
|
||||
import ru.terrakok.cicerone.sample.mvp.animation.photos.SelectPhotoPresenter;
|
||||
import ru.terrakok.cicerone.sample.mvp.animation.photos.SelectPhotoView;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.ProfileActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.common.BackButtonListener;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
public class SelectPhotoFragment extends MvpAppCompatFragment implements SelectPhotoView, BackButtonListener {
|
||||
private static final String ARG_RESULT_CODE = "arg_result_code";
|
||||
private static final String ARG_ANIM_DESTINATION = "arg_anim_dest";
|
||||
|
||||
private ImageView photo1;
|
||||
private ImageView photo2;
|
||||
private ImageView photo3;
|
||||
private ImageView photo4;
|
||||
|
||||
@Inject
|
||||
Router router;
|
||||
|
||||
@InjectPresenter
|
||||
SelectPhotoPresenter presenter;
|
||||
|
||||
public static SelectPhotoFragment getNewInstance(int resultCode) {
|
||||
SelectPhotoFragment fragment = new SelectPhotoFragment();
|
||||
Bundle args = new Bundle();
|
||||
args.putInt(ARG_RESULT_CODE, resultCode);
|
||||
fragment.setArguments(args);
|
||||
return fragment;
|
||||
}
|
||||
|
||||
public void setAnimationDestinationId(int resId) {
|
||||
Bundle arguments = getArguments();
|
||||
arguments.putInt(ARG_ANIM_DESTINATION, resId);
|
||||
setArguments(arguments);
|
||||
}
|
||||
|
||||
private int getAnimationDestionationId() {
|
||||
return getArguments().getInt(ARG_ANIM_DESTINATION);
|
||||
}
|
||||
|
||||
@ProvidePresenter
|
||||
SelectPhotoPresenter providePresenter() {
|
||||
return new SelectPhotoPresenter(router, getArguments().getInt(ARG_RESULT_CODE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
SampleApplication.INSTANCE.getAppComponent().inject(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_select_photo, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
photo1 = (ImageView) view.findViewById(R.id.select_image_1);
|
||||
photo2 = (ImageView) view.findViewById(R.id.select_image_2);
|
||||
photo3 = (ImageView) view.findViewById(R.id.select_image_3);
|
||||
photo4 = (ImageView) view.findViewById(R.id.select_image_4);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
photo1.setOnClickListener(clickListener);
|
||||
photo2.setOnClickListener(clickListener);
|
||||
photo3.setOnClickListener(clickListener);
|
||||
photo4.setOnClickListener(clickListener);
|
||||
}
|
||||
|
||||
private View.OnClickListener clickListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
photo1.setTransitionName(null);
|
||||
photo2.setTransitionName(null);
|
||||
photo3.setTransitionName(null);
|
||||
photo4.setTransitionName(null);
|
||||
v.setTransitionName(ProfileActivity.PHOTO_TRANSITION);
|
||||
presenter.onPhotoClick((Integer) v.getTag());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void showPhotos(int[] resurceIds) {
|
||||
if (resurceIds.length >= 4) {
|
||||
photo1.setImageResource(resurceIds[0]);
|
||||
photo2.setImageResource(resurceIds[1]);
|
||||
photo3.setImageResource(resurceIds[2]);
|
||||
photo4.setImageResource(resurceIds[3]);
|
||||
|
||||
photo1.setTag(resurceIds[0]);
|
||||
photo2.setTag(resurceIds[1]);
|
||||
photo3.setTag(resurceIds[2]);
|
||||
photo4.setTag(resurceIds[3]);
|
||||
|
||||
//for shared element animation
|
||||
int animRes = getAnimationDestionationId();
|
||||
photo1.setTransitionName(animRes == resurceIds[0] ? ProfileActivity.PHOTO_TRANSITION : null);
|
||||
photo2.setTransitionName(animRes == resurceIds[1] ? ProfileActivity.PHOTO_TRANSITION : null);
|
||||
photo3.setTransitionName(animRes == resurceIds[2] ? ProfileActivity.PHOTO_TRANSITION : null);
|
||||
photo4.setTransitionName(animRes == resurceIds[3] ? ProfileActivity.PHOTO_TRANSITION : null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
presenter.onBackPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
package ru.terrakok.cicerone.sample.ui.animations.profile;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.arellomobile.mvp.MvpAppCompatFragment;
|
||||
import com.arellomobile.mvp.presenter.InjectPresenter;
|
||||
import com.arellomobile.mvp.presenter.ProvidePresenter;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import ru.terrakok.cicerone.Router;
|
||||
import ru.terrakok.cicerone.sample.R;
|
||||
import ru.terrakok.cicerone.sample.SampleApplication;
|
||||
import ru.terrakok.cicerone.sample.mvp.animation.profile.ProfilePresenter;
|
||||
import ru.terrakok.cicerone.sample.mvp.animation.profile.ProfileView;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.ProfileActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.common.BackButtonListener;
|
||||
|
||||
/**
|
||||
* Created by Konstantin Tskhovrebov (aka @terrakok) on 14.07.17.
|
||||
*/
|
||||
|
||||
public class ProfileFragment extends MvpAppCompatFragment implements ProfileView, BackButtonListener {
|
||||
private ImageView avatar;
|
||||
|
||||
@Inject
|
||||
Router router;
|
||||
|
||||
@InjectPresenter
|
||||
ProfilePresenter presenter;
|
||||
|
||||
@ProvidePresenter
|
||||
ProfilePresenter providePresenter() {
|
||||
return new ProfilePresenter(R.drawable.ava_1, router);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
SampleApplication.INSTANCE.getAppComponent().inject(this);
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
return inflater.inflate(R.layout.fragment_profile, container, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
avatar = (ImageView) view.findViewById(R.id.avatar_imageView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
avatar.setTransitionName(ProfileActivity.PHOTO_TRANSITION);
|
||||
avatar.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
presenter.onPhotoClicked();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showPhoto(int resId) {
|
||||
avatar.setImageResource(resId);
|
||||
|
||||
//for shared element animation
|
||||
avatar.setTag(resId);
|
||||
}
|
||||
|
||||
public View getAvatarViewForAnimation() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onBackPressed() {
|
||||
presenter.onBackPressed();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import ru.terrakok.cicerone.sample.SampleApplication;
|
||||
import ru.terrakok.cicerone.sample.Screens;
|
||||
import ru.terrakok.cicerone.sample.mvp.start.StartActivityPresenter;
|
||||
import ru.terrakok.cicerone.sample.mvp.start.StartActivityView;
|
||||
import ru.terrakok.cicerone.sample.ui.animations.ProfileActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.bottom.BottomNavigationActivity;
|
||||
import ru.terrakok.cicerone.sample.ui.main.MainActivity;
|
||||
|
||||
@@ -68,6 +69,12 @@ public class StartActivity extends MvpAppCompatActivity implements StartActivity
|
||||
presenter.onMultiPressed();
|
||||
}
|
||||
});
|
||||
findViewById(R.id.result_and_anim_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
presenter.onResultWithAnimationPressed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,6 +94,7 @@ public class StartActivity extends MvpAppCompatActivity implements StartActivity
|
||||
presenter.onBackPressed();
|
||||
}
|
||||
|
||||
//Sample fully custom navigator:
|
||||
private Navigator navigator = new Navigator() {
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
@@ -114,6 +122,9 @@ public class StartActivity extends MvpAppCompatActivity implements StartActivity
|
||||
case Screens.BOTTOM_NAVIGATION_ACTIVITY_SCREEN:
|
||||
startActivity(new Intent(StartActivity.this, BottomNavigationActivity.class));
|
||||
break;
|
||||
case Screens.PROFILE_SCREEN:
|
||||
startActivity(new Intent(StartActivity.this, ProfileActivity.class));
|
||||
break;
|
||||
default:
|
||||
Log.e("Cicerone", "Unknown screen: " + command.getScreenKey());
|
||||
break;
|
||||
@@ -125,6 +136,7 @@ public class StartActivity extends MvpAppCompatActivity implements StartActivity
|
||||
case Screens.START_ACTIVITY_SCREEN:
|
||||
case Screens.MAIN_ACTIVITY_SCREEN:
|
||||
case Screens.BOTTOM_NAVIGATION_ACTIVITY_SCREEN:
|
||||
case Screens.PROFILE_SCREEN:
|
||||
forward(new Forward(command.getScreenKey(), command.getTransitionData()));
|
||||
finish();
|
||||
break;
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 293 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 231 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 200 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 366 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
@@ -36,4 +36,11 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/multi_nav"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/result_and_anim_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/result_and_anim_nav"/>
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/avatar_imageView"
|
||||
android:layout_width="100dp"
|
||||
android:layout_height="100dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:layout_margin="40dp"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/ava_1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:gravity="center"
|
||||
android:text="Click on image for select other photo"
|
||||
android:textSize="16sp"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/select_image_1"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/select_image_2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/select_image_3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/select_image_4"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:scaleType="centerCrop"/>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -3,6 +3,7 @@
|
||||
<string name="cicerone_description">Cicerone is a lightweight library that makes the navigation in an Android app easy.</string>
|
||||
<string name="ordinary_nav">Ordinary navigation</string>
|
||||
<string name="multi_nav">Multi navigation</string>
|
||||
<string name="result_and_anim_nav">Resulting and animation sample</string>
|
||||
|
||||
<string name="tab_android">Android</string>
|
||||
<string name="tab_bug">Bug</string>
|
||||
|
||||
Reference in New Issue
Block a user