模糊、水波纹、折叠实现思路

  • 1.通过getWindow().getDecorView()可以获得最顶层的视图,在调用getDrawingCache()方法即可获取Bitmap,再对该Bitmap进行相关的处理并显示在一个ImageView上
  • 2.设置Activity切换不展示动画
1
2
currActivity.startActivity(intent);
currActivity.overridePendingTransition(0, 0);

模糊

1.创建一个匹配父窗口的ImageView

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private ImageView createImageView(Activity destActivity, Bitmap bmp) {
ImageView imageView = new ImageView(destActivity);
imageView.setImageBitmap(bmp);
imageView.setScaleType(ScaleType.FIT_XY);
WindowManager.LayoutParams windowParams = new WindowManager.LayoutParams();
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = top;
windowParams.height = bmp.getHeight();
windowParams.width = bmp.getWidth();
windowParams.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
windowParams.format = PixelFormat.TRANSLUCENT;
windowParams.windowAnimations = 0;
destActivity.getWindowManager().addView(imageView, windowParams);
return imageView;
}

2.模糊处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
if (VERSION.SDK_INT > 16) {
Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
final RenderScript rs = RenderScript.create(context);
final Allocation input = Allocation.createFromBitmap(rs, sentBitmap, Allocation.MipmapControl.MIPMAP_NONE,
Allocation.USAGE_SCRIPT);
final Allocation output = Allocation.createTyped(rs, input.getType());
final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
script.setRadius(radius);
script.setInput(input);
script.forEach(output);
output.copyTo(bitmap);
return bitmap;
}

16以下版本可使用v8包


水波纹

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
public class DrawWaterWaveWithSina extends ImageView implements Runnable {
boolean isRunning = false;
private final static double TWO_PI = Math.PI * 2;
private int width;
private int height;
private int[] mBitmap2;
private int[] mBitmap1;
private float wavelength = 36;
private float amplitude = 10;
private float phase = 0;
private int radius = 5;
private int radius2 = 0;
private int icentreX;
private int icentreY;
private int alpha = 255;
private Paint mPaint;
private boolean flag = true;
private Activity mActivity;
private int SCALE = 3;
public DrawWaterWaveWithSina(Activity context, Bitmap bmp) {
super(context);
mPaint = new Paint();
Bitmap image = bmp;
width = image.getWidth() / SCALE;
height = image.getHeight() / SCALE;
mActivity = context;
mBitmap2 = new int[width * height];
mBitmap1 = new int[width * height];
Bitmap scaledBitmap = Bitmap.createScaledBitmap(image, width, height, false);
scaledBitmap.getPixels(mBitmap1, 0, width, 0, 0, width, height);
for (int i = 0; i < width * height; i++) {
mBitmap2[i] = mBitmap1[i];
}
setImageBitmap(Bitmap.createBitmap(mBitmap2, 0, width, width, height, Bitmap.Config.ARGB_8888));
}
private boolean transformInverse(int x, int y, int[] out) {
int dx = x - icentreX;
int dy = y - icentreY;
int distance2 = dx * dx + dy * dy;
if (distance2 > radius2) {
out[0] = x;
out[1] = y;
out[2] = 0;
return false;
} else {
float distance = (float) Math.sqrt(distance2);
float amount = amplitude * (float) Math.sin(distance / wavelength * TWO_PI - phase / TWO_PI);
amount *= (radius - distance) / radius;
out[0] = (int) (x + dx * amount);
out[1] = (int) (y + dy * amount);
out[2] = (int) distance;
return true;
}
}
private void createNextBitmap() {
int[] temp = new int[3];
for (int i = 0; i < width; i++)
for (int j = 0; j < height; j++) {
if (transformInverse(i, j, temp)) {
if (temp[0] >= width || temp[1] >= height || temp[0] < 0 || temp[1] < 0) {
mBitmap2[j * width + i] = 0x00000000;
} else {
mBitmap2[j * width + i] = (mBitmap1[temp[1] * width + temp[0]] & 0x00ffffff)
+ (alpha << 24);
}
} else {
if (temp[0] >= width || temp[1] >= height || temp[0] < 0 || temp[1] < 0) {
mBitmap2[j * width + i] = 0x00000000;
} else {
mBitmap2[j * width + i] = mBitmap1[temp[1] * width + temp[0]];
}
}
}
}
@Override
public void run() {
isRunning = true;
while (flag) {
try {
Thread.sleep(30);
} catch (Exception e) {
}
phase += 5;
radius += 5;
amplitude /= 1.12;
if (amplitude < 0.01) {
stop();
return;
}
if (alpha > 0) {
alpha -= 5;
} else {
alpha = 0;
}
radius2 = radius * radius;
long start = System.currentTimeMillis();
createNextBitmap();
post(new Runnable() {
@Override
public void run() {
setImageBitmap(Bitmap.createBitmap(mBitmap2, 0, width, width, height, Bitmap.Config.ARGB_8888));
}
});
System.out.println("duration:" + (System.currentTimeMillis() - start));
postInvalidate();
}
}
private void stop() {
flag = false;
if (this.getParent() != null) {
this.post(new Runnable() {
@Override
public void run() {
mActivity.getWindowManager().removeView(DrawWaterWaveWithSina.this);
}
});
}
}
public void start(int x, int y) {
icentreX = x / SCALE;
icentreY = y / SCALE;
Thread t = new Thread(this);
t.start();
}
}

折叠

该效果则是在之前的基础上,又增加了手势的操作;像微信那样可以两级Activity联动的效果,可能也是在下层生成了图片,滑动时底层图片也跟随滚动


待更新