diff --git a/.idea/deploymentTargetSelector.xml b/.idea/deploymentTargetSelector.xml
index b268ef3..08c51b4 100644
--- a/.idea/deploymentTargetSelector.xml
+++ b/.idea/deploymentTargetSelector.xml
@@ -4,6 +4,14 @@
+
+
+
+
+
+
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
index 0ad17cb..f351441 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,4 +7,11 @@
+
+
+
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6f45e8f..30a4019 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,11 +1,9 @@
-
-
+ xmlns:tools="http://schemas.android.com/tools">
+
-
+ android:usesCleartextTraffic="true"
+ tools:targetApi="31">
+
+
+
+ android:exported="true"
+ android:theme="@style/MainActivity">
diff --git a/app/src/main/java/com/example/androiddemo/Function.java b/app/src/main/java/com/example/androiddemo/Function.java
index c4e1d81..46d07c0 100644
--- a/app/src/main/java/com/example/androiddemo/Function.java
+++ b/app/src/main/java/com/example/androiddemo/Function.java
@@ -1,6 +1,8 @@
package com.example.androiddemo;
-import com.example.androiddemo.activity.Toast;
+import com.example.androiddemo.activity.DefPopup;
+import com.example.androiddemo.activity.Dialog;
+import com.example.androiddemo.activity.DefToast;
import java.util.ArrayList;
import java.util.List;
@@ -20,7 +22,9 @@ public class Function {
}
public static void init() {
- list.add(new Function("多样化提示", Toast.class));
+ list.add(new Function("多样化提示", DefToast.class));
+ list.add(new Function("毛玻璃弹窗", Dialog.class));
+ list.add(new Function("自定义Popup", DefPopup.class));
}
diff --git a/app/src/main/java/com/example/androiddemo/activity/DefPopup.java b/app/src/main/java/com/example/androiddemo/activity/DefPopup.java
new file mode 100644
index 0000000..2577477
--- /dev/null
+++ b/app/src/main/java/com/example/androiddemo/activity/DefPopup.java
@@ -0,0 +1,49 @@
+package com.example.androiddemo.activity;
+
+import android.animation.AnimatorInflater;
+import android.animation.AnimatorSet;
+import android.app.Activity;
+import android.os.Bundle;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.PopupWindow;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.PopupMenu;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.example.androiddemo.R;
+
+public class DefPopup extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_def_popup);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ findViewById(R.id.btn_custom).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ PopupMenu popupMenu = new PopupMenu(DefPopup.this, v);
+ popupMenu.getMenuInflater().inflate(R.menu.popup_menu, popupMenu.getMenu());
+ popupMenu.setOnMenuItemClickListener(item -> {
+ Toast.makeText(DefPopup.this, item.getTitle(), Toast.LENGTH_SHORT).show();
+ return true;
+ });
+ popupMenu.show();
+ }
+ });
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/example/androiddemo/activity/Toast.java b/app/src/main/java/com/example/androiddemo/activity/DefToast.java
similarity index 78%
rename from app/src/main/java/com/example/androiddemo/activity/Toast.java
rename to app/src/main/java/com/example/androiddemo/activity/DefToast.java
index d25e8d7..28dd3d7 100644
--- a/app/src/main/java/com/example/androiddemo/activity/Toast.java
+++ b/app/src/main/java/com/example/androiddemo/activity/DefToast.java
@@ -3,19 +3,11 @@ package com.example.androiddemo.activity;
import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
-import android.app.Dialog;
-import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
-import android.renderscript.Allocation;
-import android.renderscript.Element;
-import android.renderscript.RenderScript;
-import android.renderscript.ScriptIntrinsicBlur;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import androidx.activity.EdgeToEdge;
@@ -25,7 +17,6 @@ import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
-import com.bumptech.glide.Glide;
import com.example.androiddemo.R;
import com.example.androiddemo.databinding.ViewToastBinding;
import com.google.android.material.card.MaterialCardView;
@@ -33,7 +24,7 @@ import com.google.android.material.card.MaterialCardView;
/**
* 多样化提示界面
*/
-public class Toast extends AppCompatActivity {
+public class DefToast extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -45,7 +36,6 @@ public class Toast extends AppCompatActivity {
v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
return insets;
});
- View viewById = findViewById(R.id.TopToast);
LinearLayout linearLayout = findViewById(R.id.line1);
// 屏幕的宽度/2
@@ -57,11 +47,18 @@ public class Toast extends AppCompatActivity {
layoutParams.setMargins(0, 20, 0, 0);
layoutParams.gravity = Gravity.CENTER_HORIZONTAL;
- viewById.setOnClickListener(v -> linearLayout.addView(NewToast("测试"), 0, layoutParams));
+ findViewById(R.id.TopToast).setOnClickListener(v -> {
+ linearLayout.setGravity(Gravity.CENTER_HORIZONTAL);
+ linearLayout.addView(NewToast("测试"), 0, layoutParams);
+ });
+ findViewById(R.id.CenterToast).setOnClickListener(v -> {
+ linearLayout.setGravity(Gravity.CENTER);
+ linearLayout.addView(NewToast("测试"), 0, layoutParams);
+ });
- Glide.with(this).load("https://pic2.zhimg.com/v2-febc9228d18886a29c68a66536279dfb_r.jpg?source=1940ef5c")
- .into((ImageView) findViewById(R.id.imageView));
+// Glide.with(this).load("https://pic2.zhimg.com/v2-febc9228d18886a29c68a66536279dfb_r.jpg?source=1940ef5c")
+// .into((ImageView) findViewById(R.id.imageView));
}
@@ -75,16 +72,14 @@ public class Toast extends AppCompatActivity {
MaterialCardView materialCardView = binding.getRoot();
- ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(materialCardView, "scaleY", 0.8f, 1f);
- scaleYAnimator.setDuration(300); // 动画持续时间1秒
-
- // 创建透明度渐变动画
- ObjectAnimator fadeInAnimator = ObjectAnimator.ofFloat(materialCardView, "alpha", 0f, 1f);
- fadeInAnimator.setDuration(300); // 动画持续时间1秒
-
+ //创建移动动画
+ ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(materialCardView, "scaleY", 0.5f, 1f);
+ ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(materialCardView, "scaleX", 0.5f, 1f);
+ scaleXAnimator.setDuration(100);
+ scaleYAnimator.setDuration(100); // 动画持续时间1秒
// 同时播放两个动画
AnimatorSet set = new AnimatorSet();
- set.playTogether(scaleYAnimator, fadeInAnimator);
+ set.playTogether(scaleYAnimator,scaleXAnimator);
set.start();
// 设置动画结束后的回调
diff --git a/app/src/main/java/com/example/androiddemo/activity/Dialog.java b/app/src/main/java/com/example/androiddemo/activity/Dialog.java
new file mode 100644
index 0000000..f0cc76e
--- /dev/null
+++ b/app/src/main/java/com/example/androiddemo/activity/Dialog.java
@@ -0,0 +1,208 @@
+package com.example.androiddemo.activity;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.os.Build;
+import android.os.Bundle;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+import android.widget.Toast;
+
+import androidx.activity.EdgeToEdge;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.appcompat.app.AlertDialog;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.core.graphics.Insets;
+import androidx.core.view.ViewCompat;
+import androidx.core.view.WindowInsetsCompat;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.DataSource;
+import com.bumptech.glide.load.engine.GlideException;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.target.Target;
+import com.example.androiddemo.R;
+import com.google.android.material.dialog.MaterialAlertDialogBuilder;
+import com.google.android.material.dialog.MaterialDialogs;
+
+import java.util.function.Consumer;
+
+public class Dialog extends AppCompatActivity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ EdgeToEdge.enable(this);
+ setContentView(R.layout.activity_dialog);
+ ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
+ Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
+ v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
+ return insets;
+ });
+ //SDK 小于31 的关闭界面
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
+ android.widget.Toast.makeText(this, "只支持Android 12以上的设备", Toast.LENGTH_SHORT).show();
+ finish();
+ }
+ findViewById(R.id.btn_dialog).setOnClickListener(v -> {
+ //仅模糊背景
+ BlurDialog dialog = new BlurDialog(v.getContext(), BlurDialog.BLUR_TYPE_BLUR_BACKGROUND);
+ dialog.show();
+ });
+ findViewById(R.id.btn_dialog2).setOnClickListener(v -> {
+ //仅模糊后方屏幕
+ BlurDialog dialog = new BlurDialog(this, BlurDialog.BLUR_TYPE_BLUR_BEHIND);
+ dialog.show();
+ });
+ findViewById(R.id.btn_dialog3).setOnClickListener(v -> {
+ //模糊背景和后方屏幕
+ BlurDialog dialog = new BlurDialog(this, BlurDialog.BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND);
+ dialog.show();
+ });
+
+ Glide.with(this).asDrawable().
+ load("https://pic2.zhimg.com/v2-febc9228d18886a29c68a66536279dfb_r.jpg?source=1940ef5c")
+ .addListener(new RequestListener() {
+ @Override
+ public boolean onLoadFailed(@Nullable GlideException e, @Nullable Object model, @NonNull Target target, boolean isFirstResource) {
+ return false;
+ }
+
+ @Override
+ public boolean onResourceReady(@NonNull Drawable resource, @NonNull Object model, Target target, @NonNull DataSource dataSource, boolean isFirstResource) {
+ findViewById(R.id.main).setBackground(resource);
+ return false;
+ }
+ }).submit();
+
+ }
+ /**
+ * 对话框背景毛玻璃化
+ */
+ private void blurdialog() {
+ BlurDialog dialog = new BlurDialog(this, BlurDialog.BLUR_TYPE_BLUR_BACKGROUND);
+ dialog.show();
+ }
+ /** @noinspection FieldCanBeLocal*/
+ public class BlurDialog extends AlertDialog {
+
+ private Window mWindow;
+
+ //窗口背景高斯模糊程度,数值越高越模糊且越消耗性能
+ private final int mBackgroundBlurRadius = 90;
+ //窗口周边背景高斯模糊程度
+ private final int mBlurBehindRadius = 20;
+
+ //根据窗口高斯模糊功能是否开启来设置窗口周边暗色的程度
+ private final float mDimAmountWithBlur = 0f;
+ private final float mDimAmountNoBlur = 0.4f;
+
+ // 根据窗口高斯模糊功能是否开启来为窗口设置不同的不透明度
+ private final int mWindowBackgroundAlphaWithBlur = 170;
+ private final int mWindowBackgroundAlphaNoBlur = 255;
+
+ //使用一个矩形drawable文件作为窗口背景,这个矩形的轮廓和圆角确定了窗口高斯模糊的区域
+ private Drawable mWindowBackgroundDrawable;
+
+ /**
+ * 高斯模糊的类型
+ * 0代表只模糊背景
+ * 1代表之模糊后方屏幕
+ * 2代表同时模糊背景和后方屏幕
+ */
+ private int mBlurType = 0;
+ public static final int BLUR_TYPE_BLUR_BACKGROUND = 0;
+ public static final int BLUR_TYPE_BLUR_BEHIND = 1;
+ public static final int BLUR_TYPE_BLUR_BACKGROUND_AND_BEHIND = 2;
+
+ public BlurDialog(@NonNull Context context, int blurType) {
+ super(context, R.style.BlurDialogTheme);
+ mBlurType = blurType;
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.dialog_blur);
+ initBlur();
+ }
+
+ private void initBlur() {
+ mWindow = getWindow();
+ //替换window默认的背景
+ mWindowBackgroundDrawable = getContext().getDrawable(R.drawable.window_background);
+ getWindow().setBackgroundDrawable(mWindowBackgroundDrawable);
+
+ //注册一个监听者去监听窗口UI视图是否可见以便调整窗口高斯模糊功能是否开启
+ setupWindowBlurListener();
+
+ //允许背景模糊,也可以通过样式属性R.attr#windowBlurBehindEnabled来实现
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_BLUR_BEHIND);
+
+ // 允许背景变暗,也可以通过样式属性R.attr#backgroundDimEnabled来实现
+ getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+ }
+
+ /**
+ * 设置一个窗口视图状态监听者,监听窗口视图是否可见以便是否更新窗口模糊的状态
+ */
+ private void setupWindowBlurListener() {
+ Consumer windowBlurEnabledListener = this::updateWindowForBlurs;
+ getWindow().getDecorView().addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
+ @Override
+ public void onViewAttachedToWindow(@NonNull View v) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ mWindow.getWindowManager().addCrossWindowBlurEnabledListener(windowBlurEnabledListener);
+ }
+ }
+
+ @Override
+ public void onViewDetachedFromWindow(@NonNull View v) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ mWindow.getWindowManager().removeCrossWindowBlurEnabledListener(windowBlurEnabledListener);
+ }
+ }
+ });
+ }
+
+ /**
+ * 更新窗口的高斯模糊效果
+ *
+ * @param blursEnabled
+ */
+ private void updateWindowForBlurs(boolean blursEnabled) {
+ if (mBlurType == BLUR_TYPE_BLUR_BACKGROUND) {
+ //仅模糊背景
+ mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
+ getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
+ }
+ return;
+ }
+ if (mBlurType == BLUR_TYPE_BLUR_BEHIND) {
+ //仅模糊后方屏幕
+ getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
+ }
+ getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
+ return;
+ }
+ //同时模糊背景和后方屏幕
+ mWindowBackgroundDrawable.setAlpha(blursEnabled ? mWindowBackgroundAlphaWithBlur : mWindowBackgroundAlphaNoBlur);//调整背景的透明度
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ getWindow().setBackgroundBlurRadius(mBackgroundBlurRadius);//设置背景模糊程度
+ }
+ getWindow().setDimAmount(blursEnabled ? mDimAmountWithBlur : mDimAmountNoBlur);//调整背景周边昏暗的程度
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ getWindow().getAttributes().setBlurBehindRadius(mBlurBehindRadius);//设置背景周边模糊程度
+ }
+ getWindow().setAttributes(getWindow().getAttributes());//让上面的高斯模糊效果生效
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/res/animator/popup_enter.xml b/app/src/main/res/animator/popup_enter.xml
new file mode 100644
index 0000000..6bbc258
--- /dev/null
+++ b/app/src/main/res/animator/popup_enter.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/drawable/window_background.xml b/app/src/main/res/drawable/window_background.xml
new file mode 100644
index 0000000..7eca51c
--- /dev/null
+++ b/app/src/main/res/drawable/window_background.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_def_popup.xml b/app/src/main/res/layout/activity_def_popup.xml
new file mode 100644
index 0000000..3e025d6
--- /dev/null
+++ b/app/src/main/res/layout/activity_def_popup.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_dialog.xml b/app/src/main/res/layout/activity_dialog.xml
new file mode 100644
index 0000000..08becf3
--- /dev/null
+++ b/app/src/main/res/layout/activity_dialog.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_toast.xml b/app/src/main/res/layout/activity_toast.xml
index d6fcec0..3fba301 100644
--- a/app/src/main/res/layout/activity_toast.xml
+++ b/app/src/main/res/layout/activity_toast.xml
@@ -5,21 +5,34 @@
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
- tools:context=".activity.Toast">
+ tools:context=".activity.DefToast">
-
+ app:layout_constraintTop_toTopOf="parent"
+ android:gravity="center">
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/popup_menu.xml b/app/src/main/res/layout/popup_menu.xml
new file mode 100644
index 0000000..cc4a540
--- /dev/null
+++ b/app/src/main/res/layout/popup_menu.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/res/menu/popup_menu.xml b/app/src/main/res/menu/popup_menu.xml
new file mode 100644
index 0000000..9f5a0af
--- /dev/null
+++ b/app/src/main/res/menu/popup_menu.xml
@@ -0,0 +1,12 @@
+
+
\ No newline at end of file
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
index c8ff295..04b668b 100644
--- a/app/src/main/res/values/themes.xml
+++ b/app/src/main/res/values/themes.xml
@@ -12,5 +12,17 @@
- true
- @android:color/transparent
-
+
+
+
+
+
+
+
\ No newline at end of file