feat: 添加拖动时毛玻璃效果
This commit is contained in:
parent
bd3e498888
commit
27c918f1be
@ -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,47 +417,13 @@ public class SplitLayout extends ViewGroup {
|
||||
} else {
|
||||
mHandleDrawable.setBounds(splitPosition - mHandleSize / 2, 0, splitPosition + mHandleSize / 2, mHeight);
|
||||
}
|
||||
if (mIsDragging) {
|
||||
canvas.drawRect(mHandleDrawable.getBounds(),splitPressBgPaint);
|
||||
} else {
|
||||
canvas.drawRect(mHandleDrawable.getBounds(),splitBgPaint);
|
||||
}
|
||||
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);
|
||||
} else {
|
||||
resetChildSnapshotBitmap(canvas, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkSplitFraction() {
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
/**
|
||||
* 图片工具类
|
||||
* <p>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user