Android11(MTK) SystemUI下拉栏背景高斯模糊

Android11(MTK) SystemUI下拉栏背景高斯模糊,第1张

status_bar_expanded.xml布局中


    
    

    

    

    


NotificationPanelViewController.java类
private static final int BLUR_START = 200;
private static final int BLUR_END = 700;
/**
 * 高斯模糊背景
 */
private ImageView mBlurView;
createTouchHandler()方法中
public boolean onTouch(View v, MotionEvent event) {
    if (mBlockTouches || (mQsFullyExpanded && mQs != null
            && mQs.disallowPanelTouches())) {
        return false;
    }

    // Do not allow panel expansion if bouncer is scrimmed, otherwise user would be able
    // to pull down QS or expand the shade.
    if (mStatusBar.isBouncerShowingScrimmed()) {
        return false;
    }

    // Make sure the next touch won't the blocked after the current ends.
    if (event.getAction() == MotionEvent.ACTION_UP
            || event.getAction() == MotionEvent.ACTION_CANCEL) {
        mBlockingExpansionForCurrentTouch = false;
    }
    // When touch focus transfer happens, ACTION_DOWN->ACTION_UP may happen immediately
    // without any ACTION_MOVE event.
    // In such case, simply expand the panel instead of being stuck at the bottom bar.
    if (mLastEventSynthesizedDown && event.getAction() == MotionEvent.ACTION_UP) {
        expand(true /* animate */);
    }
    initDownStates(event);
    if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)
            && mPulseExpansionHandler.onTouchEvent(event)) {
        // We're expanding all the other ones shouldn't get this anymore
        return true;
    }
    if (mListenForHeadsUp && !mHeadsUpTouchHelper.isTrackingHeadsUp()
            && mHeadsUpTouchHelper.onInterceptTouchEvent(event)) {
        mMetricsLogger.count(COUNTER_PANEL_OPEN_PEEK, 1);
    }
    boolean handled = false;
    if ((!mIsExpanding || mHintAnimationRunning) && !mQsExpanded
            && mBarState != StatusBarState.SHADE && !mDozing) {
        handled |= mAffordanceHelper.onTouchEvent(event);
    }
    if (mOnlyAffordanceInThisMotion) {
        return true;
    }
    handled |= mHeadsUpTouchHelper.onTouchEvent(event);

    if (!mHeadsUpTouchHelper.isTrackingHeadsUp() && handleQsTouch(event)) {
        return true;
    }
    if (event.getActionMasked() == MotionEvent.ACTION_DOWN && isFullyCollapsed()) {
        mMetricsLogger.count(COUNTER_PANEL_OPEN, 1);
        updateVerticalPanelPosition(event.getX());
        handled = true;
    }

    //添加背景高斯模糊 begin
    float y = event.getY();
    switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            if (!mPanelExpanded) {
                setBlurBackground();
            }
            break;
        case MotionEvent.ACTION_MOVE:
            if (y <= BLUR_END) {
                float alpha = (y - BLUR_START) / (BLUR_END - BLUR_START);
                if (alpha < 0) {
                    alpha = 0;
                }
                mBlurView.setAlpha(alpha);
            }
            break;
        case MotionEvent.ACTION_UP:
            float a = mBlurView.getAlpha();
            startAlphaAnimation(a, 1.0f);
            break;
    }
    // 添加背景高斯模糊 end

    handled |= super.onTouch(v, event);
    return !mDozing || mPulsing || handled;
}

private void startAlphaAnimation(float start, float end) {
    ValueAnimator va = ValueAnimator.ofFloat(start, end);
    va.setDuration((long) (Math.abs(end - start) * 500));
    va.start();
    va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float alpha = (float) animation.getAnimatedValue();
            mBlurView.setAlpha(alpha);
        }
    });
}

private void setBlurBackground() {
    Bitmap bitmap = ScreenShotUtil.takeScreenShot(mView.getContext());
    if (bitmap == null) {
        Log.d(TAG, "setBlurBackground bitmap == null");
        return;
    }
    Bitmap cutBitmap = ScreenShotUtil.convertHardWareBitmap(bitmap);
    Bitmap blurBitmap = BlurUtil.blur(mView.getContext(), cutBitmap, BlurUtil.BLUR_RADIUS_MAX);
    BitmapUtils.recycleImageView(mBlurView);
    mBlurView.setImageBitmap(blurBitmap);
}

private class StatusBarStateListener implements StateListener {
        @Override
        public void onStateChanged(int statusBarState) {
            boolean goingToFullShade = mStatusBarStateController.goingToFullShade();
            boolean keyguardFadingAway = mKeyguardStateController.isKeyguardFadingAway();
            int oldState = mBarState;
            boolean keyguardShowing = statusBarState == StatusBarState.KEYGUARD;
            setKeyguardStatusViewVisibility(statusBarState, keyguardFadingAway, goingToFullShade);
            setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade);

            mBarState = statusBarState;
            mKeyguardShowing = keyguardShowing;

            if (oldState == StatusBarState.KEYGUARD && (goingToFullShade
                    || statusBarState == StatusBarState.SHADE_LOCKED)) {
                animateKeyguardStatusBarOut();
                long
                        delay =
                        mBarState == StatusBarState.SHADE_LOCKED ? 0
                                : mKeyguardStateController.calculateGoingToFullShadeDelay();
                mQs.animateHeaderSlidingIn(delay);
            } else if (oldState == StatusBarState.SHADE_LOCKED
                    && statusBarState == StatusBarState.KEYGUARD) {
                animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
                mNotificationStackScroller.resetScrollPosition();
                // Only animate header if the header is visible. If not, it will partially
                // animate out
                // the top of QS
                if (!mQsExpanded) {
                    mQs.animateHeaderSlidingOut();
                }
            } else {
                mKeyguardStatusBar.setAlpha(1f);
                mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
                if (keyguardShowing && oldState != mBarState) {
                    if (mQs != null) {
                        mQs.hideImmediately();
                    }
                }
            }
            updateKeyguardStatusBarForHeadsUp();
            if (keyguardShowing) {
                updateDozingVisibilities(false /* animate */);
            }
            // THe update needs to happen after the headerSlide in above, otherwise the translation
            // would reset
            updateQSPulseExpansion();
            maybeAnimateBottomAreaAlpha();
            resetHorizontalPanelPosition();
            updateQsState();
            // 根据是否锁屏展示高斯模糊背景
            updateBlurVisibility(keyguardShowing);
        }

/**
     * 根据是否锁屏展示高斯模糊背景
     * @param keyguardShowing
     */
    private void updateBlurVisibility(boolean keyguardShowing){
        if (keyguardShowing) {
            mBlurView.setVisibility(View.GONE);
            BitmapUtils.recycleImageView(mBlurView);
        }else {
            mBlurView.setVisibility(View.VISIBLE);
        }
    }

工具类:

public class BitmapUtils {

    /**
     * 回收ImageView
     * @param view
     */
    public static void recycleImageView(View view) {
        if (view == null) return;
        if (view instanceof ImageView) {
            Drawable drawable = ((ImageView) view).getDrawable();
            if (drawable instanceof BitmapDrawable) {
                Bitmap bmp = ((BitmapDrawable) drawable).getBitmap();
                if (bmp != null && !bmp.isRecycled()) {
                    ((ImageView) view).setImageBitmap(null);
                    bmp.recycle();
                    bmp = null;
                }
            }
        }
    }
}
public class BlurUtil {
    private static final float BITMAP_SCALE = 0.4f;
    private static final int BLUR_RADIUS = 7;
    /**
     * 高斯模糊半径,0-25区间,越大越模糊
     */
    public static final int BLUR_RADIUS_MAX = 25;

    public static Bitmap blur(Context context, Bitmap bitmap) {
        return blur(context, bitmap, BITMAP_SCALE, BLUR_RADIUS);
    }

    public static Bitmap blur(Context context, Bitmap bitmap, float bitmap_scale) {
        return blur(context, bitmap, bitmap_scale, BLUR_RADIUS);
    }

    public static Bitmap blur(Context context, Bitmap bitmap, int blur_radius) {
        return blur(context, bitmap, BITMAP_SCALE, blur_radius);
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
    public static Bitmap blur(Context context, Bitmap bitmap, float bitmap_scale, int blur_radius) {
        Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, Math.round(bitmap.getWidth() * bitmap_scale),
                Math.round(bitmap.getHeight() * bitmap_scale), false);
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
        RenderScript rs = RenderScript.create(context);
        ScriptIntrinsicBlur theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        theIntrinsic.setRadius(blur_radius);
        theIntrinsic.setInput(tmpIn);
        theIntrinsic.forEach(tmpOut);
        tmpOut.copyTo(outputBitmap);
        rs.destroy();
        bitmap.recycle();

        return outputBitmap;
    }
}
public class ScreenShotUtil {

    /**
     * 获取截屏图片
     * @param context
     * @return
     */
    public static Bitmap takeScreenShot(Context context) {
        Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getRealMetrics(displayMetrics);
        final float[] dims = {displayMetrics.widthPixels, displayMetrics.heightPixels};
        Rect crop = new Rect(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels);
        int rot = display.getRotation();
        int width = crop.width();
        int height = crop.height();
        Bitmap bitmap = SurfaceControl.screenshot(crop, width, height, rot);
        if (bitmap != null) {
            return bitmap;
        }
        bitmap = SurfaceControl.screenshot(crop, height, width, rot);
        Matrix matrix = new Matrix();
        matrix.setRotate(-90);
        if (bitmap == null) {
            return null;
        }
        Bitmap newBM = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
        bitmap.recycle();
        return newBM;
    }

    public static Bitmap convertHardWareBitmap(Bitmap src) {
        if (src.getConfig() != Bitmap.Config.HARDWARE) {
            //return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight());
            return src;
        }
        final int w = src.getWidth();
        final int h = src.getHeight();
        // For hardware bitmaps, use the Picture API to directly create a software bitmap
        Picture picture = new Picture();
        Canvas canvas = picture.beginRecording(w, h);
        canvas.drawBitmap(src, 0, 0, null);
        picture.endRecording();
        return Bitmap.createBitmap(picture, w, h, Bitmap.Config.ARGB_8888);
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/992133.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-21
下一篇2022-05-21

发表评论

登录后才能评论

评论列表(0条)

    保存