栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android 11 SystemUI 删除状态栏的点击下拉动画

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android 11 SystemUI 删除状态栏的点击下拉动画

1. 问题描述

通话过程中,因未完全遮挡距离传感器导致屏幕亮屏,屏幕亮屏后耳朵附近误触状态栏导致状态栏下拉

状态栏下拉的情况有两种:一种为拖动状态栏下拉,另一种为在非锁屏下点击两次状态栏使状态栏下拉(第一次点击状态栏时,状态栏下拉为展开动画此时动画展示完成后会完全收回状态栏,在动画展示时进行第二次点击,则此时状态栏会完全展开)

由于在通话过程中大概率还是点击导致状态栏下拉,拖动导致下拉的概率较低,所以在状态栏点击功能方面解决该问题,在点击情况下由于完整的下拉的前提是状态栏处于展开动画,所以不显示状态栏的展开展示动画即可删除状态栏的点击下拉功能

2. 状态栏点击事件分发

点击导致状态栏下拉,其处理逻辑必然是从Down事件及Up事件的处理逻辑开始,所以可以先查看状态栏点击事件的分发过程

从View层面开始描述点击事件的分发过程

点击事件由ViewGroup传递到View,状态栏的View则是PhoneStatusBarView,因此查看PhoneStatusBarView的点击事件分发

public boolean onTouchEvent(MotionEvent event) {
    boolean barConsumedEvent = mBar.interceptTouchEvent(event);

    if (DEBUG_GESTURES) {
        if (event.getActionMasked() != MotionEvent.ACTION_MOVE) {
            EventLog.writeEvent(EventLogTags.SYSUI_PANELBAR_TOUCH,
                    event.getActionMasked(), (int) event.getX(), (int) event.getY(),
                    barConsumedEvent ? 1 : 0);
        }
    }

    return barConsumedEvent || super.onTouchEvent(event);
}

此处并没有进行事件的处理,继续向下调用super.onTouchEvent PhoneStatusBarView的父类是PanelBar,则调用到PanelBar的onTouchEvent方法
public boolean onTouchEvent(MotionEvent event) {
    // Allow subclasses to implement enable/disable semantics
    if (!panelEnabled()) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            Log.v(TAG, String.format("onTouch: all panels disabled, ignoring touch at (%d,%d)",
                    (int) event.getX(), (int) event.getY()));
        }
        return false;
    }

    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        final PanelViewController panel = mPanel;
        if (panel == null) {
            // panel is not there, so we'll eat the gesture
            Log.v(TAG, String.format("onTouch: no panel for touch at (%d,%d)",
                    (int) event.getX(), (int) event.getY()));
            return true;
        }
        boolean enabled = panel.isEnabled();
        if (DEBUG) LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %s %s", mState, panel,
                (enabled ? "" : " (disabled)"));
        if (!enabled) {
            // panel is disabled, so we'll eat the gesture
            Log.v(TAG, String.format(
                    "onTouch: panel (%s) is disabled, ignoring touch at (%d,%d)",
                    panel, (int) event.getX(), (int) event.getY()));
            return true;
        }
    }
    return mPanel == null || mPanel.getView().dispatchTouchEvent(event);
}

此时有做Down手势的判断但是由于 panel 不等于 null,且panel.isEnabled等于true,所以无法进入if判断,不会返回true,返回true时即事件被消费掉,不会再向下传递了,但是此时继续向下传递至mPanel.getView().dispatchTouchEvent(event); 事件继续进行分发,dispatchTouchEvent过程中若事件没有被拦截,则会走onInterceptTouchEvent(ViewGroup的特有方法),后面走onTouch,最后则是onTouchEvent 事件最终被传递到NotificationPanelViewController的onTouch方法 public boolean onTouch(View v, MotionEvent event) {     //......     handled |= super.onTouch(v, event);     return !mDozing || mPulsing || handled; } 前面经过很多判断,最终到super.onTouch, 其父类为PanelViewController
public boolean onTouch(View v, MotionEvent event) {
    //......

    

    //......
    switch (event.getActionMasked()) {
        case MotionEvent.ACTION_DOWN:
            startExpandMotion(x, y, false , mExpandedHeight);
            mJustPeeked = false;
            mMinExpandHeight = 0.0f;
            mPanelClosedOnDown = isFullyCollapsed();
            mHasLayoutedSinceDown = false;
            mUpdateFlingOnLayout = false;
            mMotionAborted = false;
            mPeekTouching = mPanelClosedOnDown;
            mDownTime = SystemClock.uptimeMillis();
            mTouchAboveFalsingThreshold = false;
            mCollapsedAndHeadsUpOnDown =
                    isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp();
            addMovement(event);
            //......
            //锁屏界面无法点击下拉状态栏
            if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()
                    && !mStatusBar.isBouncerShowing()) {
                startOpening(event);
            }
            break;

        //......

        case MotionEvent.ACTION_UP:
            addMovement(event);
            endMotionEvent(event, x, y, false );
            break;
    }
    return !mGestureWaitForTouchSlop || mTracking;
}

这里就是真正的Down Up事件的处理逻辑,原生注释显示,如果用户只是简单的点击一下会快速看到shade,在收到Down事件的时候判断,如果此时处于完全收起状态,并且没在点按状态,并且不是锁屏界面,则此时会走startOpening()
private void startOpening(MotionEvent event) {
    runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
            false );
    //......
}

在startOpening()中主要调用了runPeekAnimation,这也就是点按时快速展开shade的动画,在调用的时候会传入此动画的高度 如果是按下状态时,因为展开的动画只有状态栏那么高,所以高度仅仅是45, 在Up时间的处理过程中会判断如果Down和Up的时间不超过400ms ,则依旧会调用该动画并重新设置较高的高度
private void runPeekAnimation(long duration, float peekHeight, boolean collapseWhenFinished) {
    mPeekHeight = peekHeight;
    if (mHeightAnimator != null) {
        return;
    }
    if (mPeekAnimator != null) {
        mPeekAnimator.cancel();
    }
    mPeekAnimator = ObjectAnimator.ofFloat(this, "expandedHeight", mPeekHeight).setDuration(
            duration);
    mPeekAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
    mPeekAnimator.addListener(new AnimatorListenerAdapter() {
        private boolean mCancelled;

        @Override
        public void onAnimationCancel(Animator animation) {
            mCancelled = true;
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            mPeekAnimator = null;
            if (!mCancelled && collapseWhenFinished) {
                mView.postonAnimation(mPostCollapseRunnable);
            }

        }
    });
    notifyExpandingStarted();
    mPeekAnimator.start();
    mJustPeeked = true;
}

mPeekAnimator 即快速展开Shade的动画,如果要删除该动画方法较多,但是最终使用如下方法 mPeekAnimator = ObjectAnimator.ofFloat(this, "expandedHeight", 0f).setDuration(             duration); 仅调整动画高度,将Down时间及Up时间时的动画高度都调为0f,所以动画也就不会显示出来,动画不显示,第二次的点击事件也不会造成状态栏完整下拉
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/284585.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号