@@ -17,8 +17,6 @@ public final class BlurEngine {
1717
1818 private View targetView ;
1919 private int [] location = new int [2 ];
20- private int [] parentLocation = new int [2 ];
21- private Rect srcRect = new Rect ();
2220 private Bitmap cachedBitmap ;
2321 private Canvas cachedCanvas ;
2422 private static Paint strokePaint ;
@@ -44,41 +42,52 @@ public Bitmap getUpdatedBlurBitmap() {
4442 return null ;
4543 }
4644
47- // Lấy RootView thực sự (thường là DecorView của Window)
45+ // Lấy RootView để tính toán tỷ lệ chính xác giữa màn hình và BlurBitmap
4846 View rootView = targetView .getRootView ();
4947 if (rootView == null ) return null ;
48+
5049 targetView .getLocationOnScreen (location );
50+
5151 float scaleX = (float ) blurBitmap .getWidth () / rootView .getWidth ();
5252 float scaleY = (float ) blurBitmap .getHeight () / rootView .getHeight ();
5353
54+ // Kích thước thực tế của vùng Blur trên View
5455 int w = (int ) (targetView .getWidth () * scaleX );
5556 int h = (int ) (targetView .getHeight () * scaleY );
57+
58+ // Tọa độ thực tế (cho phép giá trị âm khi vuốt ra ngoài biên)
5659 int x = (int ) (location [0 ] * scaleX );
5760 int y = (int ) (location [1 ] * scaleY );
5861
59- // Chống tràn biên Bitmap
60- x = Math .max (0 , Math .min (x , blurBitmap .getWidth () - w ));
61- y = Math .max (0 , Math .min (y , blurBitmap .getHeight () - h ));
62+ try {
63+ // Khởi tạo hoặc tái sử dụng cachedBitmap theo kích thước View
64+ if (cachedBitmap == null || cachedBitmap .getWidth () != w || cachedBitmap .getHeight () != h ) {
65+ if (cachedBitmap != null ) cachedBitmap .recycle ();
66+ cachedBitmap = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
67+ cachedCanvas = new Canvas (cachedBitmap );
68+ }
69+
70+ // Xóa canvas cũ
71+ cachedCanvas .drawColor (0 , PorterDuff .Mode .CLEAR );
72+
73+ /**
74+ * GIẢI PHÁP CHO VẤN ĐỀ 4:
75+ * Thay vì dùng srcRect cắt giới hạn trong Bitmap, ta dịch chuyển Canvas.
76+ * Chúng ta dịch chuyển ngược một khoảng đúng bằng tọa độ của View trên màn hình.
77+ * Điều này đảm bảo ảnh nền luôn khớp với vị trí của View bất kể View ở đâu.
78+ */
79+ cachedCanvas .save ();
80+ cachedCanvas .translate (-x , -y );
81+ cachedCanvas .drawBitmap (blurBitmap , 0 , 0 , null );
82+ cachedCanvas .restore ();
6283
63- if (w > 0 && h > 0 ) {
64- try {
65- if (cachedBitmap == null || cachedBitmap .getWidth () != w || cachedBitmap .getHeight () != h ) {
66- if (cachedBitmap != null ) cachedBitmap .recycle ();
67- cachedBitmap = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
68- cachedCanvas = new Canvas (cachedBitmap );
69- }
84+ // Phủ lớp màu (Tint) lên trên lớp blur
85+ cachedCanvas .drawColor (getBlurTintColor ());
7086
71- srcRect .set (x , y , x + w , y + h );
72- cachedCanvas .drawColor (0 , PorterDuff .Mode .CLEAR );
73-
74- cachedCanvas .drawBitmap (blurBitmap , srcRect , new Rect (0 , 0 , w , h ), null );
75- cachedCanvas .drawColor (getBlurTintColor ());
76- return cachedBitmap ;
77- } catch (Exception e ) {
78- return null ;
79- }
87+ return cachedBitmap ;
88+ } catch (Exception e ) {
89+ return null ;
8090 }
81- return null ;
8291 }
8392
8493 private int getBlurTintColor () {
0 commit comments