Android 多任务列表高斯模糊

2,234 阅读2分钟

现状

金融类App可能需实现多任务列表高斯模糊,因android碎片化严重,国内android厂商会在系统级实现,了解下市面上只有微众银行实现该效果,但也无法实现手势导航监听,按键导航在不用设备下表现效果也不同,会有偶发失效的情况。以下为功能具体实现,最终效果类似微众银行。

实现

广播监听多任务键与Home键

public class DeviceKeyMonitor {
    private static final String SYSTEM_REASON = "reason";
    private static final String SYSTEM_HOME_RECENT_APPS = "recentapps";
    private static final String SYSTEM_HOME_KEY = "homekey";
    private Context mContext;
    private BroadcastReceiver mDeviceKeyReceiver;
    private OnKeyListener mListener;

    public DeviceKeyMonitor(Context context, final OnKeyListener listener) {
        mContext = context;
        mListener = listener;
        mDeviceKeyReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (!TextUtils.isEmpty(action)) {

                    if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(intent.getAction())) {
                        String reason = intent.getStringExtra(SYSTEM_REASON);
                        if (reason == null)
                            return;
                        if (SYSTEM_HOME_RECENT_APPS.equals(reason) || SYSTEM_HOME_KEY.equals(reason)) {
                            mListener.onRecentClick();

                        }
                    }
                }
            }
        };
        mContext.registerReceiver(mDeviceKeyReceiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
    }

    public interface OnKeyListener {
        void onRecentClick();
    }

    public void unregister() {
        if (mDeviceKeyReceiver != null) {
            mContext.unregisterReceiver(mDeviceKeyReceiver);
            mDeviceKeyReceiver = null;
        }
    }

}

高斯模糊处理当前页面

注:这里并未使用高斯模糊,使用一张默认资源图代替,可根据业务需求调整

public class BgBlurUtils {

    public static Bitmap activityShot(Activity activity) {
        /*获取windows中最顶层的view*/
        View view = activity.getWindow().getDecorView();

        //允许当前窗口保存缓存信息
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();

        //获取状态栏高度
        Rect rect = new Rect();
        view.getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;

        WindowManager windowManager = activity.getWindowManager();

        //获取屏幕宽和高
        DisplayMetrics outMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(outMetrics);
        int width = outMetrics.widthPixels;
        int height = outMetrics.heightPixels;
        Bitmap blurBitmap = BitmapFactory.decodeResource(activity.getResources(), R.drawable.splash_blur);


        //去掉状态栏
//        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache(), 0, 0, width, height);
//        Bitmap bitmap = Bitmap.createBitmap(bitmap1, 0, 0, width, height);
//        Bitmap bitmap = BitmapFactory.decodeResource(activity.getResources(),R.drawable.splash_blur);

        //销毁缓存信息
        view.destroyDrawingCache();
        view.setDrawingCacheEnabled(false);


        return blurBitmap;
    }

    public static Bitmap rsBlur(Context context, Bitmap source, int radius) {
        Bitmap inputBmp = source;
//        //(1)
//        //初始化一个RenderScript Context
//        RenderScript renderScript = RenderScript.create(context);
//
//        // Allocate memory for Renderscript to work with
//        //(2)
//        //创建输入输出的allocation
//        final Allocation input = Allocation.createFromBitmap(renderScript, inputBmp);
//        final Allocation output = Allocation.createTyped(renderScript, input.getType());
//        //(3)
//        // Load up an instance of the specific script that we want to use.
//        //创建ScriptIntrinsic
//        ScriptIntrinsicBlur scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript));
//        //(4)
//        //填充数据
//        scriptIntrinsicBlur.setInput(input);
//        //(5)
//        // Set the blur radius
//        //设置模糊半径
//        scriptIntrinsicBlur.setRadius(radius);
//        //(6)
//        // Start the ScriptIntrinisicBlur
//        //启动内核
//        scriptIntrinsicBlur.forEach(output);
//        //(7)
//        // Copy the output to the blurred bitmap
//        //copy数据
//        output.copyTo(inputBmp);
//        //(8)
//        //销毁renderScript
//        renderScript.destroy();
        return inputBmp;

    }

}

注册

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    deviceKeyMonitor = new DeviceKeyMonitor(this, this);//注册
    bitmap = BgBlurUtils.rsBlur(this, BgBlurUtils.activityShot(this), 20);//初始图片
}

接口实现

  @Override
    public void onRecentClick() {
        group = (ViewGroup) activity.getWindow().getDecorView();
        group.removeView(bgImage);
        bgImage = new ImageView(activity);
        Rect rect = new Rect();
        group.getWindowVisibleDisplayFrame(rect);
        int statusBarHeight = rect.top;
        WindowManager windowManager = activity.getWindowManager();
        //获取屏幕宽和高
        DisplayMetrics outMetrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getMetrics(outMetrics);
        int width = outMetrics.widthPixels;
        int height = outMetrics.heightPixels
        
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(width, height + statusBarHeight);
        bgImage.setLayoutParams(params);
        bgImage.setBackgroundColor(activity.getResources().getColor(R.color.white));
        if (bitmap != null) {
            bgImage.setImageBitmap(bitmap);
            group.addView(bgImage);
        }
    }

移除

@Override
protected void onResume() {
    super.onResume();
    if (group == null || group.getChildCount() <= 0) {
        return;
    }
    for (int i = 0; i < group.getChildCount(); i++) {
        group.removeView(bgImage);
    }
}

注销


@Override
protected void onDestroy() {
    super.onDestroy();
    deviceKeyMonitor.unregister();
}