Add float debug button for react native
React-native 里面在模拟器里面可以通过快捷键打开开发菜单,在设备里面可以通过摇晃设备打开开发菜单。但是摇晃有时候并不是一个好的操作,比如是个 pad,或者比如你自己的设备本身会触发晃动动作。那么如何在开发模式下面增加一个按钮打开这个菜单呢?可惜官方对这个功能没有兴趣多做开发 https://github.com/facebook/react-native/issues/10191 。
iOS
ios 里面直接就把这个接口暴露出来了,可以直接在 js 里面调用。
1import {NativeModules} from 'react-native';
2
3// 在某个按钮的动作里面
4const {DevMenu} = NativeModules;
5DevMenu.show();
Android
iOS 是 react-native 的亲儿子,Android 里面并没有那么方便的方法,得自己通过 native 代码加。
下面两种方式加的都是 android.support.design.widget.FloatingActionButton
按钮,其它的类似。需要增加好编译依赖 compile 'com.android.support:design:23.0.0'
,版本号按照自己的修改下。
1 private void addDevButton() {
2
3 MainApplication application = (MainApplication) getApplication();
4 ReactNativeHost reactNativeHost = application.getReactNativeHost();
5 ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
6 final DevSupportManager devSupportManager = reactInstanceManager.getDevSupportManager();
7
8 // 这里是增加一个自定义菜单
9// devSupportManager.addCustomDevOption("Custom dev option", new DevOptionHandler() {
10// @Override
11// public void onOptionSelected() {
12// Toast.makeText(MainActivity.this, "Hello from custom dev option", Toast.LENGTH_SHORT).show();
13// }
14// });
15
16
17 // Fake empty container dev_button_layout
18 // 创建一个 layout
19 RelativeLayout lContainerLayout = new RelativeLayout(mActivity.getApplicationContext());
20 lContainerLayout.setLayoutParams(new RelativeLayout.LayoutParams(
21 ViewGroup.LayoutParams.MATCH_PARENT , ViewGroup.LayoutParams.MATCH_PARENT ));
22
23 // custom view
24 // 创建一个 button
25 FloatingActionButton button = new FloatingActionButton(mActivity);
26 button.setImageResource(R.drawable.ga_airplane);
27
28 RelativeLayout.LayoutParams lButtonParams = new RelativeLayout.LayoutParams(
29 ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT
30 );
31 lButtonParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
32 lButtonParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
33 button.setLayoutParams(lButtonParams);
34
35 ViewGroup.MarginLayoutParams mp = (ViewGroup.MarginLayoutParams) button.getLayoutParams();
36 mp.setMargins(0, 0, 0, dpToPx(mActivity, 125));
37
38 button.setLayoutParams(mp);
39
40 //设定拖动动作
41 button.setOnTouchListener(new View.OnTouchListener() {
42 @Override
43 public boolean onTouch(View v, MotionEvent event) {
44 switch (event.getActionMasked()) {
45 case MotionEvent.ACTION_DOWN:
46 dX = v.getX() - event.getRawX();
47 dY = v.getY() - event.getRawY();
48 lastAction = MotionEvent.ACTION_DOWN;
49 break;
50
51 case MotionEvent.ACTION_MOVE:
52 v.setY(event.getRawY() + dY);
53 v.setX(event.getRawX() + dX);
54 lastAction = MotionEvent.ACTION_MOVE;
55 break;
56
57 case MotionEvent.ACTION_UP:
58 if (lastAction == MotionEvent.ACTION_DOWN)
59 // 点击的时候打开菜单
60 devSupportManager.showDevOptionsDialog();
61 break;
62
63 default:
64 return false;
65 }
66 return true;
67 }
68 });
69
70 lContainerLayout.addView(button);
71 addContentView(lContainerLayout, new ViewGroup.LayoutParams(
72 ViewGroup.LayoutParams.MATCH_PARENT , ViewGroup.LayoutParams.MATCH_PARENT ));
73 }
上面是纯代码方式,还可以通过 xml 文件方式搞定。
新建一个 layout 文件,取名比如叫做 dev_button_layout.xml
, rootTag 是 RelativeLayout
。然后在里面添加一个 FloatingActionButton
,id 设置为 dev_button
,然后设置好属性和位置。
1 private void addDevButton() {
2 MainApplication application = (MainApplication) getApplication();
3 ReactNativeHost reactNativeHost = application.getReactNativeHost();
4 ReactInstanceManager reactInstanceManager = reactNativeHost.getReactInstanceManager();
5 final DevSupportManager devSupportManager = reactInstanceManager.getDevSupportManager();
6
7 View view = View.inflate(mActivity, R.layout.dev_button_layout, null);
8 FloatingActionButton button = (FloatingActionButton) view.findViewById(R.id.dev_button);
9 //button.setImageResource(R.drawable.ga_airplane);
10
11 button.setOnTouchListener(new View.OnTouchListener() {
12 @Override
13 public boolean onTouch(View v, MotionEvent event) {
14 switch (event.getActionMasked()) {
15 case MotionEvent.ACTION_DOWN:
16 dX = v.getX() - event.getRawX();
17 dY = v.getY() - event.getRawY();
18 lastAction = MotionEvent.ACTION_DOWN;
19 break;
20
21 case MotionEvent.ACTION_MOVE:
22 v.setY(event.getRawY() + dY);
23 v.setX(event.getRawX() + dX);
24 lastAction = MotionEvent.ACTION_MOVE;
25 break;
26
27 case MotionEvent.ACTION_UP:
28 if (lastAction == MotionEvent.ACTION_DOWN)
29 devSupportManager.showDevOptionsDialog();
30 break;
31
32 default:
33 return false;
34 }
35 return true;
36 }
37 });
38
39 addContentView(view, new ViewGroup.LayoutParams(
40 ViewGroup.LayoutParams.MATCH_PARENT , ViewGroup.LayoutParams.MATCH_PARENT ));
41 }
然后在你的 MainActivity
的 onCreate
里面,在 super.onCreate(savedInstanceState);
后面增加
// debug 环境下才显示
if(BuildConfig.DEBUG)
addDevButton();