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,6 +10,7 @@ import android.support.v7.app.AppCompatActivity;
10 10
 import android.util.Log;
11 11
 import android.view.KeyEvent;
12 12
 import android.view.Menu;
13
+import android.view.MenuItem;
13 14
 import android.widget.EditText;
14 15
 import android.widget.Toast;
15 16
 
@@ -18,11 +19,14 @@ import com.facebook.react.LifecycleState;
18 19
 import com.facebook.react.ReactInstanceManager;
19 20
 import com.facebook.react.ReactPackage;
20 21
 import com.facebook.react.ReactRootView;
22
+import com.facebook.react.bridge.Arguments;
23
+import com.facebook.react.bridge.WritableMap;
21 24
 import com.facebook.react.common.ReactConstants;
22 25
 import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
23 26
 import com.facebook.react.shell.MainReactPackage;
24 27
 import com.reactnativenavigation.BuildConfig;
25 28
 import com.reactnativenavigation.core.RctManager;
29
+import com.reactnativenavigation.core.objects.Button;
26 30
 import com.reactnativenavigation.core.objects.Screen;
27 31
 import com.reactnativenavigation.packages.RnnPackage;
28 32
 import com.reactnativenavigation.utils.ContextProvider;
@@ -41,6 +45,7 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
41 45
     private static final String TAG = "BaseReactActivity";
42 46
     private static final String REDBOX_PERMISSION_MESSAGE =
43 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 50
     @Nullable
46 51
     protected ReactInstanceManager mReactInstanceManager;
@@ -225,7 +230,9 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
225 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 237
     public abstract int getScreenStackSize();
231 238
 
@@ -235,6 +242,20 @@ public abstract class BaseReactActivity extends AppCompatActivity implements Def
235 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 259
     public Menu getMenu() {
239 260
         return mMenu;
240 261
     }

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

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

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

@@ -58,6 +58,11 @@ public class SingleScreenActivity extends BaseReactActivity {
58 58
         return mNavigatorId;
59 59
     }
60 60
 
61
+    @Override
62
+    protected Screen getCurrentScreen() {
63
+        return mScreenStack.peek();
64
+    }
65
+
61 66
     @Override
62 67
     public int getScreenStackSize() {
63 68
         return mScreenStack.getStackSize();

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

@@ -20,8 +20,6 @@ public class TabActivity extends BaseReactActivity {
20 20
 
21 21
     private TabLayout mTabLayout;
22 22
     private ViewPager mViewPager;
23
-
24
-    private ArrayList<Screen> mScreens;
25 23
     private ViewPagerAdapter mAdapter;
26 24
 
27 25
     @Override
@@ -33,19 +31,19 @@ public class TabActivity extends BaseReactActivity {
33 31
         mTabLayout = (TabLayout) findViewById(R.id.tabLayout);
34 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 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 47
         mViewPager.setAdapter(mAdapter);
50 48
         mTabLayout.setupWithViewPager(mViewPager);
51 49
         mTabLayout.setOnTabSelectedListener(mAdapter);
@@ -72,7 +70,12 @@ public class TabActivity extends BaseReactActivity {
72 70
     }
73 71
 
74 72
     @Override
75
-    public String getCurrentNavigatorId() {
73
+    protected Screen getCurrentScreen() {
74
+        return mAdapter.peek(getCurrentNavigatorId());
75
+    }
76
+
77
+    @Override
78
+    protected String getCurrentNavigatorId() {
76 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,6 +58,11 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
58 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 66
     @Override
62 67
     public Object instantiateItem(ViewGroup container, int position) {
63 68
         ScreenStack view = mScreenStacks.get(position);
@@ -96,8 +101,7 @@ public class ViewPagerAdapter extends PagerAdapter implements TabLayout.OnTabSel
96 101
         // Send tab selected event
97 102
         WritableMap params = Arguments.createMap();
98 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 107
     @Override

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

@@ -9,6 +9,7 @@ import com.facebook.react.ReactPackage;
9 9
 import com.facebook.react.bridge.ReactContext;
10 10
 import com.facebook.react.bridge.ReactContextBaseJavaModule;
11 11
 import com.facebook.react.bridge.WritableMap;
12
+import com.reactnativenavigation.core.objects.Screen;
12 13
 
13 14
 import java.util.List;
14 15
 
@@ -93,16 +94,17 @@ public class RctManager {
93 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 95
      * @param eventName Name of the event
95 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 100
         RCTDeviceEventEmitter eventEmitter = getEventEmitter();
100 101
         if (eventEmitter == null) {
101 102
             return;
102 103
         }
103 104
 
104 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 110
     private RCTDeviceEventEmitter getEventEmitter() {

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

@@ -6,6 +6,7 @@ import android.graphics.BitmapFactory;
6 6
 import android.graphics.drawable.BitmapDrawable;
7 7
 import android.graphics.drawable.Drawable;
8 8
 import android.net.Uri;
9
+import android.view.MenuItem;
9 10
 
10 11
 import com.facebook.react.bridge.ReadableMap;
11 12
 import com.reactnativenavigation.BuildConfig;
@@ -92,4 +93,20 @@ public class Button extends JsonObject implements Serializable {
92 93
         sStringToNumericId.put(id, itemId);
93 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,8 +0,0 @@
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"/>