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 View switchLongPressChildView = null; // 记录用户长按拖动的子View
|
||||||
private boolean hasSwitchChild = false; // 子View是否通过手势切换完成
|
private boolean hasSwitchChild = false; // 子View是否通过手势切换完成
|
||||||
private long LONG_PRESS_TIME = 1200;
|
private long LONG_PRESS_TIME = 1200;
|
||||||
|
private Bitmap blurBitmap; // 毛玻璃效果的Bitmap
|
||||||
|
private Paint splitBgPaint = new Paint(); // 用于绘制分割线背景的画笔
|
||||||
|
private Paint splitPressBgPaint = new Paint(); // 用于绘制分割线背景的画笔
|
||||||
// private Vibrator vibrator;
|
// private Vibrator vibrator;
|
||||||
|
|
||||||
public SplitLayout(Context context) {
|
public SplitLayout(Context context) {
|
||||||
@ -93,8 +96,8 @@ public class SplitLayout extends ViewGroup {
|
|||||||
mHandleDrawable = a.getDrawable(R.styleable.SplitLayout_splitHandleDrawable);
|
mHandleDrawable = a.getDrawable(R.styleable.SplitLayout_splitHandleDrawable);
|
||||||
if (mHandleDrawable == null) {
|
if (mHandleDrawable == null) {
|
||||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
StateListDrawable stateListDrawable = new StateListDrawable();
|
||||||
stateListDrawable.addState(new int[] { android.R.attr.state_pressed }, new ColorDrawable(0x990288d1));
|
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(Color.TRANSPARENT));
|
stateListDrawable.addState(new int[] {}, new ColorDrawable(getResources().getColor(R.color.material_pink_500)));
|
||||||
stateListDrawable.setEnterFadeDuration(150);
|
stateListDrawable.setEnterFadeDuration(150);
|
||||||
stateListDrawable.setExitFadeDuration(150);
|
stateListDrawable.setExitFadeDuration(150);
|
||||||
mHandleDrawable = stateListDrawable;
|
mHandleDrawable = stateListDrawable;
|
||||||
@ -117,6 +120,8 @@ public class SplitLayout extends ViewGroup {
|
|||||||
a.recycle();
|
a.recycle();
|
||||||
|
|
||||||
mPaint.setColor(dragForgroundColor);
|
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 = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
|
||||||
// vibrator.vibrate(VibrationEffect.createOneShot(500, 125));
|
// vibrator.vibrate(VibrationEffect.createOneShot(500, 125));
|
||||||
@ -211,7 +216,11 @@ public class SplitLayout extends ViewGroup {
|
|||||||
mHandleDrawable.setState(PRESSED_STATE_SET);
|
mHandleDrawable.setState(PRESSED_STATE_SET);
|
||||||
mIsDragging = true;
|
mIsDragging = true;
|
||||||
getParent().requestDisallowInterceptTouchEvent(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();
|
invalidate();
|
||||||
} else {
|
} else {
|
||||||
mIsDragging = false;
|
mIsDragging = false;
|
||||||
@ -362,6 +371,45 @@ public class SplitLayout extends ViewGroup {
|
|||||||
@Override
|
@Override
|
||||||
protected void dispatchDraw(Canvas canvas) {
|
protected void dispatchDraw(Canvas canvas) {
|
||||||
super.dispatchDraw(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) {
|
if (mSplitPosition != INVAID_SPLITPOSITION && mHandleDrawable != null) {
|
||||||
final int splitPosition = Math.round(mSplitPosition);
|
final int splitPosition = Math.round(mSplitPosition);
|
||||||
if (mOrientation == VERTICAL) {
|
if (mOrientation == VERTICAL) {
|
||||||
@ -369,47 +417,13 @@ public class SplitLayout extends ViewGroup {
|
|||||||
} else {
|
} else {
|
||||||
mHandleDrawable.setBounds(splitPosition - mHandleSize / 2, 0, splitPosition + mHandleSize / 2, mHeight);
|
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);
|
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() {
|
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区域的内容
|
*此方法直接截取屏幕指定view区域的内容
|
||||||
* @param view 需要截取屏幕的图片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