wd and cc

-- Good good study, day day up!

Add float debug button for react native

#Android #React #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        }

然后在你的 MainActivityonCreate 里面,在 super.onCreate(savedInstanceState); 后面增加

            // debug 环境下才显示
            if(BuildConfig.DEBUG)
                addDevButton();
comments powered by Disqus