66import androidx .core .content .ContextCompat ;
77import com .tool .tree .R ;
88import android .content .Context ;
9- import android .util .DisplayMetrics ;
109
1110public final class BlurEngine {
1211 public static BlurController controller = new BlurController ();
1312 public static volatile Bitmap blurBitmap ;
14- public static boolean isPaused = false ; // Mặc định để false để có thể chạy ngay
13+ public static boolean isPaused = false ;
1514
1615 public static float DEFAULT_CORNER_RADIUS = 30.0f ;
1716 public float cornerRadius = DEFAULT_CORNER_RADIUS ;
1817
1918 private View targetView ;
2019 private int [] location = new int [2 ];
20+ private int [] parentLocation = new int [2 ];
2121 private Rect srcRect = new Rect ();
2222 private Bitmap cachedBitmap ;
2323 private Canvas cachedCanvas ;
@@ -44,29 +44,31 @@ public Bitmap getUpdatedBlurBitmap() {
4444 return null ;
4545 }
4646
47- // Lấy tọa độ tuyệt đối trên màn hình thay vì trong Window
47+ // Lấy RootView thực sự (thường là DecorView của Window)
48+ View rootView = targetView .getRootView ();
49+ if (rootView == null ) return null ;
50+
51+ // Lấy vị trí của View hiện tại trên màn hình
4852 targetView .getLocationOnScreen (location );
4953
50- Context context = targetView .getContext ();
51- DisplayMetrics dm = context .getResources ().getDisplayMetrics ();
52-
53- // Tính tỷ lệ dựa trên kích thước thực tế của màn hình (Screen Metrics)
54- // Điều này đảm bảo ảnh blur khớp 1:1 với Wallpaper gốc phía sau
55- float scaleX = (float ) blurBitmap .getWidth () / dm .widthPixels ;
56- float scaleY = (float ) blurBitmap .getHeight () / dm .heightPixels ;
54+ // Tỷ lệ giữa Bitmap blur (đã thu nhỏ) và kích thước thực tế của RootView
55+ // Điều này đảm bảo dù ScrollView dài bao nhiêu, vị trí vẫn khớp với Wallpaper phía sau DecorView
56+ float scaleX = (float ) blurBitmap .getWidth () / rootView .getWidth ();
57+ float scaleY = (float ) blurBitmap .getHeight () / rootView .getHeight ();
5758
5859 int w = (int ) (targetView .getWidth () * scaleX );
5960 int h = (int ) (targetView .getHeight () * scaleY );
61+
62+ // Tính toán tọa độ cắt dựa trên vị trí tuyệt đối trên màn hình
6063 int x = (int ) (location [0 ] * scaleX );
6164 int y = (int ) (location [1 ] * scaleY );
6265
63- // Giới hạn vùng cắt để không bị OutOfBounds
66+ // Chống tràn biên Bitmap
6467 x = Math .max (0 , Math .min (x , blurBitmap .getWidth () - w ));
6568 y = Math .max (0 , Math .min (y , blurBitmap .getHeight () - h ));
6669
6770 if (w > 0 && h > 0 ) {
6871 try {
69- // Chỉ khởi tạo lại cachedBitmap khi kích thước view thay đổi (rất quan trọng cho ScrollView)
7072 if (cachedBitmap == null || cachedBitmap .getWidth () != w || cachedBitmap .getHeight () != h ) {
7173 if (cachedBitmap != null ) cachedBitmap .recycle ();
7274 cachedBitmap = Bitmap .createBitmap (w , h , Bitmap .Config .ARGB_8888 );
@@ -75,9 +77,12 @@ public Bitmap getUpdatedBlurBitmap() {
7577
7678 srcRect .set (x , y , x + w , y + h );
7779 cachedCanvas .drawColor (0 , PorterDuff .Mode .CLEAR );
80+
81+ // Vẽ vùng tương ứng của ảnh nền vào cachedBitmap
7882 cachedCanvas .drawBitmap (blurBitmap , srcRect , new Rect (0 , 0 , w , h ), null );
79- cachedCanvas .drawColor (getBlurTintColor ());
8083
84+ // Phủ lớp màu (Tint)
85+ cachedCanvas .drawColor (getBlurTintColor ());
8186 return cachedBitmap ;
8287 } catch (Exception e ) {
8388 return null ;
@@ -98,14 +103,9 @@ public static Paint getStrokePaint(Context context) {
98103 strokePaint .setStyle (Paint .Style .STROKE );
99104 strokePaint .setStrokeWidth (3.0f );
100105 }
101-
102106 int colorRes = ThemeModeState .isDarkMode () ? R .color .colorPirmLight : R .color .colorPirmDark ;
103107 int color = ContextCompat .getColor (context , colorRes );
104-
105- if (strokePaint .getColor () != color ) {
106- strokePaint .setColor (color );
107- }
108-
108+ if (strokePaint .getColor () != color ) strokePaint .setColor (color );
109109 return strokePaint ;
110110 }
111111
0 commit comments