android 7.0平台客制化虚拟导航按键(隐藏NavigationBar,上滑显示NavigationBar)

如图,需求是增加一个按钮可以隐藏NavigationBar,上滑显示NavigationBar。

 参考文章:

Android 8.1平台客制化虚拟导航按键

Android 7.0 虚拟按键(NavigationBar)源码分析(一) 之 View的创建流程

android导航栏隐藏与浮现

1.首先新建一个hide_show.xml,其中systemui:keyCode="142"为事件值,相当与F12.

    <?xml version="1.0" encoding="utf-8"?>
    <!-- Copyright (C) 2016 The Android Open Source Project
     
         Licensed under the Apache License, Version 2.0 (the "License");
         you may not use this file except in compliance with the License.
         You may obtain a copy of the License at
     
              http://www.apache.org/licenses/LICENSE-2.0
     
         Unless required by applicable law or agreed to in writing, software
         distributed under the License is distributed on an "AS IS" BASIS,
         WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
         See the License for the specific language governing permissions and
         limitations under the License.
    -->
    <com.android.systemui.statusbar.policy.KeyButtonView
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:systemui="http://schemas.android.com/apk/res-auto"
        android:id="@+id/hide"
        android:layout_width="@dimen/navigation_key_width"
        android:layout_height="match_parent"
        android:layout_weight="0"
        android:src="@drawable/ic_sysbar_back_ime"
        systemui:keyCode="142"
        android:scaleType="center"
        android:contentDescription="@string/accessibility_home"
        android:paddingStart="@dimen/navigation_key_padding"
        android:paddingEnd="@dimen/navigation_key_padding"
        />

2.NavigationBarInflaterView.java

增加hide。

        public static final String HOME = "home";
        public static final String RECENT = "recent";
        public static final String NAVSPACE = "space";
        public static final String CLIPBOARD = "clipboard";
        public static final String KEY = "key";
        public static final String HIDE = "hide";// add by csc for hide navigationbar
        /// M: BMW @{
        public static final String RESTORE = "restore";

        protected void inflateLayout(String newLayout) {
            mCurrentLayout = newLayout;
            if (newLayout == null) {
                newLayout = getDefaultLayout();
            }
            newLayout = "hide;recent;home;back";// add by csc
            String[] sets = newLayout.split(GRAVITY_SEPARATOR, 4);// mod by csc from 3
            String[] hide = sets[0].split(BUTTON_SEPARATOR);// add by csc
            String[] start = sets[1].split(BUTTON_SEPARATOR);
            String[] center = sets[2].split(BUTTON_SEPARATOR);
            String[] end = sets[3].split(BUTTON_SEPARATOR);
            // Inflate these in start to end order or accessibility traversal will be messed up.
     
            inflateButtons(hide, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);// add by csc
            inflateButtons(hide, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);// add by csc
     
            inflateButtons(start, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
            inflateButtons(start, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
     
            inflateButtons(center, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
            inflateButtons(center, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
     
            // delete by csc
           /* addGravitySpacer((LinearLayout) mRot0.findViewById(R.id.ends_group));
            addGravitySpacer((LinearLayout) mRot90.findViewById(R.id.ends_group));*/
     
            inflateButtons(end, (ViewGroup) mRot0.findViewById(R.id.ends_group), false);
            inflateButtons(end, (ViewGroup) mRot90.findViewById(R.id.ends_group), true);
        }

其中,为了布局把center_group改为ends_group,将space去掉(注释addGravitySpacer)。

inflateButton方法里面增加:

     else if (HIDE.equals(button)){// add by csc for hide navigationBar
                Log.d("chenshichun"," "+this.getClass().getCanonicalName()+" ::::::HIDE:button::");
                v = inflater.inflate(R.layout.hide_show, parent, false);
            }

3.NavigationBarView.java

     mBarTransitions = new NavigationBarTransitions(this);
            mButtonDisatchers.put(R.id.hide, new ButtonDispatcher(R.id.hide));// add by csc for hide navigationbar
            getHideButton().setLongClickable(false);// add by csc for hide navigationbar
            mButtonDisatchers.put(R.id.back, new ButtonDispatcher(R.id.back));
            mButtonDisatchers.put(R.id.home, new ButtonDispatcher(R.id.home));
            mButtonDisatchers.put(R.id.recent_apps, new ButtonDispatcher(R.id.recent_apps));

    public ButtonDispatcher getBackButton() {
            return mButtonDisatchers.get(R.id.back);
        }
     
        public ButtonDispatcher getHomeButton() {
            return mButtonDisatchers.get(R.id.home);
        }
     
        public ButtonDispatcher getHideButton() {// add by csc
            return mButtonDisatchers.get(R.id.hide);
        }

到这里可以在界面上显示按钮。接下来加上点击事件。

4.PhoneWindowManager.java

 在interceptKeyBeforeDispatching方法里面增加F12的监听事件,这时候为隐藏事件:

    else if(keyCode == KeyEvent.KEYCODE_F12){// add by csc
                Intent hideNavigationBarIntent = new Intent("HIDE_NAVIGATION_BAR");
                mContext.sendBroadcast(hideNavigationBarIntent);
                return -1;
            }

上滑显示事件:

    mSystemGestures = new SystemGesturesPointerEventListener(context,
                    new SystemGesturesPointerEventListener.Callbacks() {
                        @Override
                        public void onSwipeFromTop() {
                            /// M: Disable gesture in immersive mode. {@
                            if (isGestureIsolated()) {
                                return;
                            }
                            /// @}
                            if (mStatusBar != null) {
                                requestTransientBars(mStatusBar);
                            }
                        }
                        @Override
                        public void onSwipeFromBottom() {
                            /// M: Disable gesture in immersive mode. {@
                            if (isGestureIsolated()) {
                                return;
                            }
                            /// @}
                            if (mNavigationBar != null && mNavigationBarOnBottom) {
                                requestTransientBars(mNavigationBar);
                            }
                        /*add by csc*/
                            Intent intent = new Intent();
                            intent.setAction("SHOW_NAVIGATION_BAR");
                            mContext.sendBroadcast(intent);
                        }

5.PhoneStatusBar.java

该类处理导航栏的隐藏或显示。

先注册广播:

       filter.addAction("HIDE_NAVIGATION_BAR");// add by csc
       filter.addAction("SHOW_NAVIGATION_BAR");// add by csc

                else if(action.equals("HIDE_NAVIGATION_BAR")&&mWindowManager!=null&&mNavigationBarView!=null&&mNavigationBarView.getParent()!=null){
                    mWindowManager.removeView(mNavigationBarView);
                    mNavigationBarView = null ;
                    isNavigationShow = false;
                }else if(action.equals("SHOW_NAVIGATION_BAR")){
                    if(isNavigationShow){
                        return ;
                    }
                        showNavigationBar();
                        isNavigationShow = true;
                }

        public void showNavigationBar() {
            mNavigationBarView =(NavigationBarView) View.inflate(mContext, R.layout.navigation_bar, null);
            prepareNavigationBarView();
            addNavigationBar();
     
            //防止在桌面时上拉出导航栏时,导航栏背景为黑色
            mNavigationBarView.setBackgroundColor(Color.TRANSPARENT);
        }

     protected void addNavigationBar() {
            if (DEBUG) Log.v(TAG, "addNavigationBar: about to add " + mNavigationBarView);
            if (mNavigationBarView == null) return;
     
            prepareNavigationBarView();
            if(mNavigationBarView!=null && mNavigationBarView.getParent()==null) {// add by csc
     
                mWindowManager.addView(mNavigationBarView, getNavigationBarLayoutParams());
            }
        }

ok。
————————————————
版权声明:本文为CSDN博主「cuckoochun」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/cuckoochun/article/details/84109895

发布了18 篇原创文章 · 获赞 6 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_37207639/article/details/103515682