From 27c918f1be59fa3e8306cc2cb93f286b13f4c5e7 Mon Sep 17 00:00:00 2001 From: "xiaoyan159@6800H" Date: Fri, 18 Oct 2024 13:39:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=8B=96=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E6=AF=9B=E7=8E=BB=E7=92=83=E6=95=88=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../library/splitlayout/SplitLayout.java | 103 ++++++----- .../library/splitlayout/UtilBitmap.java | 172 ++++++++++++++++++ 2 files changed, 234 insertions(+), 41 deletions(-) create mode 100644 automotive/src/main/java/com/mixiaoxiao/library/splitlayout/UtilBitmap.java diff --git a/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/SplitLayout.java b/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/SplitLayout.java index 4153cca..4edae31 100644 --- a/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/SplitLayout.java +++ b/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/SplitLayout.java @@ -72,6 +72,9 @@ public class SplitLayout extends ViewGroup { private View switchLongPressChildView = null; // 记录用户长按拖动的子View private boolean hasSwitchChild = false; // 子View是否通过手势切换完成 private long LONG_PRESS_TIME = 1200; + private Bitmap blurBitmap; // 毛玻璃效果的Bitmap + private Paint splitBgPaint = new Paint(); // 用于绘制分割线背景的画笔 + private Paint splitPressBgPaint = new Paint(); // 用于绘制分割线背景的画笔 // private Vibrator vibrator; public SplitLayout(Context context) { @@ -93,8 +96,8 @@ public class SplitLayout extends ViewGroup { mHandleDrawable = a.getDrawable(R.styleable.SplitLayout_splitHandleDrawable); if (mHandleDrawable == null) { StateListDrawable stateListDrawable = new StateListDrawable(); - stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(0x990288d1)); - stateListDrawable.addState(new int[] {}, new ColorDrawable(Color.TRANSPARENT)); + stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(getResources().getColor(R.color.draw_progress_bg_color))); + stateListDrawable.addState(new int[] {}, new ColorDrawable(getResources().getColor(R.color.material_pink_500))); stateListDrawable.setEnterFadeDuration(150); stateListDrawable.setExitFadeDuration(150); mHandleDrawable = stateListDrawable; @@ -117,6 +120,8 @@ public class SplitLayout extends ViewGroup { a.recycle(); mPaint.setColor(dragForgroundColor); + splitBgPaint.setColor(getResources().getColor(R.color.material_pink_500)); + splitPressBgPaint.setColor(getResources().getColor(R.color.material_lightblue_500)); // // 获取震动权限 // vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); // vibrator.vibrate(VibrationEffect.createOneShot(500, 125)); @@ -211,7 +216,11 @@ public class SplitLayout extends ViewGroup { mHandleDrawable.setState(PRESSED_STATE_SET); mIsDragging = true; getParent().requestDisallowInterceptTouchEvent(true); - getBitmapFromChildView(); // 截屏当前两个子View的图片,用于在拖动过程中的 +// getBitmapFromChildView(); // 截屏当前两个子View的图片,用于在拖动过程中的 + blurBitmap = getBlurBitmap(); + // 开始绘制蒙版图层 + cachedCanvas.drawColor(getContext().getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR); + cachedCanvas.drawBitmap(blurBitmap, 0, 0, null); invalidate(); } else { mIsDragging = false; @@ -362,6 +371,45 @@ public class SplitLayout extends ViewGroup { @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); + Log.d("SplitLayout", "dispatchDraw"); + if (mIsDragging) { // 开始拖动 +// // 获取两个子View的截图Bitmap +// cachedCanvas.drawColor(getContext().getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR); +// if (cachedBitmapArray != null) { +// Rect child0Rect = new Rect(); +// Rect child1Rect = new Rect(); +// if (mOrientation == VERTICAL) { +// child0Rect.set(0, 0, getWidth(), (int) (mSplitPosition - mHandleSize / 2)); +// child1Rect.set(0, (int) (mSplitPosition + mHandleSize / 2), getWidth(), getHeight()); +// } else { +// child0Rect.set(0, 0, (int) (mSplitPosition - mHandleSize / 2), getHeight()); +// child1Rect.set((int) (mSplitPosition + mHandleSize / 2), 0, getWidth(), getHeight()); +// } +// if (splitIsShowSnapshotView) { +// cachedCanvas.drawBitmap(cachedBitmapArray[0], null, child0Rect, null); +// } +// cachedCanvas.drawRect(child0Rect, mPaint); +//// cachedCanvas.drawBitmap(((BitmapDrawable)getContext().getDrawable(R.drawable.icon_app)).getBitmap(), +//// child0Rect.centerX() - (getContext().getDrawable(R.drawable.icon_app).getBounds().width()/2), +//// child0Rect.centerY() - (getContext().getDrawable(R.drawable.icon_app).getBounds().height()/2), null); +// if (splitIsShowSnapshotView) { +// cachedCanvas.drawBitmap(cachedBitmapArray[1], null, child1Rect, null); +// } +// cachedCanvas.drawRect(child1Rect, mPaint); +//// cachedCanvas.drawBitmap(((BitmapDrawable)getContext().getDrawable(R.drawable.icon_app)).getBitmap(), +//// child1Rect.centerX() - (getContext().getDrawable(R.drawable.icon_app).getBounds().width()/2), +//// child1Rect.centerY() - (getContext().getDrawable(R.drawable.icon_app).getBounds().height()/2), null); +// canvas.drawBitmap(cachedBitmap, 0, 0, null); +// } + canvas.drawBitmap(cachedBitmap, 0, 0, null); + } else if (mIsSwitching) { // 开始拖动切换 + if (hasSwitchChild) { + resetChildSnapshotBitmap(canvas, true); + } else { + resetChildSnapshotBitmap(canvas, false); + } + } + if (mSplitPosition != INVAID_SPLITPOSITION && mHandleDrawable != null) { final int splitPosition = Math.round(mSplitPosition); if (mOrientation == VERTICAL) { @@ -369,46 +417,12 @@ public class SplitLayout extends ViewGroup { } else { mHandleDrawable.setBounds(splitPosition - mHandleSize / 2, 0, splitPosition + mHandleSize / 2, mHeight); } - mHandleDrawable.draw(canvas); - } - - Log.d("SplitLayout", "dispatchDraw"); - if (mIsDragging) { // 开始拖动 - // 获取两个子View的截图Bitmap - cachedCanvas.drawColor(getContext().getColor(android.R.color.transparent), PorterDuff.Mode.CLEAR); - if (cachedBitmapArray != null) { - Rect child0Rect = new Rect(); - Rect child1Rect = new Rect(); - if (mOrientation == VERTICAL) { - child0Rect.set(0, 0, getWidth(), (int) (mSplitPosition - mHandleSize / 2)); - child1Rect.set(0, (int) (mSplitPosition + mHandleSize / 2), getWidth(), getHeight()); - } else { - child0Rect.set(0, 0, (int) (mSplitPosition - mHandleSize / 2), getHeight()); - child1Rect.set((int) (mSplitPosition + mHandleSize / 2), 0, getWidth(), getHeight()); - } - if (splitIsShowSnapshotView) { - cachedCanvas.drawBitmap(cachedBitmapArray[0], null, child0Rect, null); - } - cachedCanvas.drawRect(child0Rect, mPaint); -// cachedCanvas.drawBitmap(((BitmapDrawable)getContext().getDrawable(R.drawable.icon_app)).getBitmap(), -// child0Rect.centerX() - (getContext().getDrawable(R.drawable.icon_app).getBounds().width()/2), -// child0Rect.centerY() - (getContext().getDrawable(R.drawable.icon_app).getBounds().height()/2), null); - if (splitIsShowSnapshotView) { - cachedCanvas.drawBitmap(cachedBitmapArray[1], null, child1Rect, null); - } - cachedCanvas.drawRect(child1Rect, mPaint); -// cachedCanvas.drawBitmap(((BitmapDrawable)getContext().getDrawable(R.drawable.icon_app)).getBitmap(), -// child1Rect.centerX() - (getContext().getDrawable(R.drawable.icon_app).getBounds().width()/2), -// child1Rect.centerY() - (getContext().getDrawable(R.drawable.icon_app).getBounds().height()/2), null); - canvas.drawBitmap(cachedBitmap, 0, 0, null); - } - - } else if (mIsSwitching) { // 开始拖动切换 - if (hasSwitchChild) { - resetChildSnapshotBitmap(canvas, true); + if (mIsDragging) { + canvas.drawRect(mHandleDrawable.getBounds(),splitPressBgPaint); } else { - resetChildSnapshotBitmap(canvas, false); + canvas.drawRect(mHandleDrawable.getBounds(),splitBgPaint); } + mHandleDrawable.draw(canvas); } } @@ -493,6 +507,13 @@ public class SplitLayout extends ViewGroup { } } + // 获取高斯模糊的bitmap图片 + private Bitmap getBlurBitmap() { + // 先获取当前界面的整体截图 + Bitmap currentBitmap = loadBitmapFromViewBySystem(this); + return UtilBitmap.blurBitmap(getContext(), currentBitmap, 20f); + } + /** *此方法直接截取屏幕指定view区域的内容 * @param view 需要截取屏幕的图片view diff --git a/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/UtilBitmap.java b/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/UtilBitmap.java new file mode 100644 index 0000000..24dedac --- /dev/null +++ b/automotive/src/main/java/com/mixiaoxiao/library/splitlayout/UtilBitmap.java @@ -0,0 +1,172 @@ +package com.mixiaoxiao.library.splitlayout; + + +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.RectF; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; +import android.renderscript.Allocation; +import android.renderscript.Element; +import android.renderscript.RenderScript; +import android.renderscript.ScriptIntrinsicBlur; +import android.util.Log; +import android.widget.ImageView; + +/** + * 图片工具类 + *

+ * Created by Bamboy on 2017/04/01. + */ +public class UtilBitmap { + /** + * 图片缩放比例 + */ + private static final float BITMAP_SCALE = 1f; + + /** + * 将Drawable对象转化为Bitmap对象 + * + * @param drawable Drawable对象 + * @return 对应的Bitmap对象 + */ + private static Bitmap drawableToBitmap(Drawable drawable) { + Bitmap bitmap; + + //如果本身就是BitmapDrawable类型 直接转换即可 + if (drawable instanceof BitmapDrawable) { + BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; + if (bitmapDrawable.getBitmap() != null) { + return bitmapDrawable.getBitmap(); + } + } + + //取得Drawable固有宽高 + if (drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) { + //创建一个1x1像素的单位色图 + bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); + } else { + //直接设置一下宽高和ARGB + bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); + } + + //重新绘制Bitmap + Canvas canvas = new Canvas(bitmap); + drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight()); + drawable.draw(canvas); + return bitmap; + } + + + /** + * 模糊ImageView + * + * @param context + * @param img ImageView + * @param level 模糊等级【0 ~ 25之间】 + */ + public static void blurImageView(Context context, ImageView img, float level) { + // 将图片处理成模糊 + Bitmap bitmap = blurBitmap(context, drawableToBitmap(img.getDrawable()), level); + if (bitmap != null) { + img.setImageBitmap(bitmap); + } + } + + /** + * 模糊ImageView + * + * @param context + * @param img ImageView + * @param level 模糊等级【0 ~ 25之间】 + * @param color 为ImageView蒙上一层颜色 + */ + public static void blurImageView(Context context, ImageView img, float level, int color) { + // 将图片处理成模糊 + Bitmap bitmap = blurBitmap(context, drawableToBitmap(img.getDrawable()), level); + if (bitmap != null) { + Drawable drawable = coverColor(context, bitmap, color); + img.setScaleType(ImageView.ScaleType.FIT_XY); + img.setImageDrawable(drawable); + } else { + img.setImageBitmap(null); + img.setBackgroundColor(color); + } + } + + /** + * 将bitmap转成蒙上颜色的Drawable + * + * @param context + * @param bitmap + * @param color 要蒙上的颜色 + * @return Drawable + */ + public static Drawable coverColor(Context context, Bitmap bitmap, int color) { + Paint paint = new Paint(); + paint.setColor(color); + RectF rect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight()); + new Canvas(bitmap).drawRoundRect(rect, 0, 0, paint); + return new BitmapDrawable(context.getResources(), bitmap); + } + + + /** + * 模糊图片的具体方法 + * + * @param context 上下文对象 + * @param bitmap 需要模糊的图片 + * @return 模糊处理后的图片 + */ + public static Bitmap blurBitmap(Context context, Bitmap bitmap, float blurRadius) { + if (blurRadius < 0) { + blurRadius = 0; + } + if (blurRadius > 25) { + blurRadius = 25; + } + Bitmap outputBitmap = null; + try { + + Class.forName("android.renderscript.ScriptIntrinsicBlur"); + // 计算图片缩小后的长宽 + int width = Math.round(bitmap.getWidth() * BITMAP_SCALE); + int height = Math.round(bitmap.getHeight() * BITMAP_SCALE); + if (width < 2 || height < 2) { + return null; + } + + // 将缩小后的图片做为预渲染的图片。 + Bitmap inputBitmap = Bitmap.createScaledBitmap(bitmap, width, height, false); + // 创建一张渲染后的输出图片。 + outputBitmap = Bitmap.createBitmap(inputBitmap); + + // 创建RenderScript内核对象 + RenderScript rs = RenderScript.create(context); + // 创建一个模糊效果的RenderScript的工具对象 + ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs)); + + // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间。 + // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去。 + Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap); + Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap); + + // 设置渲染的模糊程度, 25f是最大模糊度 + blurScript.setRadius(blurRadius); + // 设置blurScript对象的输入内存 + blurScript.setInput(tmpIn); + // 将输出数据保存到输出内存中 + blurScript.forEach(tmpOut); + + // 将数据填充到Allocation中 + tmpOut.copyTo(outputBitmap); + + return outputBitmap; + } catch (Exception e) { + Log.e("Bemboy_Error", "Android版本过低"); + return null; + } + } +}