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
 import android.os.Bundle;
5
 import android.os.Bundle;
6
 import android.os.Handler;
6
 import android.os.Handler;
7
 import android.provider.Settings;
7
 import android.provider.Settings;
8
+import android.support.annotation.CallSuper;
8
 import android.support.v7.app.AppCompatActivity;
9
 import android.support.v7.app.AppCompatActivity;
9
 import android.util.Log;
10
 import android.util.Log;
10
 import android.view.KeyEvent;
11
 import android.view.KeyEvent;
25
 import com.reactnativenavigation.core.objects.Screen;
26
 import com.reactnativenavigation.core.objects.Screen;
26
 import com.reactnativenavigation.packages.RnnPackage;
27
 import com.reactnativenavigation.packages.RnnPackage;
27
 import com.reactnativenavigation.utils.ContextProvider;
28
 import com.reactnativenavigation.utils.ContextProvider;
29
+import com.reactnativenavigation.views.RnnToolBar;
28
 
30
 
29
 import java.util.Arrays;
31
 import java.util.Arrays;
30
 import java.util.List;
32
 import java.util.List;
45
     private LifecycleState mLifecycleState = LifecycleState.BEFORE_RESUME;
47
     private LifecycleState mLifecycleState = LifecycleState.BEFORE_RESUME;
46
     private boolean mDoRefresh = false;
48
     private boolean mDoRefresh = false;
47
     private Menu mMenu;
49
     private Menu mMenu;
50
+    protected RnnToolBar mToolbar;
48
 
51
 
49
     /**
52
     /**
50
      * Returns the name of the bundle in assets. If this is null, and no file path is specified for
53
      * Returns the name of the bundle in assets. If this is null, and no file path is specified for
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
     public abstract int getScreenStackSize();
230
     public abstract int getScreenStackSize();
213
 
231
 
260
     @Override
278
     @Override
261
     public void onBackPressed() {
279
     public void onBackPressed() {
262
         if (getScreenStackSize() > 1) {
280
         if (getScreenStackSize() > 1) {
263
-            pop(getActiveNavigatorID());
281
+            pop(getCurrentNavigatorId());
264
         } else {
282
         } else {
265
             if (mReactInstanceManager != null) {
283
             if (mReactInstanceManager != null) {
266
                 mReactInstanceManager.onBackPressed();
284
                 mReactInstanceManager.onBackPressed();

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

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

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

16
     public static final String EXTRA_SCREEN = "extraScreen";
16
     public static final String EXTRA_SCREEN = "extraScreen";
17
 
17
 
18
     private Toolbar mToolbar;
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
     @Override
22
     @Override
24
     protected void handleOnCreate() {
23
     protected void handleOnCreate() {
26
 
25
 
27
         setContentView(R.layout.single_screen_activity);
26
         setContentView(R.layout.single_screen_activity);
28
         mToolbar = (Toolbar) findViewById(R.id.toolbar);
27
         mToolbar = (Toolbar) findViewById(R.id.toolbar);
29
-        mContentFrame = (FrameLayout) findViewById(R.id.contentFrame);
30
 
28
 
31
         Screen screen = (Screen) getIntent().getSerializableExtra(EXTRA_SCREEN);
29
         Screen screen = (Screen) getIntent().getSerializableExtra(EXTRA_SCREEN);
32
-        navID = screen.navigatorId;
30
+        mNavigatorId = screen.navigatorId;
33
         setupToolbar(screen.title);
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
     private void setupToolbar(String title) {
39
     private void setupToolbar(String title) {
41
         mToolbar.setTitle(title);
40
         mToolbar.setTitle(title);
41
+        setSupportActionBar(mToolbar);
42
     }
42
     }
43
     
43
     
44
     @Override
44
     @Override
45
     public void push(Screen screen) {
45
     public void push(Screen screen) {
46
-        screenStack.push(screen);
46
+        super.push(screen);
47
+        mScreenStack.push(screen);
47
     }
48
     }
48
 
49
 
49
     @Override
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
     @Override
56
     @Override
55
-    public String getActiveNavigatorID() {
56
-        return navID;
57
+    public String getCurrentNavigatorId() {
58
+        return mNavigatorId;
57
     }
59
     }
58
 
60
 
59
     @Override
61
     @Override
60
     public int getScreenStackSize() {
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
 public class TabActivity extends BaseReactActivity {
18
 public class TabActivity extends BaseReactActivity {
19
     public static final String EXTRA_SCREENS = "extraScreens";
19
     public static final String EXTRA_SCREENS = "extraScreens";
20
 
20
 
21
-    private RnnToolBar mToolbar;
22
     private TabLayout mTabLayout;
21
     private TabLayout mTabLayout;
23
     private ViewPager mViewPager;
22
     private ViewPager mViewPager;
24
 
23
 
25
     private ArrayList<Screen> mScreens;
24
     private ArrayList<Screen> mScreens;
26
-    private ViewPagerAdapter adapter;
25
+    private ViewPagerAdapter mAdapter;
27
 
26
 
28
     @Override
27
     @Override
29
     protected void handleOnCreate() {
28
     protected void handleOnCreate() {
40
         setupViewPager();
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
     private void setupToolbar() {
42
     private void setupToolbar() {
54
         setSupportActionBar(mToolbar);
43
         setSupportActionBar(mToolbar);
55
         mToolbar.setScreens(mScreens);
44
         mToolbar.setScreens(mScreens);
56
     }
45
     }
57
 
46
 
58
     private void setupViewPager() {
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
         mTabLayout.setupWithViewPager(mViewPager);
50
         mTabLayout.setupWithViewPager(mViewPager);
62
-        mTabLayout.setOnTabSelectedListener(adapter);
63
-        adapter.notifyDataSetChanged();
51
+        mTabLayout.setOnTabSelectedListener(mAdapter);
52
+        mAdapter.notifyDataSetChanged();
64
     }
53
     }
65
 
54
 
66
     @Override
55
     @Override
71
     }
60
     }
72
 
61
 
73
     @Override
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
     @Override
79
     @Override
79
     public int getScreenStackSize() {
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
 
27
 
28
     private ViewPager mViewPager;
28
     private ViewPager mViewPager;
29
     private RnnToolBar mToolbar;
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
     public ViewPagerAdapter(BaseReactActivity context, ViewPager viewPager, RnnToolBar toolbar,
35
     public ViewPagerAdapter(BaseReactActivity context, ViewPager viewPager, RnnToolBar toolbar,
36
                             ArrayList<Screen> screens) {
36
                             ArrayList<Screen> screens) {
37
         mViewPager = viewPager;
37
         mViewPager = viewPager;
38
         mToolbar = toolbar;
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
         for (Screen screen : screens) {
42
         for (Screen screen : screens) {
43
             ScreenStack stack = new ScreenStack(context);
43
             ScreenStack stack = new ScreenStack(context);
44
             stack.push(screen);
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
         stack.push(screen);
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
     @Override
61
     @Override
65
     public Object instantiateItem(ViewGroup container, int position) {
62
     public Object instantiateItem(ViewGroup container, int position) {
66
-        ScreenStack view = screenStacks.get(position);
63
+        ScreenStack view = mScreenStacks.get(position);
67
         container.addView(view);
64
         container.addView(view);
68
         return view;
65
         return view;
69
     }
66
     }
75
 
72
 
76
     @Override
73
     @Override
77
     public int getCount() {
74
     public int getCount() {
78
-        return screenStacks.size();
75
+        return mScreenStacks.size();
79
     }
76
     }
80
 
77
 
81
     @Override
78
     @Override
85
 
82
 
86
     @Override
83
     @Override
87
     public CharSequence getPageTitle(int position) {
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
     @Override
88
     @Override
94
         int position = tab.getPosition();
91
         int position = tab.getPosition();
95
         mViewPager.setCurrentItem(position);
92
         mViewPager.setCurrentItem(position);
96
 
93
 
94
+        mToolbar.setupToolbarButtonsAsync(mScreenStacks.get(position).peek());
95
+
97
         // Send tab selected event
96
         // Send tab selected event
98
         WritableMap params = Arguments.createMap();
97
         WritableMap params = Arguments.createMap();
99
-        Screen screen = screenStacks.get(position).peek();
98
+        Screen screen = mScreenStacks.get(position).peek();
100
         params.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
99
         params.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
101
-
102
-        mToolbar.setupToolbarButtonsAsync(screenStacks.get(position).peek());
103
-
104
         RctManager.getInstance().sendEvent(EVENT_ON_TAB_SELECTED, screen.navigatorEventId, params);
100
         RctManager.getInstance().sendEvent(EVENT_ON_TAB_SELECTED, screen.navigatorEventId, params);
105
     }
101
     }
106
 
102
 
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
     public int getStackSizeForNavigatorId(String activeNavigatorID) {
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
         }
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
     private static class SetupToolbarButtonsTask extends AsyncTask<Void, Void, Map<String, Drawable>> {
66
     private static class SetupToolbarButtonsTask extends AsyncTask<Void, Void, Map<String, Drawable>> {
57
         private final List<Button> mButtons;
67
         private final List<Button> mButtons;
58
         private final WeakReference<RnnToolBar> mToolbarWR;
68
         private final WeakReference<RnnToolBar> mToolbarWR;

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

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