最近在开发电子白板项目,系统用的是Android8.0,有一些Android手机上的功能是不需要的,如通知栏下拉
需求是通知可以弹出,可以点击,可以左右滑清除,但是不能下拉
需求有了,那就开始改吧
首先要先找到通知栏代码的位置
通知栏的代码是在SystemUI(frameworks\base\packages\SystemUI\src\com\android\systemui\)
先找到PhoneStatusBarView,PhoneStatusBarView是负责状态栏的绘制和管理,代码位置是在(frameworks\base\packages\SystemUI\src\com\android\systemui\statusbar\phone\PhoneStatusBarView.java)
因为是点击下拉,所以直接看onTouchEvent的代码
@Override
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(event)
PhoneStatusBarView继承PanelBar,PanelBar的onTouchEvent代码如下
@Override
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 PanelView 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.onTouchEvent(event);
}
这里还是没有处理MotionEvent ,调 mPanel.onTouchEvent(event),这个mPanel是PanelView
PanelView的onTouchEvent代码如下
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mInstantExpanding || mTouchDisabled
|| (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
return false;
}
// If dragging should not expand the notifications shade, then return false.
if (!mNotificationsDragEnabled) {
if (mTracking) {
// Turn off tracking if it's on or the shade can get stuck in the down position.
onTrackingStopped(true /* expand */);
}
return false;
}
// On expanding, single mouse click expands the panel instead of dragging.
if (isFullyCollapsed() && event.isFromSource(InputDevice.SOURCE_MOUSE)) {
if (event.getAction() == MotionEvent.ACTION_UP) {
expand(true);
}
return true;
}
/*
* We capture touch events here and update the expand height here in case according to
* the users fingers. This also handles multi-touch.
*
* If the user just clicks shortly, we show a quick peek of the shade.
*
* Flinging is also enabled in order to open or close the shade.
*/
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
mTrackingPointer = event.getPointerId(pointerIndex);
}
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
}
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
startExpandMotion(x, y, false /* startTracking */, 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();
if (mVelocityTracker == null) {
initVelocityTracker();
}
trackMovement(event);
if (!mGestureWaitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning)
|| mPeekAnimator != null) {
mTouchSlopExceeded = (mHeightAnimator != null && !mHintAnimationRunning)
|| mPeekAnimator != null;
cancelHeightAnimator();
cancelPeek();
onTrackingStarted();
}
if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()) {
startOpening();
}
break;
case MotionEvent.ACTION_POINTER_UP:
final int upPointer = event.getPointerId(event.getActionIndex());
if (mTrackingPointer == upPointer) {
// gesture is ongoing, find a new pointer to track
final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
final float newY = event.getY(newIndex);
final float newX = event.getX(newIndex);
mTrackingPointer = event.getPointerId(newIndex);
startExpandMotion(newX, newY, true /* startTracking */, mExpandedHeight);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
mMotionAborted = true;
endMotionEvent(event, x, y, true /* forceCancel */);
return false;
}
break;
case MotionEvent.ACTION_MOVE:
trackMovement(event);
float h = y - mInitialTouchY;
// If the panel was collapsed when touching, we only need to check for the
// y-component of the gesture, as we have no conflicting horizontal gesture.
if (Math.abs(h) > mTouchSlop
&& (Math.abs(h) > Math.abs(x - mInitialTouchX)
|| mIgnoreXTouchSlop)) {
mTouchSlopExceeded = true;
if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) {
if (!mJustPeeked && mInitialOffsetOnTouch != 0f) {
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
h = 0;
}
cancelHeightAnimator();
onTrackingStarted();
}
}
float newHeight = Math.max(0, h + mInitialOffsetOnTouch);
if (newHeight > mPeekHeight) {
if (mPeekAnimator != null) {
mPeekAnimator.cancel();
}
mJustPeeked = false;
} else if (mPeekAnimator == null && mJustPeeked) {
// The initial peek has finished, but we haven't dragged as far yet, lets
// speed it up by starting at the peek height.
mInitialOffsetOnTouch = mExpandedHeight;
mInitialTouchY = y;
mMinExpandHeight = mExpandedHeight;
mJustPeeked = false;
}
newHeight = Math.max(newHeight, mMinExpandHeight);
if (-h >= getFalsingThreshold()) {
mTouchAboveFalsingThreshold = true;
mUpwardsWhenTresholdReached = isDirectionUpwards(x, y);
}
if (!mJustPeeked && (!mGestureWaitForTouchSlop || mTracking) &&
!isTrackingBlocked()) {
setExpandedHeightInternal(newHeight);
}
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
trackMovement(event);
endMotionEvent(event, x, y, false /* forceCancel */);
break;
}
return !mGestureWaitForTouchSlop || mTracking;
}
好了,MotionEven的处理地方就是这里了
我们的目的是不能让它下拉,简单粗暴的改法是直接把case MotionEvent.ACTION_MOVE的代码全部注释了,代码如下:
@Override
public boolean onTouchEvent(MotionEvent event) {
......
case MotionEvent.ACTION_MOVE:
//[remove] zhongxiang.huang,20200104, forbidden dropdown Notification bar
// trackMovement(event);
// float h = y - mInitialTouchY;
//
// // If the panel was collapsed when touching, we only need to check for the
// // y-component of the gesture, as we have no conflicting horizontal gesture.
// if (Math.abs(h) > mTouchSlop
// && (Math.abs(h) > Math.abs(x - mInitialTouchX)
// || mIgnoreXTouchSlop)) {
// mTouchSlopExceeded = true;
// if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) {
// if (!mJustPeeked && mInitialOffsetOnTouch != 0f) {
// startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
// h = 0;
// }
// cancelHeightAnimator();
// onTrackingStarted();
// }
// }
// float newHeight = Math.max(0, h + mInitialOffsetOnTouch);
// if (newHeight > mPeekHeight) {
// if (mPeekAnimator != null) {
// mPeekAnimator.cancel();
// }
// mJustPeeked = false;
// } else if (mPeekAnimator == null && mJustPeeked) {
// // The initial peek has finished, but we haven't dragged as far yet, lets
// // speed it up by starting at the peek height.
// mInitialOffsetOnTouch = mExpandedHeight;
// mInitialTouchY = y;
// mMinExpandHeight = mExpandedHeight;
// mJustPeeked = false;
// }
// newHeight = Math.max(newHeight, mMinExpandHeight);
// if (-h >= getFalsingThreshold()) {
// mTouchAboveFalsingThreshold = true;
// mUpwardsWhenTresholdReached = isDirectionUpwards(x, y);
// }
// if (!mJustPeeked && (!mGestureWaitForTouchSlop || mTracking) &&
// !isTrackingBlocked()) {
// setExpandedHeightInternal(newHeight);
// }
//[end] zhongxiang.huang,20200104, forbidden dropdown Notification bar
break;
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
......
}
return !mGestureWaitForTouchSlop || mTracking;
}
重新编译SystemUI代码,把SystemUI.apk push到/system/priv-app/SystemUI/,然后重启
尝试下拉,通知栏是偶尔能展开,这就有点儿怪了
想了一下,会不会是在onTouchEvent之前也有处理这个下拉动作
在onTouchEvent之前的话,那应该是onInterceptTouchEvent了
PanelView的onInterceptTouchEvent代码如下:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
if (mInstantExpanding || !mNotificationsDragEnabled || mTouchDisabled
|| (mMotionAborted && event.getActionMasked() != MotionEvent.ACTION_DOWN)) {
return false;
}
/*
* If the user drags anywhere inside the panel we intercept it if the movement is
* upwards. This allows closing the shade from anywhere inside the panel.
*
* We only do this if the current content is scrolled to the bottom,
* i.e isScrolledToBottom() is true and therefore there is no conflicting scrolling gesture
* possible.
*/
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
mTrackingPointer = event.getPointerId(pointerIndex);
}
final float x = event.getX(pointerIndex);
final float y = event.getY(pointerIndex);
boolean scrolledToBottom = isScrolledToBottom();
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
mStatusBar.userActivity();
mAnimatingOnDown = mHeightAnimator != null;
mMinExpandHeight = 0.0f;
mDownTime = SystemClock.uptimeMillis();
if (mAnimatingOnDown && mClosing && !mHintAnimationRunning
|| mPeekAnimator != null) {
cancelHeightAnimator();
cancelPeek();
mTouchSlopExceeded = true;
return true;
}
mInitialTouchY = y;
mInitialTouchX = x;
mTouchStartedInEmptyArea = !isInContentBounds(x, y);
mTouchSlopExceeded = false;
mJustPeeked = false;
mMotionAborted = false;
mPanelClosedOnDown = isFullyCollapsed();
mCollapsedAndHeadsUpOnDown = false;
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mTouchAboveFalsingThreshold = false;
initVelocityTracker();
trackMovement(event);
break;
case MotionEvent.ACTION_POINTER_UP:
final int upPointer = event.getPointerId(event.getActionIndex());
if (mTrackingPointer == upPointer) {
// gesture is ongoing, find a new pointer to track
final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
mTrackingPointer = event.getPointerId(newIndex);
mInitialTouchX = event.getX(newIndex);
mInitialTouchY = event.getY(newIndex);
}
break;
case MotionEvent.ACTION_POINTER_DOWN:
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
mMotionAborted = true;
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
}
break;
case MotionEvent.ACTION_MOVE:
//[remove] zhongxiang.huang,20200104, forbidden dropdown Notification bar
// final float h = y - mInitialTouchY;
// trackMovement(event);
// if (scrolledToBottom || mTouchStartedInEmptyArea || mAnimatingOnDown) {
// float hAbs = Math.abs(h);
// if ((h < -mTouchSlop || (mAnimatingOnDown && hAbs > mTouchSlop))
// && hAbs > Math.abs(x - mInitialTouchX)) {
// cancelHeightAnimator();
// startExpandMotion(x, y, true /* startTracking */, mExpandedHeight);
// return true;
// }
// }
//[end] zhongxiang.huang,20200104, forbidden dropdown Notification bar
break;
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
return false;
}
上面是我改过的代码,也是把case MotionEvent.ACTION_MOVE的代码直接注释了
重新编译SystemUI,然后push,然后重启,弹出通知,尝试下拉,发现拉不下来了
再试一下能不能点击,能不能左右滑动清除,都可以。
来源:CSDN
作者:zx_huang
链接:https://blog.csdn.net/mai763727999/article/details/103945105