Android7.0 锁屏的通知消息的滑动、删除所有

1:代码核心类

SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java

SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java

SystemUI/src/com/android/systemui/statusbar/DismissView.java 

SystemUI/src/com/android/systemui/statusbar/NotificationSettingsIconRow.java

SystemUI/src/com/android/systemui/SwipeHelper.java

SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java

2:通知显示的类(NotificationStackScrollLayout)

有通知时,会添加到这个类上,并显示

3:删除所有按钮的显示流程(DismissView.java)

这个控件是动态添加到NotificationStackScrollLayout中的,其代码流程如下:

PhoneStatusBar.java

 @Override
    public void createAndAddWindows() {
        addStatusBarWindow();
    }

  private void addStatusBarWindow() {
        makeStatusBarView();
        mStatusBarWindowManager = new StatusBarWindowManager(mContext);
        mRemoteInputController = new RemoteInputController(mStatusBarWindowManager,
                mHeadsUpManager);
        mStatusBarWindowManager.add(mStatusBarWindow, getStatusBarHeight());
    }

protected PhoneStatusBarView makeStatusBarView() {
    ...
       // figure out which pixel-format to use for the status bar.
        mPixelFormat = PixelFormat.OPAQUE;

        mStackScroller = (NotificationStackScrollLayout) mStatusBarWindow.findViewById(
                R.id.notification_stack_scroller);
        mStackScroller.setLongPressListener(getNotificationLongClicker());
        mStackScroller.setPhoneStatusBar(this);
        mStackScroller.setGroupManager(mGroupManager);
        mStackScroller.setHeadsUpManager(mHeadsUpManager);
        mGroupManager.setOnGroupChangeListener(mStackScroller);

        inflateOverflowContainer();
        inflateEmptyShadeView();
        inflateDismissView();
        mExpandedContents = mStackScroller;
    ....
}

 private void inflateDismissView() {
        mDismissView = (DismissView) LayoutInflater.from(mContext).inflate(
                R.layout.status_bar_notification_dismiss_all, mStackScroller, false);
        mDismissView.setOnButtonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                MetricsLogger.action(mContext, MetricsEvent.ACTION_DISMISS_ALL_NOTES);
                clearAllNotifications();
            }
        });
        mStackScroller.setDismissView(mDismissView);
    }

其上的makeStatusBarView()函数很长,只贴了关键代码。在inflateDismissView()的函数中初始化了DismissView的对象并设置到mStackScroller(NotificationStackScrollLayout.java类)中。

mDismissView.setOnButtonClickListener(...)设置了点击事件的监听。

DismissView.java :

  public void setOnButtonClickListener(OnClickListener listener) {
        mContent.setOnClickListener(listener);
    }
4:删除所有按钮的显示与隐藏

DismissView 删除控件是随着有无通知消息和消息属性显示或隐藏的,代码流程如下:

PhoneStatusBar.java的代码:

 @Override
    protected void updateNotifications() {
        Log.d("kaymediashot2", "updateNotifications:" );
        mNotificationData.filterAndSort();

        updateNotificationShade();
        mIconController.updateNotificationIcons(mNotificationData);
    }

 private void updateNotificationShade() {

    ...
      updateRowStates();
        updateSpeedbump();
        updateClearAll(); ///这里
        updateEmptyShadeView();

        updateQsExpansionEnabled();
        mShadeUpdates.check();
}

private void updateClearAll() {
        boolean showDismissView =
                mState != StatusBarState.KEYGUARD &&
                mNotificationData.hasActiveClearableNotifications();
        mStackScroller.updateDismissView(showDismissView);
    }

之后通过mStackScroller.updateDismissView(showDismissView)跳转到NotificationStackScrollLayout.java中进行判断显示还是隐藏。

 public void updateDismissView(boolean visible) {
        int oldVisibility = mDismissView.willBeGone() ? GONE : mDismissView.getVisibility();
        int newVisibility = visible ? VISIBLE : GONE;

        if (oldVisibility != newVisibility) {
            if (newVisibility != GONE) {
                if (mDismissView.willBeGone()) {
                    mDismissView.cancelAnimation();
                } else {
                    mDismissView.setInvisible();
                }
                mDismissView.setVisibility(newVisibility);
                mDismissView.setWillBeGone(false);
                updateContentHeight();
                notifyHeightChangeListener(mDismissView);
            } else {
                Runnable dimissHideFinishRunnable = new Runnable() {
                    @Override
                    public void run() {
                        mDismissView.setVisibility(GONE);
                        mDismissView.setWillBeGone(false);
                        updateContentHeight();
                        notifyHeightChangeListener(mDismissView);
                    }
                };
                if (mDismissView.isButtonVisible() && mIsExpanded && mAnimationsEnabled) {
                    mDismissView.setWillBeGone(true);
                    mDismissView.performVisibilityAnimation(false, dimissHideFinishRunnable);
                } else {
                    dimissHideFinishRunnable.run();
                }
            }
        }
    }
5:滑动通知消息显示设置图标的流程

NotificationStackScrollLayout.java中,代码如下:

@Override
    public boolean onTouchEvent(MotionEvent ev) {
        boolean isCancelOrUp = ev.getActionMasked() == MotionEvent.ACTION_CANCEL
                || ev.getActionMasked()== MotionEvent.ACTION_UP;
        handleEmptySpaceClick(ev);
        boolean expandWantsIt = false;
        if (mIsExpanded && !mSwipingInProgress && !mOnlyScrollingInThisMotion) {
            if (isCancelOrUp) {
                mExpandHelper.onlyObserveMovements(false);
            }
            boolean wasExpandingBefore = mExpandingNotification;
            expandWantsIt = mExpandHelper.onTouchEvent(ev);
            if (mExpandedInThisMotion && !mExpandingNotification && wasExpandingBefore
                    && !mDisallowScrollingInThisMotion) {
                dispatchDownEventToScroller(ev);
            }
        }
        boolean scrollerWantsIt = false;
        if (mIsExpanded && !mSwipingInProgress && !mExpandingNotification
                && !mDisallowScrollingInThisMotion) {
            scrollerWantsIt = onScrollTouch(ev);
        }
        boolean horizontalSwipeWantsIt = false;
        if (!mIsBeingDragged
                && !mExpandingNotification
                && !mExpandedInThisMotion
                && !mOnlyScrollingInThisMotion
                && !mDisallowDismissInThisMotion) {
            horizontalSwipeWantsIt = mSwipeHelper.onTouchEvent(ev);//这里显示通知的设置图标
        }
        return horizontalSwipeWantsIt || scrollerWantsIt || expandWantsIt || super.onTouchEvent(ev);
    }
mSwipeHelper.onTouchEvent(ev);这里进入SwipeHelper进行处。

SwipeHelper.java:

 public boolean onTouchEvent(MotionEvent ev) {
        if (mLongPressSent) {
            return true;
        }

        if (!mDragging) {
            if (mCallback.getChildAtPosition(ev) != null) {

                // We are dragging directly over a card, make sure that we also catch the gesture
                // even if nobody else wants the touch event.
                onInterceptTouchEvent(ev);
                return true;
            } else {

                // We are not doing anything, make sure the long press callback
                // is not still ticking like a bomb waiting to go off.
                removeLongPressCallback();
                return false;
            }
        }

        mVelocityTracker.addMovement(ev);
        final int action = ev.getAction();
        switch (action) {
            case MotionEvent.ACTION_OUTSIDE:
            case MotionEvent.ACTION_MOVE:
                if (mCurrView != null) {
                    float delta = getPos(ev) - mInitialTouchPos;
                    float absDelta = Math.abs(delta);
                    if (absDelta >= getFalsingThreshold()) {
                        mTouchAboveFalsingThreshold = true;
                    }
                    // don't let items that can't be dismissed be dragged more than
                    // maxScrollDistance
                    if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
                        float size = getSize(mCurrView);
                        float maxScrollDistance = 0.25f * size;
                        if (absDelta >= size) {
                            delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
                        } else {
                            delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
                        }
                    }

                    setTranslation(mCurrView, mTranslation + delta);//这里
                    updateSwipeProgressFromOffset(mCurrView, mCanCurrViewBeDimissed);
                    onMoveUpdate(mCurrView, mTranslation + delta, delta);
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                if (mCurrView == null) {
                    break;
                }
                mVelocityTracker.computeCurrentVelocity(1000 /* px/sec */, getMaxVelocity());
                float velocity = getVelocity(mVelocityTracker);

                if (!handleUpEvent(ev, mCurrView, velocity, getTranslation(mCurrView))) {
                    if (isDismissGesture(ev)) {
                        // flingadingy
                        dismissChild(mCurrView, velocity,
                                !swipedFastEnough() /* useAccelerateInterpolator */);
                    } else {
                        // snappity
                        mCallback.onDragCancelled(mCurrView);
                        snapChild(mCurrView, 0 /* leftTarget */, velocity);
                    }
                    mCurrView = null;
                }
                mDragging = false;
                break;
        }
        return true;
    }
setTranslation(mCurrView, mTranslation + delta);;继续处理滑动,其的具体执行位置在NotificationStackScrollLayout.java中的NotificationSwipeHelper中;
,代码如下:
    @Override
        public void setTranslation(View v, float translate) {
            ((ExpandableView) v).setTranslation(translate);
        }
((ExpandableView) v).setTranslation(translate);

ExpandableView.java

   /**
     * Sets the translation of the view.
     */
    public void setTranslation(float translation) {
        setTranslationX(translation);
    }
setTranslationX(translation);的运行位置在ExpandableNotificationRow.java文件中:
 @Override
    public void setTranslation(float translationX) {
        if (areGutsExposed()) {
            // Don't translate if guts are showing.
            return;
        }
        // Translate the group of views
        for (int i = 0; i < mTranslateableViews.size(); i++) {
            if (mTranslateableViews.get(i) != null) {
                mTranslateableViews.get(i).setTranslationX(translationX);
            }
        }
        invalidateOutline();
        if (mSettingsIconRow != null) {
            mSettingsIconRow.updateSettingsIcons(translationX, getMeasuredWidth());
        }
    }

mSettingsIconRow是NotificationSettingsIconRow.java类:

public void updateSettingsIcons(final float transX, final float size) {
        if (mAnimating || !mSettingsFadedIn) {
            // Don't adjust when animating, or if the gear hasn't been shown yet.
            return;
        }

        final float fadeThreshold = size * 0.3f;
        final float absTrans = Math.abs(transX);
        float desiredAlpha = 0;

        if (absTrans == 0) {
            desiredAlpha = 0;
        } else if (absTrans <= fadeThreshold) {
            desiredAlpha = 1;
        } else {
            desiredAlpha = 1 - ((absTrans - fadeThreshold) / (size - fadeThreshold));
        }
        setGearAlpha(desiredAlpha);
    }

 public void setGearAlpha(float alpha) {
        if (alpha == 0) {
            mSettingsFadedIn = false; // Can fade in again once it's gone.
            setVisibility(View.INVISIBLE);
        } else {
            setVisibility(View.VISIBLE);
        }
        mGearIcon.setAlpha(alpha);
    }

这里通过透明值来设置mGearIcon(按钮控件变量)的父类的显示与隐藏,并设置其本身的透明值.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值