Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 427592e309 | |||
| b3e32c154f | |||
| 69feb03db6 | |||
| 1505ba87af | |||
| 3dfb107a21 | |||
| 458d9b053e | |||
| 93cecdee1d | |||
| 457c70e026 | |||
| e88b08d8ce | |||
| 4e896d3631 | |||
| a5404b0939 | |||
| 4d096351cc |
@@ -1,31 +1,28 @@
|
||||
# Cicerone
|
||||
[](https://bintray.com/terrakok/terramaven/cicerone)
|
||||
[](http://choosealicense.com/licenses/apache-2.0/)
|
||||
|
||||
Cicerone (a guide who gives information to sightseers) is a lightweight library that makes the navigation in an Android app easy.
|
||||
It designed for using with MVP architecture (try [Moxy](https://github.com/Arello-Mobile/Moxy)), but it fits to work in other ways.
|
||||
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.
|
||||
|
||||
## Main advantages
|
||||
+ not tied to Fragments
|
||||
+ not framework
|
||||
+ is not tied to Fragments
|
||||
+ not a framework
|
||||
+ short navigation calls (no builders)
|
||||
+ lifecycle-safely!
|
||||
+ functional is simple to extent
|
||||
+ adapted for Unit Testing
|
||||
+ lifecycle-safe!
|
||||
+ functionality is simple to extend
|
||||
+ suitable for Unit Testing
|
||||
|
||||
## How to connect?
|
||||
Add the following lines to build.gradle:
|
||||
## How to add
|
||||
Add the dependency in your build.gradle:
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://dl.bintray.com/terrakok/terramaven/'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//Cicerone
|
||||
compile 'ru.terrakok.cicerone:cicerone:1.0'
|
||||
compile 'ru.terrakok.cicerone:cicerone:1.1'
|
||||
}
|
||||
```
|
||||
And initialise library for example with application:
|
||||
|
||||
Initialize the library (for example in your Application class):
|
||||
```java
|
||||
public class SampleApplication extends MvpApplication {
|
||||
public static SampleApplication INSTANCE;
|
||||
@@ -76,10 +73,11 @@ public class SamplePresenter extends Presenter<SampleView> {
|
||||
}
|
||||
```
|
||||
|
||||
Router converts the navigation calls to Comand sets and sends them to CommandBuffer.
|
||||
Command Buffer checks whether there _"active"_ Navigator.
|
||||
If yes, it caused the necessary commands for the requested transfer.
|
||||
If not, the command added to the queue, which will be applied as soon as _"active"_ Navigator.
|
||||
Router converts the navigation call to the set of Commands and sends them to CommandBuffer.
|
||||
|
||||
CommandBuffer checks whether there are _"active"_ Navigator:
|
||||
If yes, it passes the commands to the Navigator. Navigator will process them to achive the desired transition.
|
||||
If no, then CommandBuffer saves the commands in a queue, and will apply them as soon as new _"active"_ Navigator will appear.
|
||||
|
||||
```java
|
||||
protected void executeCommand(Command command) {
|
||||
@@ -91,8 +89,8 @@ protected void executeCommand(Command command) {
|
||||
}
|
||||
```
|
||||
|
||||
Navigator - implements the navigation commands, e.g. anonymous class inside the Activity.
|
||||
Activity provides Navigator for CommandBuffer in _onResume_ and remove in _onPause_
|
||||
Navigator processes the navigation commands. Usually it is an anonymous class inside the Activity.
|
||||
Activity provides Navigator to the CommandBuffer in _onResume_ and removes it in _onPause_.
|
||||
|
||||
```java
|
||||
@Override
|
||||
@@ -110,27 +108,27 @@ protected void onPause() {
|
||||
private Navigator navigator = new Navigator() {
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
//implements commands logic
|
||||
//implement commands logic
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
## Navigation commands
|
||||
These command set will fulfill needs of the most application. But if you require more - supply your own!
|
||||
This commands set will fulfill the needs of the most applications. But if you need something special - just add it!
|
||||
+ Forward - Opens new screen
|
||||

|
||||
+ Back - Rolls back the last transition from the screens chain
|
||||
+ Back - Rolls back the last transition
|
||||

|
||||
+ BackTo - Rolls back to the needed screen from the screens chain
|
||||
+ BackTo - Rolls back to the needed screen in the screens chain
|
||||

|
||||
+ Replace - Replaces the current screen
|
||||

|
||||
+ SystemMessage - Shows system message (Alert, Toast, Snack etc)
|
||||
+ SystemMessage - Shows system message (Alert, Toast, Snack, etc.)
|
||||

|
||||
|
||||
## Ready navigators
|
||||
The library provides ready navigators for _Activity_.
|
||||
To use them, just give the container and pass _FragmentManager_.
|
||||
## Predefined navigators
|
||||
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) {
|
||||
@@ -151,13 +149,13 @@ private Navigator navigator = new SupportFragmentNavigator(
|
||||
};
|
||||
```
|
||||
## Sample
|
||||
Library usage examples, ready navigators and more can be found in the sample application.
|
||||
To see how to add, initialize and use the library and predefined navigators check out the sample.
|
||||
|
||||

|
||||
|
||||
## Participants
|
||||
+ idea and realization - Konstantin Tckhovrebov (@terrakok)
|
||||
+ architectural advice, documentation and publication - Vasily Chirvon (@Jeevuz)
|
||||
+ idea and code - Konstantin Tskhovrebov (@terrakok)
|
||||
+ architecture advice, documentation and publication - Vasili Chyrvon (@Jeevuz)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
+2
-8
@@ -12,17 +12,11 @@ Cicerone (_"чи-че-ро́-не"_ - устар. гид) - легкая биб
|
||||
+ приспособлена для Unit тестов
|
||||
|
||||
## Как подключить?
|
||||
Добавьте в build.gradle следующие строки:
|
||||
Добавьте в build.gradle зависимость:
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
url 'https://dl.bintray.com/terrakok/terramaven/'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
//Cicerone
|
||||
compile 'ru.terrakok.cicerone:cicerone:1.0'
|
||||
compile 'ru.terrakok.cicerone:cicerone:1.1'
|
||||
}
|
||||
```
|
||||
И инициализируйте библиотеку, например, так:
|
||||
|
||||
@@ -6,8 +6,7 @@ sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.google.android:android:4.0.1.2'
|
||||
compileOnly project(':stub-appcompat')
|
||||
compileOnly project(':stub-android')
|
||||
}
|
||||
|
||||
ext {
|
||||
@@ -16,7 +15,7 @@ ext {
|
||||
bintrayName = 'cicerone'
|
||||
publishedGroupId = 'ru.terrakok.cicerone'
|
||||
artifact = 'cicerone'
|
||||
libraryVersion = '1.0'
|
||||
libraryVersion = '1.1'
|
||||
gitUrl = 'https://github.com/terrakok/Cicerone'
|
||||
allLicenses = ['Apache-2.0']
|
||||
}
|
||||
|
||||
@@ -2,7 +2,3 @@ apply plugin: 'java'
|
||||
|
||||
sourceCompatibility = JavaVersion.VERSION_1_7
|
||||
targetCompatibility = JavaVersion.VERSION_1_7
|
||||
|
||||
dependencies {
|
||||
compileOnly 'com.google.android:android:4.0.1.2'
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package android.app;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class Activity {
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package android.app;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class Fragment {
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void onStart() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void onDestroyView() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void onDestroy() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
final public boolean isRemoving() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public final Activity getActivity() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
package android.app;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class FragmentManager {
|
||||
|
||||
public FragmentTransaction beginTransaction() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public boolean executePendingTransactions() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public void popBackStack() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public boolean popBackStackImmediate() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public boolean popBackStackImmediate(String name, int flags) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public int getBackStackEntryCount() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public BackStackEntry getBackStackEntryAt(int index) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public interface BackStackEntry {
|
||||
int getId();
|
||||
|
||||
String getName();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package android.app;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class FragmentTransaction {
|
||||
public FragmentTransaction replace(int containerViewId, Fragment fragment) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public FragmentTransaction addToBackStack(String name) {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
|
||||
public int commit() {
|
||||
throw new RuntimeException("Stub!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package android.os;
|
||||
|
||||
/***
|
||||
* Created by laomo on 2016-11-21.
|
||||
*/
|
||||
public class Bundle {
|
||||
}
|
||||
@@ -7,15 +7,17 @@
|
||||
android:name=".SampleApplication"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:theme="@style/AppTheme"
|
||||
android:label="@string/app_name">
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity
|
||||
android:name=".ui.main.MainActivity">
|
||||
android:name=".ui.start.StartActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
<category android:name="android.intent.category.LAUNCHER"/>
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity android:name=".ui.main.MainActivity"/>
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -7,4 +7,6 @@ package ru.terrakok.cicerone.sample;
|
||||
|
||||
public class Screens {
|
||||
public static final String SAMPLE_SCREEN = "sample_screen_";
|
||||
public static final String START_ACTIVITY_SCREEN = "start activity screen";
|
||||
public static final String MAIN_ACTIVITY_SCREEN = "main activity screen";
|
||||
}
|
||||
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.start;
|
||||
|
||||
import com.arellomobile.mvp.MvpPresenter;
|
||||
|
||||
import ru.terrakok.cicerone.Router;
|
||||
import ru.terrakok.cicerone.sample.SampleApplication;
|
||||
import ru.terrakok.cicerone.sample.Screens;
|
||||
|
||||
/**
|
||||
* Created by terrakok 21.11.16
|
||||
*/
|
||||
public class StartActivityPresenter extends MvpPresenter<StartActivityView> {
|
||||
private Router router;
|
||||
|
||||
public StartActivityPresenter() {
|
||||
router = SampleApplication.INSTANCE.getRouter();
|
||||
}
|
||||
|
||||
public void onNextPressed() {
|
||||
router.replaceScreen(Screens.MAIN_ACTIVITY_SCREEN);
|
||||
}
|
||||
|
||||
public void onBackPressed() {
|
||||
router.exit();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package ru.terrakok.cicerone.sample.mvp.start;
|
||||
|
||||
import com.arellomobile.mvp.MvpView;
|
||||
|
||||
/**
|
||||
* Created by terrakok 21.11.16
|
||||
*/
|
||||
public interface StartActivityView extends MvpView {
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package ru.terrakok.cicerone.sample.ui.start;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.arellomobile.mvp.MvpAppCompatActivity;
|
||||
import com.arellomobile.mvp.presenter.InjectPresenter;
|
||||
|
||||
import ru.terrakok.cicerone.Navigator;
|
||||
import ru.terrakok.cicerone.commands.Back;
|
||||
import ru.terrakok.cicerone.commands.Command;
|
||||
import ru.terrakok.cicerone.commands.Forward;
|
||||
import ru.terrakok.cicerone.commands.Replace;
|
||||
import ru.terrakok.cicerone.commands.SystemMessage;
|
||||
import ru.terrakok.cicerone.sample.R;
|
||||
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.main.MainActivity;
|
||||
|
||||
/**
|
||||
* Created by terrakok 21.11.16
|
||||
*/
|
||||
public class StartActivity extends MvpAppCompatActivity implements StartActivityView {
|
||||
@InjectPresenter
|
||||
StartActivityPresenter presenter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_start);
|
||||
initViews();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
findViewById(R.id.lets_go_button).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
presenter.onNextPressed();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
SampleApplication.INSTANCE.getNavigatorHolder().setNavigator(navigator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
SampleApplication.INSTANCE.getNavigatorHolder().removeNavigator();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
presenter.onBackPressed();
|
||||
}
|
||||
|
||||
private Navigator navigator = new Navigator() {
|
||||
@Override
|
||||
public void applyCommand(Command command) {
|
||||
if (command instanceof Forward) {
|
||||
forward((Forward) command);
|
||||
} else if (command instanceof Replace) {
|
||||
replace((Replace) command);
|
||||
} else if (command instanceof Back) {
|
||||
back();
|
||||
} else if (command instanceof SystemMessage) {
|
||||
Toast.makeText(StartActivity.this, ((SystemMessage) command).getMessage(), Toast.LENGTH_SHORT).show();
|
||||
} else {
|
||||
Log.e("Cicerone", "Illegal command for this screen: " + command.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
private void forward(Forward command) {
|
||||
switch (command.getScreenKey()) {
|
||||
case Screens.START_ACTIVITY_SCREEN:
|
||||
startActivity(new Intent(StartActivity.this, StartActivity.class));
|
||||
break;
|
||||
case Screens.MAIN_ACTIVITY_SCREEN:
|
||||
startActivity(new Intent(StartActivity.this, MainActivity.class));
|
||||
break;
|
||||
default:
|
||||
Log.e("Cicerone", "Unknown screen: " + command.getScreenKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void replace(Replace command) {
|
||||
switch (command.getScreenKey()) {
|
||||
case Screens.START_ACTIVITY_SCREEN:
|
||||
case Screens.MAIN_ACTIVITY_SCREEN:
|
||||
forward(new Forward(command.getScreenKey(), command.getTransitionData()));
|
||||
finish();
|
||||
break;
|
||||
default:
|
||||
Log.e("Cicerone", "Unknown screen: " + command.getScreenKey());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void back() {
|
||||
finish();
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?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">
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="16dp"
|
||||
android:text="@string/cicerone_description"
|
||||
android:textSize="18sp"/>
|
||||
|
||||
<android.support.v4.widget.Space
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/lets_go_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
android:text="@string/lets_go"/>
|
||||
</LinearLayout>
|
||||
@@ -1,3 +1,5 @@
|
||||
<resources>
|
||||
<string name="app_name">Cicerone Sample</string>
|
||||
<string name="cicerone_description">Cicerone is a lightweight library that makes the navigation in an Android app easy.</string>
|
||||
<string name="lets_go">Lets Go!</string>
|
||||
</resources>
|
||||
+2
-2
@@ -1,2 +1,2 @@
|
||||
include ':library', ':sample', ':stub-appcompat'
|
||||
project(':stub-appcompat').projectDir = new File('library/stub-appcompat')
|
||||
include ':library', ':sample', ':stub-android'
|
||||
project(':stub-android').projectDir = new File('library/stub-android')
|
||||
|
||||
Reference in New Issue
Block a user