Browse Source

Send toolbar button click events

Guy Carmeli 8 years ago
parent
commit
1d42d3ff20

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

10
 import android.util.Log;
10
 import android.util.Log;
11
 import android.view.KeyEvent;
11
 import android.view.KeyEvent;
12
 import android.view.Menu;
12
 import android.view.Menu;
13
+import android.view.MenuItem;
13
 import android.widget.EditText;
14
 import android.widget.EditText;
14
 import android.widget.Toast;
15
 import android.widget.Toast;
15
 
16
 
18
 import com.facebook.react.ReactInstanceManager;
19
 import com.facebook.react.ReactInstanceManager;
19
 import com.facebook.react.ReactPackage;
20
 import com.facebook.react.ReactPackage;
20
 import com.facebook.react.ReactRootView;
21
 import com.facebook.react.ReactRootView;
22
+import com.facebook.react.bridge.Arguments;
23
+import com.facebook.react.bridge.WritableMap;
21
 import com.facebook.react.common.ReactConstants;
24
 import com.facebook.react.common.ReactConstants;
22
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
25
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
23
 import com.facebook.react.shell.MainReactPackage;
26
 import com.facebook.react.shell.MainReactPackage;
24
 import com.reactnativenavigation.BuildConfig;
27
 import com.reactnativenavigation.BuildConfig;
25
 import com.reactnativenavigation.core.RctManager;
28
 import com.reactnativenavigation.core.RctManager;
29
+import com.reactnativenavigation.core.objects.Button;
26
 import com.reactnativenavigation.core.objects.Screen;
30
 import com.reactnativenavigation.core.objects.Screen;
27
 import com.reactnativenavigation.packages.RnnPackage;
31
 import com.reactnativenavigation.packages.RnnPackage;
28
 import com.reactnativenavigation.utils.ContextProvider;
32
 import com.reactnativenavigation.utils.ContextProvider;
41
     private static final String TAG = "BaseReactActivity";
45
     private static final String TAG = "BaseReactActivity";
42
     private static final String REDBOX_PERMISSION_MESSAGE =
46
     private static final String REDBOX_PERMISSION_MESSAGE =
43
             "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
47
             "Overlay permissions needs to be granted in order for react native apps to run in dev mode";
48
+    private static final String EVENT_TOOLBAR_BUTTON_CLICKED = "OnToolbarButtonClicked";
44
 
49
 
45
     @Nullable
50
     @Nullable
46
     protected ReactInstanceManager mReactInstanceManager;
51
     protected ReactInstanceManager mReactInstanceManager;
225
         return null;
230
         return null;
226
     }
231
     }
227
 
232
 
228
-    public abstract String getCurrentNavigatorId();
233
+    protected abstract String getCurrentNavigatorId();
234
+
235
+    protected abstract Screen getCurrentScreen();
229
 
236
 
230
     public abstract int getScreenStackSize();
237
     public abstract int getScreenStackSize();
231
 
238
 
235
         return super.onCreateOptionsMenu(menu);
242
         return super.onCreateOptionsMenu(menu);
236
     }
243
     }
237
 
244
 
245
+    @Override
246
+    public boolean onOptionsItemSelected(MenuItem item) {
247
+        if (item.getItemId() == android.R.id.home) {
248
+            onBackPressed();
249
+        } else {
250
+            String eventId = Button.getButtonEventId(item);
251
+            assert eventId != null;
252
+
253
+            WritableMap params = Arguments.createMap();
254
+            RctManager.getInstance().sendEvent(eventId, getCurrentScreen(), params);
255
+        }
256
+        return super.onOptionsItemSelected(item);
257
+    }
258
+
238
     public Menu getMenu() {
259
     public Menu getMenu() {
239
         return mMenu;
260
         return mMenu;
240
     }
261
     }

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

28
      // No need to implement stack interface since this activity is only used to start other
28
      // No need to implement stack interface since this activity is only used to start other
29
     // activities such as TabActivity or SingleScreenActivity.
29
     // activities such as TabActivity or SingleScreenActivity.
30
     @Override
30
     @Override
31
-    public void push(Screen screen) {
32
-    }
33
-
34
-    @Override
35
-    public Screen pop(String navigatorId) {
31
+    protected Screen getCurrentScreen() {
36
         return null;
32
         return null;
37
     }
33
     }
38
 
34
 

+ 5
- 0
android/app/src/main/java/com/reactnativenavigation/activities/SingleScreenActivity.java View File

58
         return mNavigatorId;
58
         return mNavigatorId;
59
     }
59
     }
60
 
60
 
61
+    @Override
62
+    protected Screen getCurrentScreen() {
63
+        return mScreenStack.peek();
64
+    }
65
+
61
     @Override
66
     @Override
62
     public int getScreenStackSize() {
67
     public int getScreenStackSize() {
63
         return mScreenStack.getStackSize();
68
         return mScreenStack.getStackSize();

+ 13
- 10
android/app/src/main/java/com/reactnativenavigation/activities/TabActivity.java View File

20
 
20
 
21
     private TabLayout mTabLayout;
21
     private TabLayout mTabLayout;
22
     private ViewPager mViewPager;
22
     private ViewPager mViewPager;
23
-
24
-    private ArrayList<Screen> mScreens;
25
     private ViewPagerAdapter mAdapter;
23
     private ViewPagerAdapter mAdapter;
26
 
24
 
27
     @Override
25
     @Override
33
         mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
31
         mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
34
         mViewPager = (ViewPager) findViewById(R.id.viewPager);
32
         mViewPager = (ViewPager) findViewById(R.id.viewPager);
35
 
33
 
36
-        mScreens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
34
+        ArrayList<Screen> screens = (ArrayList<Screen>) getIntent().getSerializableExtra(EXTRA_SCREENS);
37
 
35
 
38
-        setupToolbar();
39
-        setupViewPager();
36
+        setupToolbar(screens);
37
+        setupViewPager(screens);
40
     }
38
     }
41
 
39
 
42
-    private void setupToolbar() {
40
+    private void setupToolbar(ArrayList<Screen> screens) {
43
         setSupportActionBar(mToolbar);
41
         setSupportActionBar(mToolbar);
44
-        mToolbar.setScreens(mScreens);
42
+        mToolbar.setScreens(screens);
45
     }
43
     }
46
 
44
 
47
-    private void setupViewPager() {
48
-        mAdapter = new ViewPagerAdapter(this, mViewPager, mToolbar, mScreens);
45
+    private void setupViewPager(ArrayList<Screen> screens) {
46
+        mAdapter = new ViewPagerAdapter(this, mViewPager, mToolbar, screens);
49
         mViewPager.setAdapter(mAdapter);
47
         mViewPager.setAdapter(mAdapter);
50
         mTabLayout.setupWithViewPager(mViewPager);
48
         mTabLayout.setupWithViewPager(mViewPager);
51
         mTabLayout.setOnTabSelectedListener(mAdapter);
49
         mTabLayout.setOnTabSelectedListener(mAdapter);
72
     }
70
     }
73
 
71
 
74
     @Override
72
     @Override
75
-    public String getCurrentNavigatorId() {
73
+    protected Screen getCurrentScreen() {
74
+        return mAdapter.peek(getCurrentNavigatorId());
75
+    }
76
+
77
+    @Override
78
+    protected String getCurrentNavigatorId() {
76
         return mAdapter.getNavigatorId(mViewPager.getCurrentItem());
79
         return mAdapter.getNavigatorId(mViewPager.getCurrentItem());
77
     }
80
     }
78
 
81
 

+ 6
- 2
android/app/src/main/java/com/reactnativenavigation/adapters/ViewPagerAdapter.java View File

58
         return stack != null ? stack.pop() : null;
58
         return stack != null ? stack.pop() : null;
59
     }
59
     }
60
 
60
 
61
+    public Screen peek(String navigatorId) {
62
+        ScreenStack stack = mStackByNavigatorId.get(navigatorId);
63
+        return stack != null ? stack.peek() : null;
64
+    }
65
+
61
     @Override
66
     @Override
62
     public Object instantiateItem(ViewGroup container, int position) {
67
     public Object instantiateItem(ViewGroup container, int position) {
63
         ScreenStack view = mScreenStacks.get(position);
68
         ScreenStack view = mScreenStacks.get(position);
96
         // Send tab selected event
101
         // Send tab selected event
97
         WritableMap params = Arguments.createMap();
102
         WritableMap params = Arguments.createMap();
98
         Screen screen = mScreenStacks.get(position).peek();
103
         Screen screen = mScreenStacks.get(position).peek();
99
-        params.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
100
-        RctManager.getInstance().sendEvent(EVENT_ON_TAB_SELECTED, screen.navigatorEventId, params);
104
+        RctManager.getInstance().sendEvent(EVENT_ON_TAB_SELECTED, screen, params);
101
     }
105
     }
102
 
106
 
103
     @Override
107
     @Override

+ 5
- 3
android/app/src/main/java/com/reactnativenavigation/core/RctManager.java View File

9
 import com.facebook.react.bridge.ReactContext;
9
 import com.facebook.react.bridge.ReactContext;
10
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
10
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
11
 import com.facebook.react.bridge.WritableMap;
11
 import com.facebook.react.bridge.WritableMap;
12
+import com.reactnativenavigation.core.objects.Screen;
12
 
13
 
13
 import java.util.List;
14
 import java.util.List;
14
 
15
 
93
      * Sends an event to JavaScript using <a href="https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript">RCTDeviceEventEmitter</a>
94
      * Sends an event to JavaScript using <a href="https://facebook.github.io/react-native/docs/native-modules-android.html#sending-events-to-javascript">RCTDeviceEventEmitter</a>
94
      * @param eventName Name of the event
95
      * @param eventName Name of the event
95
      * @param params Event params
96
      * @param params Event params
96
-     * @param navigatorEventId Id of the navigator
97
+     * @param screen screen which should receive the event
97
      */
98
      */
98
-    public void sendEvent(String eventName, String navigatorEventId, WritableMap params) {
99
+    public void sendEvent(String eventName, Screen screen, WritableMap params) {
99
         RCTDeviceEventEmitter eventEmitter = getEventEmitter();
100
         RCTDeviceEventEmitter eventEmitter = getEventEmitter();
100
         if (eventEmitter == null) {
101
         if (eventEmitter == null) {
101
             return;
102
             return;
102
         }
103
         }
103
 
104
 
104
         params.putString(KEY_EVENT_ID, eventName);
105
         params.putString(KEY_EVENT_ID, eventName);
105
-        eventEmitter.emit(navigatorEventId, params);
106
+        params.putString(Screen.KEY_NAVIGATOR_EVENT_ID, screen.navigatorEventId);
107
+        eventEmitter.emit(screen.navigatorEventId, params);
106
     }
108
     }
107
 
109
 
108
     private RCTDeviceEventEmitter getEventEmitter() {
110
     private RCTDeviceEventEmitter getEventEmitter() {

+ 17
- 0
android/app/src/main/java/com/reactnativenavigation/core/objects/Button.java View File

6
 import android.graphics.drawable.BitmapDrawable;
6
 import android.graphics.drawable.BitmapDrawable;
7
 import android.graphics.drawable.Drawable;
7
 import android.graphics.drawable.Drawable;
8
 import android.net.Uri;
8
 import android.net.Uri;
9
+import android.view.MenuItem;
9
 
10
 
10
 import com.facebook.react.bridge.ReadableMap;
11
 import com.facebook.react.bridge.ReadableMap;
11
 import com.reactnativenavigation.BuildConfig;
12
 import com.reactnativenavigation.BuildConfig;
92
         sStringToNumericId.put(id, itemId);
93
         sStringToNumericId.put(id, itemId);
93
         return itemId;
94
         return itemId;
94
     }
95
     }
96
+
97
+    /**
98
+     * Each button has a string id, defined in JS, which is used to identify the button when
99
+     * handling events.
100
+     * @param item Toolbar button
101
+     * @return Returns the event id associated with the given menu item
102
+     */
103
+    public static String getButtonEventId(MenuItem item) {
104
+        for (Map.Entry<String, Integer> entry : sStringToNumericId.entrySet()) {
105
+            if (entry.getValue() == item.getItemId()) {
106
+                return entry.getKey();
107
+            }
108
+        }
109
+
110
+        return null;
111
+    }
95
 }
112
 }

+ 0
- 8
android/app/src/main/res/layout/toolbar.xml View File

1
-<?xml version="1.0" encoding="utf-8"?>
2
-<app:android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
3
-    xmlns:app="http://schemas.android.com/apk/res-auto"
4
-    android:id="@+id/toolbar"
5
-    android:layout_width="match_parent"
6
-    android:layout_height="?attr/actionBarSize"
7
-    app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
8
-    app:layout_collapseMode="pin"/>