├── navi
├── .gitignore
├── src
│ ├── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ │ └── com
│ │ │ └── trello
│ │ │ └── navi2
│ │ │ ├── Listener.java
│ │ │ ├── internal
│ │ │ ├── Constants.java
│ │ │ ├── HandledEvents.java
│ │ │ └── NaviEmitter.java
│ │ │ ├── model
│ │ │ ├── ViewCreated.java
│ │ │ ├── ActivityResult.java
│ │ │ ├── BundleBundle.java
│ │ │ └── RequestPermissionsResult.java
│ │ │ ├── rx
│ │ │ ├── RxNavi.java
│ │ │ └── NaviOnSubscribe.java
│ │ │ ├── NaviComponent.java
│ │ │ ├── component
│ │ │ ├── NaviFragment.java
│ │ │ ├── NaviDialogFragment.java
│ │ │ ├── support
│ │ │ │ ├── NaviDialogFragment.java
│ │ │ │ ├── NaviFragment.java
│ │ │ │ ├── NaviAppCompatDialogFragment.java
│ │ │ │ └── NaviAppCompatActivity.java
│ │ │ └── NaviActivity.java
│ │ │ └── Event.java
│ └── test
│ │ └── java
│ │ └── com
│ │ └── trello
│ │ └── navi2
│ │ ├── TestUtils.java
│ │ ├── EventHandlingTest.java
│ │ ├── rx
│ │ ├── RxNaviAllEventTest.java
│ │ ├── RxNaviFragmentTest.java
│ │ └── RxNaviActivityTest.java
│ │ ├── AllEventTest.java
│ │ ├── AddRemoveTest.java
│ │ ├── NullBundleTest.java
│ │ ├── ConcurrencyTest.java
│ │ ├── NaviFragmentTest.java
│ │ └── NaviActivityTest.java
├── gradle.properties
└── build.gradle
├── sample
├── .gitignore
├── src
│ └── main
│ │ ├── res
│ │ ├── values
│ │ │ └── strings.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
│ │ └── layout
│ │ │ └── main.xml
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── com
│ │ └── trello
│ │ └── navi2
│ │ └── sample
│ │ └── MainActivity.java
└── build.gradle
├── settings.gradle
├── gradle
├── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── artifacts.gradle
└── gradle-mvn-push.gradle
├── gradle.properties
├── .gitignore
├── .travis.yml
├── gradlew.bat
├── README.md
├── CHANGELOG.md
├── gradlew
└── LICENSE
/navi/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/sample/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':navi'
2 | include ':sample'
3 |
--------------------------------------------------------------------------------
/navi/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/navi/gradle.properties:
--------------------------------------------------------------------------------
1 | POM_NAME=Navi
2 | POM_DESCRIPTION=Navi
3 | POM_ARTIFACT_ID=navi
4 | POM_PACKAGING=aar
--------------------------------------------------------------------------------
/sample/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Navi
3 |
4 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/sample/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/sample/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/sample/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/sample/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/trello-archive/navi/HEAD/sample/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionBase=GRADLE_USER_HOME
2 | distributionPath=wrapper/dists
3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-all.zip
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 |
--------------------------------------------------------------------------------
/sample/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | GROUP=com.trello.navi2
2 | VERSION_NAME=2.1.0-SNAPSHOT
3 |
4 | POM_URL=https://github.com/trello/navi
5 | POM_SCM_URL=https://github.com/trello/navi
6 | POM_SCM_CONNECTION=scm:git:https://github.com/trello/navi.git
7 | POM_SCM_DEV_CONNECTION=scm:git:git@github.com:trello/navi.git
8 |
9 | POM_LICENCE_NAME=The Apache Software License, Version 2.0
10 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt
11 | POM_LICENCE_DIST=repo
12 |
13 | POM_DEVELOPER_ID=dlew
14 | POM_DEVELOPER_NAME=Dan Lew
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Built application files
2 | *.apk
3 | *.ap_
4 |
5 | # Files for the Dalvik VM
6 | *.dex
7 |
8 | # Java class files
9 | *.class
10 |
11 | # Generated files
12 | bin/
13 | gen/
14 |
15 | # Gradle files
16 | .gradle/
17 | build/
18 |
19 | # Local configuration file (sdk path, etc)
20 | local.properties
21 |
22 | # Proguard folder generated by Eclipse
23 | proguard/
24 |
25 | # Log Files
26 | *.log
27 |
28 | # Ignored repo build directory
29 | repo/
30 |
31 | # IntelliJ files
32 | *.iml
33 | *.idea
34 |
35 | # Mac OS
36 | .DS_STORE
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: android
2 |
3 | android:
4 | components:
5 | - tools
6 | - platform-tools
7 | - android-28
8 | - extra-android-m2repository
9 |
10 | jdk: oraclejdk8
11 |
12 | notifications:
13 | email: false
14 |
15 | sudo: false
16 |
17 | cache:
18 | directories:
19 | - $HOME/.gradle
20 |
21 | before_install:
22 | # Install SDK license so Android Gradle plugin can install deps.
23 | - mkdir "$ANDROID_HOME/licenses" || true
24 | - echo "d56f5187479451eabf01fb78af6dfcb131a6481e" > "$ANDROID_HOME/licenses/android-sdk-license"
25 |
26 | script: ./gradlew build test
--------------------------------------------------------------------------------
/sample/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.compileSdkVersion
5 |
6 | defaultConfig {
7 | applicationId "com.trello.navi2.sample"
8 | minSdkVersion rootProject.ext.minSdkVersion
9 | targetSdkVersion rootProject.ext.targetSdkVersion
10 | versionCode 1
11 | versionName "1.0"
12 | }
13 | }
14 |
15 | repositories {
16 | google()
17 | jcenter()
18 | }
19 |
20 | dependencies {
21 | implementation project(':navi')
22 | implementation rootProject.ext.supportAppCompat
23 | implementation rootProject.ext.rxJava
24 | implementation rootProject.ext.rxAndroid
25 | }
26 |
--------------------------------------------------------------------------------
/sample/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
14 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/Listener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2;
16 |
17 | import androidx.annotation.NonNull;
18 |
19 | /**
20 | * Listener callback.
21 | *
22 | * @param the callback type; can be Void in cases where event has no metadata
23 | */
24 | public interface Listener {
25 | void call(@NonNull T t);
26 | }
27 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/internal/Constants.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.internal;
16 |
17 | final class Constants {
18 |
19 | /**
20 | * Acts as a signal for events that have no data associated with them.
21 | *
22 | * We reuse a single Object to avoid any extra allocations.
23 | */
24 | static final Object SIGNAL = new Object();
25 |
26 | private Constants() {
27 | throw new AssertionError("No instances!");
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/navi/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion rootProject.ext.compileSdkVersion
5 |
6 | defaultConfig {
7 | minSdkVersion rootProject.ext.minSdkVersion
8 | }
9 |
10 | lintOptions {
11 | textReport true
12 | textOutput 'stdout'
13 | }
14 |
15 | // TODO replace with https://issuetracker.google.com/issues/72050365 once released.
16 | libraryVariants.all {
17 | it.generateBuildConfig.enabled = false
18 | }
19 | }
20 |
21 | repositories {
22 | google()
23 | jcenter()
24 | }
25 |
26 | dependencies {
27 | implementation rootProject.ext.supportAnnotations
28 |
29 | annotationProcessor rootProject.ext.autoValue
30 | compileOnly rootProject.ext.autoValueAnnotations
31 |
32 | // Optional dependencies, depending on if your project uses them
33 | compileOnly rootProject.ext.rxJava
34 | compileOnly rootProject.ext.supportAppCompat
35 |
36 | testImplementation rootProject.ext.rxJava
37 | testImplementation rootProject.ext.junit
38 | testImplementation rootProject.ext.mockito
39 | }
40 |
41 | apply from: "$rootDir/gradle/artifacts.gradle"
42 | apply from: "$rootDir/gradle/gradle-mvn-push.gradle"
43 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/model/ViewCreated.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.model;
16 |
17 | import android.os.Bundle;
18 | import android.view.View;
19 |
20 | import com.google.auto.value.AutoValue;
21 |
22 | import androidx.annotation.NonNull;
23 | import androidx.annotation.Nullable;
24 |
25 | @AutoValue public abstract class ViewCreated {
26 |
27 | public static ViewCreated create(@NonNull View view, @Nullable Bundle bundle) {
28 | return new AutoValue_ViewCreated(view, bundle);
29 | }
30 |
31 | @NonNull public abstract View view();
32 |
33 | @Nullable
34 | public abstract Bundle bundle();
35 | }
36 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/model/ActivityResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.model;
16 |
17 | import android.content.Intent;
18 |
19 | import com.google.auto.value.AutoValue;
20 |
21 | import androidx.annotation.Nullable;
22 |
23 | @AutoValue public abstract class ActivityResult {
24 |
25 | public static ActivityResult create(int requestCode, int resultCode, @Nullable Intent data) {
26 | return new AutoValue_ActivityResult(requestCode, resultCode, data);
27 | }
28 |
29 | public abstract int requestCode();
30 |
31 | public abstract int resultCode();
32 |
33 | @Nullable public abstract Intent data();
34 | }
35 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/model/BundleBundle.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.model;
16 |
17 | import android.os.Bundle;
18 | import android.os.PersistableBundle;
19 |
20 | import com.google.auto.value.AutoValue;
21 |
22 | import androidx.annotation.Nullable;
23 |
24 | @AutoValue public abstract class BundleBundle {
25 |
26 | public static BundleBundle create(@Nullable Bundle bundle,
27 | @Nullable PersistableBundle persistableBundle) {
28 | return new AutoValue_BundleBundle(bundle, persistableBundle);
29 | }
30 |
31 | @Nullable public abstract Bundle bundle();
32 |
33 | @Nullable public abstract PersistableBundle persistableBundle();
34 | }
35 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/rx/RxNavi.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.rx;
16 |
17 | import com.trello.navi2.Event;
18 | import com.trello.navi2.NaviComponent;
19 |
20 | import androidx.annotation.CheckResult;
21 | import androidx.annotation.NonNull;
22 | import io.reactivex.Observable;
23 |
24 | public final class RxNavi {
25 |
26 | @CheckResult @NonNull
27 | public static Observable observe(@NonNull NaviComponent component, @NonNull Event event) {
28 | if (component == null) throw new IllegalArgumentException("component == null");
29 | if (event == null) throw new IllegalArgumentException("event == null");
30 | return Observable.create(new NaviOnSubscribe<>(component, event));
31 | }
32 |
33 | private RxNavi() {
34 | throw new AssertionError("No instances!");
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/navi/src/test/java/com/trello/navi2/TestUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2;
16 |
17 | import android.os.Build;
18 | import java.lang.reflect.Field;
19 | import java.lang.reflect.Modifier;
20 |
21 | public class TestUtils {
22 |
23 | // This horrible hack is used while mockableAndroidJar isn't working properly
24 | public static void setSdkInt(int value) {
25 | try {
26 | Field field = Build.VERSION.class.getField("SDK_INT");
27 | field.setAccessible(true);
28 |
29 | Field modifiersField = Field.class.getDeclaredField("modifiers");
30 | modifiersField.setAccessible(true);
31 | modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
32 |
33 | field.setInt(null, value);
34 | } catch (Exception e) {
35 | throw new RuntimeException(e);
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/model/RequestPermissionsResult.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.model;
16 |
17 | import com.google.auto.value.AutoValue;
18 |
19 | import java.util.Arrays;
20 | import java.util.Collections;
21 | import java.util.List;
22 |
23 | import androidx.annotation.NonNull;
24 |
25 | @AutoValue public abstract class RequestPermissionsResult {
26 |
27 | public static RequestPermissionsResult create(int requestCode, @NonNull String[] permissions,
28 | @NonNull int[] grantResults) {
29 | return new AutoValue_RequestPermissionsResult(requestCode,
30 | Collections.unmodifiableList(Arrays.asList(permissions)), grantResults);
31 | }
32 |
33 | public abstract int requestCode();
34 |
35 | @NonNull public abstract List permissions();
36 |
37 | @SuppressWarnings("mutable")
38 | @NonNull public abstract int[] grantResults();
39 | }
40 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/NaviComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2;
16 |
17 | import androidx.annotation.NonNull;
18 |
19 | /**
20 | * Represents an Android component (Activity, Fragment) that can have listeners.
21 | */
22 | public interface NaviComponent {
23 |
24 | /**
25 | * Determines whether this component can handle particular events.
26 | *
27 | * For example, Activities do not handle Event.CREATE_VIEW since they do not have that step.
28 | *
29 | * @param events the events to check
30 | * @return true if all events can be handled
31 | */
32 | boolean handlesEvents(Event... events);
33 |
34 | /**
35 | * Adds a listener to this component.
36 | *
37 | * @param event an Event
38 | * @param listener the listener for that event
39 | * @param the callback type for the event
40 | * @throws IllegalArgumentException if this component cannot handle the event
41 | */
42 | void addListener(@NonNull Event event, @NonNull Listener listener);
43 |
44 | /**
45 | * Removes a listener from this component.
46 | *
47 | * @param the callback type for the event
48 | * @param listener the listener for that event
49 | */
50 | void removeListener(@NonNull Listener listener);
51 | }
52 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/rx/NaviOnSubscribe.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.rx;
16 |
17 | import com.trello.navi2.Event;
18 | import com.trello.navi2.Listener;
19 | import com.trello.navi2.NaviComponent;
20 |
21 | import java.util.concurrent.atomic.AtomicBoolean;
22 |
23 | import androidx.annotation.NonNull;
24 | import io.reactivex.ObservableEmitter;
25 | import io.reactivex.ObservableOnSubscribe;
26 | import io.reactivex.disposables.Disposable;
27 |
28 | final class NaviOnSubscribe implements ObservableOnSubscribe{
29 |
30 | final NaviComponent component;
31 |
32 | final Event event;
33 |
34 | NaviOnSubscribe(NaviComponent component, Event event) {
35 | this.component = component;
36 | this.event = event;
37 | }
38 |
39 | @Override public void subscribe(final ObservableEmitter emitter) {
40 | EmitterListener listener = new EmitterListener(emitter);
41 | emitter.setDisposable(listener);
42 | component.addListener(event, listener);
43 | }
44 |
45 | class EmitterListener extends AtomicBoolean implements Listener, Disposable {
46 | final ObservableEmitter emitter;
47 |
48 | public EmitterListener(ObservableEmitter emitter) {
49 | this.emitter = emitter;
50 | }
51 |
52 | @Override public void call(@NonNull T t) {
53 | emitter.onNext(t);
54 | }
55 |
56 | @Override public void dispose() {
57 | if (compareAndSet(false, true)) {
58 | component.removeListener(this);
59 | }
60 | }
61 |
62 | @Override public boolean isDisposed() {
63 | return get();
64 | }
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/navi/src/test/java/com/trello/navi2/EventHandlingTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2;
16 |
17 | import com.trello.navi2.internal.NaviEmitter;
18 | import org.junit.Rule;
19 | import org.junit.Test;
20 | import org.junit.rules.ExpectedException;
21 |
22 | import static junit.framework.Assert.assertFalse;
23 | import static junit.framework.Assert.assertTrue;
24 | import static org.mockito.Mockito.mock;
25 |
26 | public class EventHandlingTest {
27 |
28 | @Rule public final ExpectedException exception = ExpectedException.none();
29 |
30 | @Test public void handlesEventsNone() {
31 | NaviComponent component = NaviEmitter.createActivityEmitter();
32 | assertTrue(component.handlesEvents());
33 | }
34 |
35 | @Test public void handlesEventsSingle() {
36 | NaviComponent component = NaviEmitter.createActivityEmitter();
37 | assertTrue(component.handlesEvents(Event.CREATE));
38 | assertFalse(component.handlesEvents(Event.CREATE_VIEW));
39 | }
40 |
41 | @Test public void handlesEventsMultiple() {
42 | NaviComponent component = NaviEmitter.createActivityEmitter();
43 | assertTrue(component.handlesEvents(Event.CREATE, Event.START, Event.RESUME));
44 | assertFalse(component.handlesEvents(Event.ATTACH, Event.CREATE_VIEW));
45 | assertFalse(component.handlesEvents(Event.CREATE, Event.CREATE_VIEW));
46 | }
47 |
48 | @Test public void throwOnAddUnsupportedListener() {
49 | final NaviEmitter emitter = NaviEmitter.createActivityEmitter();
50 | exception.expect(IllegalArgumentException.class);
51 | emitter.addListener(Event.DETACH, mock(Listener.class));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/navi/src/main/java/com/trello/navi2/internal/HandledEvents.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.internal;
16 |
17 | import com.trello.navi2.Event;
18 | import java.util.Arrays;
19 | import java.util.List;
20 |
21 | /**
22 | * A place to store a common list of handled events by activities and fragments
23 | */
24 | final class HandledEvents {
25 |
26 | static final List> ACTIVITY_EVENTS =
27 | Arrays.asList(
28 | Event.CREATE,
29 | Event.CREATE_PERSISTABLE,
30 | Event.START,
31 | Event.POST_CREATE,
32 | Event.POST_CREATE_PERSISTABLE,
33 | Event.RESUME,
34 | Event.PAUSE,
35 | Event.STOP,
36 | Event.DESTROY,
37 | Event.RESTART,
38 | Event.SAVE_INSTANCE_STATE,
39 | Event.SAVE_INSTANCE_STATE_PERSISTABLE,
40 | Event.RESTORE_INSTANCE_STATE,
41 | Event.RESTORE_INSTANCE_STATE_PERSISTABLE,
42 | Event.NEW_INTENT,
43 | Event.BACK_PRESSED,
44 | Event.ATTACHED_TO_WINDOW,
45 | Event.DETACHED_FROM_WINDOW,
46 | Event.CONFIGURATION_CHANGED,
47 | Event.ACTIVITY_RESULT,
48 | Event.REQUEST_PERMISSIONS_RESULT
49 | );
50 |
51 | static final List> FRAGMENT_EVENTS =
52 | Arrays.asList(
53 | Event.ATTACH,
54 | Event.CREATE,
55 | Event.CREATE_VIEW,
56 | Event.VIEW_CREATED,
57 | Event.ACTIVITY_CREATED,
58 | Event.VIEW_STATE_RESTORED,
59 | Event.START,
60 | Event.RESUME,
61 | Event.PAUSE,
62 | Event.STOP,
63 | Event.DESTROY_VIEW,
64 | Event.DESTROY,
65 | Event.DETACH,
66 | Event.SAVE_INSTANCE_STATE,
67 | Event.CONFIGURATION_CHANGED,
68 | Event.ACTIVITY_RESULT,
69 | Event.REQUEST_PERMISSIONS_RESULT
70 | );
71 |
72 | private HandledEvents() {
73 | throw new AssertionError("No instances!");
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/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 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
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 Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/navi/src/test/java/com/trello/navi2/rx/RxNaviAllEventTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.rx;
16 |
17 | import android.os.Bundle;
18 | import android.os.PersistableBundle;
19 | import com.trello.navi2.Event;
20 | import com.trello.navi2.Event.Type;
21 | import com.trello.navi2.internal.NaviEmitter;
22 | import io.reactivex.observers.TestObserver;
23 | import org.junit.Test;
24 |
25 | import static org.mockito.Mockito.mock;
26 |
27 | public final class RxNaviAllEventTest {
28 |
29 | private final NaviEmitter emitter = NaviEmitter.createActivityEmitter();
30 |
31 | // Test event without listener params works
32 | @Test public void observeAllStart() {
33 | TestObserver testObserver = RxNavi.observe(emitter, Event.ALL).test();
34 | testObserver.assertNoValues();
35 |
36 | emitter.onStart();
37 | testObserver.dispose();
38 | emitter.onStart();
39 |
40 | testObserver.assertValue(Type.START);
41 | testObserver.assertNotTerminated();
42 | }
43 |
44 | // Test event with listener params works
45 | @Test public void observeAllCreate() {
46 | TestObserver testObserver = RxNavi.observe(emitter, Event.ALL).test();
47 | testObserver.assertNoValues();
48 |
49 | Bundle bundle = new Bundle();
50 | emitter.onCreate(bundle);
51 | testObserver.dispose();
52 | emitter.onCreate(bundle);
53 |
54 | testObserver.assertValue(Type.CREATE);
55 | testObserver.assertNotTerminated();
56 | }
57 |
58 | // Test persistable Activities
59 | @Test public void observeAllCreatePersistable() {
60 | TestObserver testObserver = RxNavi.observe(emitter, Event.ALL).test();
61 | testObserver.assertNoValues();
62 |
63 | Bundle bundle = new Bundle();
64 | PersistableBundle persistableBundle = mock(PersistableBundle.class);
65 | emitter.onCreate(bundle);
66 | emitter.onCreate(bundle, persistableBundle);
67 | testObserver.dispose();
68 | emitter.onCreate(bundle);
69 | emitter.onCreate(bundle, persistableBundle);
70 |
71 | testObserver.assertValues(Type.CREATE, Type.CREATE_PERSISTABLE);
72 | testObserver.assertNotTerminated();
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/navi/src/test/java/com/trello/navi2/AllEventTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2;
16 |
17 | import android.os.Bundle;
18 | import android.os.PersistableBundle;
19 | import com.trello.navi2.Event.Type;
20 | import com.trello.navi2.internal.NaviEmitter;
21 | import org.junit.After;
22 | import org.junit.Before;
23 | import org.junit.Test;
24 | import org.mockito.Mock;
25 | import org.mockito.MockitoAnnotations;
26 |
27 | import static org.mockito.Mockito.mock;
28 | import static org.mockito.Mockito.verify;
29 | import static org.mockito.Mockito.verifyNoMoreInteractions;
30 |
31 | public final class AllEventTest {
32 |
33 | private final NaviEmitter emitter = NaviEmitter.createActivityEmitter();
34 |
35 | @Mock Listener listener;
36 |
37 | @Before
38 | public void setUp() {
39 | MockitoAnnotations.initMocks(this);
40 | }
41 |
42 | @After
43 | public void tearDown() {
44 | verifyNoMoreInteractions(listener);
45 | }
46 |
47 | // Test event without listener params works
48 | @Test public void startAllListener() {
49 | emitter.addListener(Event.ALL, listener);
50 |
51 | emitter.onStart();
52 | verify(listener).call(Type.START);
53 |
54 | emitter.removeListener(listener);
55 | emitter.onStart();
56 | }
57 |
58 | // Test event with listener params works
59 | @Test public void createAllListener() {
60 | emitter.addListener(Event.ALL, listener);
61 |
62 | Bundle bundle = new Bundle();
63 | emitter.onCreate(bundle);
64 | verify(listener).call(Type.CREATE);
65 |
66 | emitter.removeListener(listener);
67 | emitter.onCreate(bundle);
68 | }
69 |
70 | // Test persistable Activities
71 | @Test public void createPersistableListener() {
72 | emitter.addListener(Event.ALL, listener);
73 |
74 | Bundle bundle = new Bundle();
75 | PersistableBundle persistableBundle = mock(PersistableBundle.class);
76 | emitter.onCreate(bundle);
77 | emitter.onCreate(bundle, persistableBundle);
78 | verify(listener).call(Type.CREATE);
79 | verify(listener).call(Type.CREATE_PERSISTABLE);
80 |
81 | emitter.removeListener(listener);
82 | emitter.onCreate(bundle, persistableBundle);
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/sample/src/main/java/com/trello/navi2/sample/MainActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Licensed under the Apache License, Version 2.0 (the "License");
3 | * you may not use this file except in compliance with the License.
4 | * You may obtain a copy of the License at
5 | *
6 | * http://www.apache.org/licenses/LICENSE-2.0
7 | *
8 | * Unless required by applicable law or agreed to in writing, software
9 | * distributed under the License is distributed on an "AS IS" BASIS,
10 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 | * See the License for the specific language governing permissions and
12 | * limitations under the License.
13 | */
14 |
15 | package com.trello.navi2.sample;
16 |
17 | import android.os.Bundle;
18 | import android.widget.TextView;
19 | import com.trello.navi2.Event;
20 | import com.trello.navi2.NaviComponent;
21 | import com.trello.navi2.component.support.NaviAppCompatActivity;
22 | import com.trello.navi2.rx.RxNavi;
23 | import io.reactivex.Observable;
24 | import io.reactivex.android.schedulers.AndroidSchedulers;
25 | import io.reactivex.functions.Consumer;
26 | import io.reactivex.functions.Function;
27 | import java.util.concurrent.TimeUnit;
28 |
29 | /**
30 | * Tiny sample.
31 | *
32 | * Don't take this too seriously. This is just a fraction of what could be done with Navi.
33 | */
34 | public class MainActivity extends NaviAppCompatActivity {
35 |
36 | // This demonstrates we don't necessarily need a reference to the Activity itself in order
37 | // to hook into its lifecycle; the NaviActivity could be provided by anyone.
38 | private final NaviComponent naviComponent = this;
39 |
40 | TextView counter;
41 |
42 | public MainActivity() {
43 | // Instead of using onCreate, we can use Observables
44 | RxNavi.observe(naviComponent, Event.CREATE).subscribe(new Consumer() {
45 | @Override public void accept(Bundle bundle) throws Exception {
46 | setContentView(R.layout.main);
47 | counter = (TextView) findViewById(R.id.counter);
48 | }
49 | });
50 |
51 | // Counter that operates on screen only while resumed; automatically ends itself on destroy
52 | RxNavi.observe(naviComponent, Event.RESUME)
53 | .flatMap(new Function