Browse Source

Initial back button implementation

Guy Carmeli 8 years ago
parent
commit
a8710e7089

+ 22
- 4
android/app/src/main/java/com/reactnativenavigation/activities/BaseReactActivity.java View File

@@ -5,6 +5,7 @@ import android.os.Build;
5 5
 import android.os.Bundle;
6 6
 import android.os.Handler;
7 7
 import android.provider.Settings;
8
+import android.support.annotation.CallSuper;
8 9
 import android.support.v7.app.AppCompatActivity;
9 10
 import android.util.Log;
10 11
 import android.view.KeyEvent;
@@ -25,6 +26,7 @@ import com.reactnativenavigation.core.RctManager;
25 26
 import com.reactnativenavigation.core.objects.Screen;
26 27
 import com.reactnativenavigation.packages.RnnPackage;
27 28
 import com.reactnativenavigation.utils.ContextProvider;
29
+import com.reactnativenavigation.views.RnnToolBar;
28 30
 
29 31
 import java.util.Arrays;
30 32
 import java.util.List;
@@ -45,6 +47,7 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
45 47
     private LifecycleState mLifecycleState = LifecycleState.BEFORE_RESUME;
46 48
     private boolean mDoRefresh = false;
47 49
     private Menu mMenu;
50
+    protected RnnToolBar mToolbar;
48 51
 
49 52
     /**
50 53
      * Returns the name of the bundle in assets. If this is null, and no file path is specified for
@@ -203,11 +206,26 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
203 206
         }
204 207
     }
205 208
 
206
-    public abstract void push(Screen screen);
209
+    @CallSuper
210
+    public void push(Screen screen) {
211
+        if (mToolbar != null &&
212
+            getCurrentNavigatorId().equals(screen.navigatorId) &&
213
+            getScreenStackSize() >= 1) {
214
+            mToolbar.showBackButton();
215
+        }
216
+    }
207 217
 
208
-    public abstract Screen pop(String navID);
218
+    @CallSuper
219
+    public Screen pop(String navigatorId) {
220
+        if (mToolbar != null &&
221
+            getCurrentNavigatorId().equals(navigatorId) &&
222
+            getScreenStackSize() <= 2) {
223
+            mToolbar.hideBackButton();
224
+        }
225
+        return null;
226
+    }
209 227
 
210
-    public abstract String getActiveNavigatorID();
228
+    public abstract String getCurrentNavigatorId();
211 229
 
212 230
     public abstract int getScreenStackSize();
213 231
 
@@ -260,7 +278,7 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
260 278
     @Override
261 279
     public void onBackPressed() {
262 280
         if (getScreenStackSize() > 1) {
263
-            pop(getActiveNavigatorID());
281
+            pop(getCurrentNavigatorId());
264 282
         } else {
265 283
             if (mReactInstanceManager != null) {
266 284
                 mReactInstanceManager.onBackPressed();

+ 2
- 2
android/app/src/main/java/com/reactnativenavigation/activities/RootActivity.java View File

@@ -32,12 +32,12 @@ public class RootActivity extends BaseReactActivity {
32 32
     }
33 33
 
34 34
     @Override
35
-    public Screen pop(String navID) {
35
+    public Screen pop(String navigatorId) {
36 36
         return null;
37 37
     }
38 38
 
39 39
     @Override
40
-    public String getActiveNavigatorID() {
40
+    public String getCurrentNavigatorId() {
41 41
         return null;
42 42
     }
43 43
 

+ 16
- 14
android/app/src/main/java/com/reactnativenavigation/activities/SingleScreenActivity.java View File

@@ -16,9 +16,8 @@ public class SingleScreenActivity extends BaseReactActivity {
16 16
     public static final String EXTRA_SCREEN = "extraScreen";
17 17
 
18 18
     private Toolbar mToolbar;
19
-    private FrameLayout mContentFrame;
20
-    private ScreenStack screenStack;
21
-    private String navID;
19
+    private ScreenStack mScreenStack;
20
+    private String mNavigatorId;
22 21
 
23 22
     @Override
24 23
     protected void handleOnCreate() {
@@ -26,38 +25,41 @@ public class SingleScreenActivity extends BaseReactActivity {
26 25
 
27 26
         setContentView(R.layout.single_screen_activity);
28 27
         mToolbar = (Toolbar) findViewById(R.id.toolbar);
29
-        mContentFrame = (FrameLayout) findViewById(R.id.contentFrame);
30 28
 
31 29
         Screen screen = (Screen) getIntent().getSerializableExtra(EXTRA_SCREEN);
32
-        navID = screen.navigatorId;
30
+        mNavigatorId = screen.navigatorId;
33 31
         setupToolbar(screen.title);
34 32
 
35
-        screenStack = new ScreenStack(this);
36
-        mContentFrame.addView(screenStack);
37
-        screenStack.push(screen);
33
+        mScreenStack = new ScreenStack(this);
34
+        FrameLayout contentFrame = (FrameLayout) findViewById(R.id.contentFrame);
35
+        contentFrame.addView(mScreenStack);
36
+        mScreenStack.push(screen);
38 37
     }
39 38
 
40 39
     private void setupToolbar(String title) {
41 40
         mToolbar.setTitle(title);
41
+        setSupportActionBar(mToolbar);
42 42
     }
43 43
     
44 44
     @Override
45 45
     public void push(Screen screen) {
46
-        screenStack.push(screen);
46
+        super.push(screen);
47
+        mScreenStack.push(screen);
47 48
     }
48 49
 
49 50
     @Override
50
-    public Screen pop(String navID) {
51
-        return screenStack.pop();
51
+    public Screen pop(String navigatorId) {
52
+        super.pop(navigatorId);
53
+        return mScreenStack.pop();
52 54
     }
53 55
 
54 56
     @Override
55
-    public String getActiveNavigatorID() {
56
-        return navID;
57
+    public String getCurrentNavigatorId() {
58
+        return mNavigatorId;
57 59
     }
58 60
 
59 61
     @Override
60 62
     public int getScreenStackSize() {
61
-        return screenStack.getStackSize();
63
+        return mScreenStack.getStackSize();
62 64
     }
63 65
 }

+ 20
- 19
android/app/src/main/java/com/reactnativenavigation/activities/TabActivity.java View File

@@ -18,12 +18,11 @@ import java.util.ArrayList;
18 18
 public class TabActivity extends BaseReactActivity {
19 19
     public static final String EXTRA_SCREENS = "extraScreens";
20 20
 
21
-    private RnnToolBar mToolbar;
22 21
     private TabLayout mTabLayout;
23 22
     private ViewPager mViewPager;
24 23
 
25 24
     private ArrayList<Screen> mScreens;
26
-    private ViewPagerAdapter adapter;
25
+    private ViewPagerAdapter mAdapter;
27 26
 
28 27
     @Override
29 28
     protected void handleOnCreate() {
@@ -40,27 +39,17 @@ public class TabActivity extends BaseReactActivity {
40 39
         setupViewPager();
41 40
     }
42 41
 
43
-    @Override
44
-    public void push(Screen screen) {
45
-        adapter.pushScreen(screen);
46
-    }
47
-
48
-    @Override
49
-    public Screen pop(String navID) {
50
-        return adapter.pop(navID);
51
-    }
52
-
53 42
     private void setupToolbar() {
54 43
         setSupportActionBar(mToolbar);
55 44
         mToolbar.setScreens(mScreens);
56 45
     }
57 46
 
58 47
     private void setupViewPager() {
59
-        adapter = new ViewPagerAdapter(this, mViewPager, mToolbar, mScreens);
60
-        mViewPager.setAdapter(adapter);
48
+        mAdapter = new ViewPagerAdapter(this, mViewPager, mToolbar, mScreens);
49
+        mViewPager.setAdapter(mAdapter);
61 50
         mTabLayout.setupWithViewPager(mViewPager);
62
-        mTabLayout.setOnTabSelectedListener(adapter);
63
-        adapter.notifyDataSetChanged();
51
+        mTabLayout.setOnTabSelectedListener(mAdapter);
52
+        mAdapter.notifyDataSetChanged();
64 53
     }
65 54
 
66 55
     @Override
@@ -71,12 +60,24 @@ public class TabActivity extends BaseReactActivity {
71 60
     }
72 61
 
73 62
     @Override
74
-    public String getActiveNavigatorID() {
75
-        return adapter.getNavID(mViewPager.getCurrentItem());
63
+    public void push(Screen screen) {
64
+        super.push(screen);
65
+        mAdapter.push(screen);
66
+    }
67
+
68
+    @Override
69
+    public Screen pop(String navigatorId) {
70
+        super.pop(navigatorId);
71
+        return mAdapter.pop(navigatorId);
72
+    }
73
+
74
+    @Override
75
+    public String getCurrentNavigatorId() {
76
+        return mAdapter.getNavigatorId(mViewPager.getCurrentItem());
76 77
     }
77 78
 
78 79
     @Override
79 80
     public int getScreenStackSize() {
80
-        return adapter.getStackSizeForNavigatorId(getActiveNavigatorID());
81
+        return mAdapter.getStackSizeForNavigatorId(getCurrentNavigatorId());
81 82
     }
82 83
 }

+ 23
- 27
android/app/src/main/java/com/reactnativenavigation/adapters/ViewPagerAdapter.java View File

@@ -27,43 +27,40 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
27 27
 
28 28
     private ViewPager mViewPager;
29 29
     private RnnToolBar mToolbar;
30
-    private final ArrayList<ScreenStack> screenStacks;
31
-    private final ArrayList<String> navIDs;
32
-    private final Map<String, ScreenStack> stacksByNavId;
30
+    private final ArrayList<ScreenStack> mScreenStacks;
31
+    private final ArrayList<String> mNavigatorIds;
32
+    private final Map<String, ScreenStack> mStackByNavigatorId;
33 33
 
34 34
 
35 35
     public ViewPagerAdapter(BaseReactActivity context, ViewPager viewPager, RnnToolBar toolbar,
36 36
                             ArrayList<Screen> screens) {
37 37
         mViewPager = viewPager;
38 38
         mToolbar = toolbar;
39
-        screenStacks = new ArrayList<>();
40
-        navIDs = new ArrayList<>();
41
-        stacksByNavId = new HashMap<>();
39
+        mScreenStacks = new ArrayList<>();
40
+        mNavigatorIds = new ArrayList<>();
41
+        mStackByNavigatorId = new HashMap<>();
42 42
         for (Screen screen : screens) {
43 43
             ScreenStack stack = new ScreenStack(context);
44 44
             stack.push(screen);
45
-            screenStacks.add(stack);
46
-            navIDs.add(screen.navigatorId);
47
-            stacksByNavId.put(screen.navigatorId, stack);
45
+            mScreenStacks.add(stack);
46
+            mNavigatorIds.add(screen.navigatorId);
47
+            mStackByNavigatorId.put(screen.navigatorId, stack);
48 48
         }
49 49
     }
50 50
 
51
-    public void pushScreen(Screen screen) {
52
-        ScreenStack stack = stacksByNavId.get(screen.navigatorId);
51
+    public void push(Screen screen) {
52
+        ScreenStack stack = mStackByNavigatorId.get(screen.navigatorId);
53 53
         stack.push(screen);
54 54
     }
55 55
 
56
-    public Screen pop(String navID) {
57
-        ScreenStack stack = stacksByNavId.get(navID);
58
-        if (stack != null) {
59
-            return stack.pop();
60
-        }
61
-        return null;
56
+    public Screen pop(String navigatorId) {
57
+        ScreenStack stack = mStackByNavigatorId.get(navigatorId);
58
+        return stack != null ? stack.pop() : null;
62 59
     }
63 60
 
64 61
     @Override
65 62
     public Object instantiateItem(ViewGroup container, int position) {
66
-        ScreenStack view = screenStacks.get(position);
63
+        ScreenStack view = mScreenStacks.get(position);
67 64
         container.addView(view);
68 65
         return view;
69 66
     }
@@ -75,7 +72,7 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
75 72
 
76 73
     @Override
77 74
     public int getCount() {
78
-        return screenStacks.size();
75
+        return mScreenStacks.size();
79 76
     }
80 77
 
81 78
     @Override
@@ -85,7 +82,7 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
85 82
 
86 83
     @Override
87 84
     public CharSequence getPageTitle(int position) {
88
-        return screenStacks.get(position).peek().title;
85
+        return mScreenStacks.get(position).peek().title;
89 86
     }
90 87
 
91 88
     @Override
@@ -94,13 +91,12 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
94 91
         int position = tab.getPosition();
95 92
         mViewPager.setCurrentItem(position);
96 93
 
94
+        mToolbar.setupToolbarButtonsAsync(mScreenStacks.get(position).peek());
95
+
97 96
         // Send tab selected event
98 97
         WritableMap params = Arguments.createMap();
99
-        Screen screen = screenStacks.get(position).peek();
98
+        Screen screen = mScreenStacks.get(position).peek();
100 99
         params.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
101
-
102
-        mToolbar.setupToolbarButtonsAsync(screenStacks.get(position).peek());
103
-
104 100
         RctManager.getInstance().sendEvent(EVENT_ON_TAB_SELECTED, screen.navigatorEventId, params);
105 101
     }
106 102
 
@@ -114,11 +110,11 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
114 110
 
115 111
     }
116 112
 
117
-    public String getNavID(int position) {
118
-        return navIDs.get(position);
113
+    public String getNavigatorId(int position) {
114
+        return mNavigatorIds.get(position);
119 115
     }
120 116
 
121 117
     public int getStackSizeForNavigatorId(String activeNavigatorID) {
122
-        return stacksByNavId.get(activeNavigatorID).getStackSize();
118
+        return mStackByNavigatorId.get(activeNavigatorID).getStackSize();
123 119
     }
124 120
 }

+ 10
- 0
android/app/src/main/java/com/reactnativenavigation/views/RnnToolBar.java View File

@@ -53,6 +53,16 @@ public class RnnToolBar extends Toolbar {
53 53
         }
54 54
     }
55 55
 
56
+    @SuppressWarnings({"ConstantConditions"})
57
+    public void showBackButton() {
58
+        ContextProvider.getActivityContext().getSupportActionBar().setDisplayHomeAsUpEnabled(true);
59
+    }
60
+
61
+    @SuppressWarnings({"ConstantConditions"})
62
+    public void hideBackButton() {
63
+        ContextProvider.getActivityContext().getSupportActionBar().setDisplayHomeAsUpEnabled(false);
64
+    }
65
+
56 66
     private static class SetupToolbarButtonsTask extends AsyncTask<Void, Void, Map<String, Drawable>> {
57 67
         private final List<Button> mButtons;
58 68
         private final WeakReference<RnnToolBar> mToolbarWR;

+ 15
- 15
android/app/src/main/java/com/reactnativenavigation/views/ScreenStack.java View File

@@ -16,7 +16,7 @@ import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
16 16
 
17 17
 public class ScreenStack extends FrameLayout {
18 18
 
19
-    private class ScreenView {
19
+    private static class ScreenView {
20 20
         Screen screen;
21 21
         RctView view;
22 22
 
@@ -26,39 +26,39 @@ public class ScreenStack extends FrameLayout {
26 26
         }
27 27
     }
28 28
 
29
-    private final Stack<ScreenView> stack = new Stack<>();
29
+    private final Stack<ScreenView> mStack = new Stack<>();
30 30
     private final ReactInstanceManager mReactInstanceManager =
31 31
             RctManager.getInstance().getReactInstanceManager();
32
-    private final BaseReactActivity reactActivity;
32
+    private final BaseReactActivity mReactActivity;
33 33
 
34 34
     public ScreenStack(BaseReactActivity context) {
35 35
         super(context);
36
-        reactActivity = context;
36
+        mReactActivity = context;
37 37
         setLayoutTransition(new LayoutTransition());
38 38
     }
39 39
 
40 40
     public void push(Screen screen) {
41 41
         RctView oldView = null;
42
-        if (!stack.isEmpty()) {
43
-            oldView = stack.peek().view;
42
+        if (!mStack.isEmpty()) {
43
+            oldView = mStack.peek().view;
44 44
         }
45
-        RctView view = new RctView(reactActivity, mReactInstanceManager, screen);
45
+        RctView view = new RctView(mReactActivity, mReactInstanceManager, screen);
46 46
         addView(view, MATCH_PARENT, MATCH_PARENT);
47 47
         if (oldView != null) {
48 48
             ReactRootView reactRootView = oldView.getReactRootView();
49 49
             ReflectionUtils.setBooleanField(reactRootView, "mAttachScheduled", true);
50 50
             removeView(oldView);
51 51
         }
52
-        stack.push(new ScreenView(screen, view));
52
+        mStack.push(new ScreenView(screen, view));
53 53
     }
54 54
 
55 55
     public Screen pop() {
56
-        if (stack.isEmpty()) {
56
+        if (mStack.isEmpty()) {
57 57
             return null;
58 58
         }
59
-        ScreenView popped = stack.pop();
60
-        if (!stack.isEmpty()) {
61
-            addView(stack.peek().view, 0);
59
+        ScreenView popped = mStack.pop();
60
+        if (!mStack.isEmpty()) {
61
+            addView(mStack.peek().view, 0);
62 62
         }
63 63
 
64 64
         ReflectionUtils.setBooleanField(popped.view.getReactRootView(), "mAttachScheduled", false);
@@ -67,14 +67,14 @@ public class ScreenStack extends FrameLayout {
67 67
     }
68 68
 
69 69
     public boolean isEmpty() {
70
-        return stack.isEmpty();
70
+        return mStack.isEmpty();
71 71
     }
72 72
 
73 73
     public int getStackSize() {
74
-        return stack.size();
74
+        return mStack.size();
75 75
     }
76 76
 
77 77
     public Screen peek() {
78
-        return stack.peek().screen;
78
+        return mStack.peek().screen;
79 79
     }
80 80
 }