Android高效率实现弹出带动画效果的对话框,仿照微信对话框效果

本文详细介绍如何使用PopupWindow在Android应用中实现带有动画效果的弹出对话框,包括配置动画、设置背景透明度及倒角效果等步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载请注明出处: http://blog.youkuaiyun.com/jakeyangchina/article/details/53423453

看到很多app页面里都有弹出对话框效果,今天使用PopupWindow实现带动画效果的对话框,先看效果图:

效果图:

这里写图片描述

分析实现思路:

  1. 弹出对话框带有动画效果
  2. 对话框从底部向上弹出
  3. 弹出对话框时,窗体背景呈现灰色(半透明)
  4. 对话框四周具有倒角效果

接下来具体实现,首先弹出具有动画效果那么我们就应该想到创建动画的方法有哪些,这里面采用xml配置动画,也可以代码创建,通过查看api可知PopupWindow提供两种方法设置动画效果

方法一:
popupWindow.setAnimationStyle(int res);通过设置样式来实现动画效果

方法二:
popupWindow.setEnterTransition(Transition t);
popupWindow.setExitTransition(Transition t);
这两个方法是设置进入和退出动画效果,显示要求最低版本19

我们采用方法一来设置动画效果,那么就需要创建xml文件,在styles.xml中配置样式

步骤:

  1. 先创建资源文件anim文件夹,具体目录:src/res/anim
  2. 在anim文件夹下创建anim_enter.xml和anim_exit.xml文件,根节点选择translate,详细配置见代码

接下来在styles.xml中创建样式style随便起名,这里起名anims指定条目属性名android:windowEnterAnimation和android:windowExitAnimation

开始创建倒角效果,具体步骤如下:

  1. 创建drawable文件夹,具体目录:src/res/drawable
  2. 在drawable文件夹下创建circle.xml名称任意起,节点选择shape具体配置见代码
  3. 在控件中引用 android:background=”@drawable/circle”

接下来直接上代码,代码标注很清晰

首先是anim_enter.xml文件
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_interpolator"
    android:duration="300"
    android:fromYDelta="100%"
    android:toXDelta="0">
</translate>

这里的属性:

  1. interpolator代表插值器,这里选择是accelerate_interpolator代表动画加速器,动画开始的时候最慢,,然后逐渐加速
  2. duration代表是动画执行的时间
  3. fromYDelta代表是动画从哪开始执行,这里使用100%代表在y轴方向父类窗体下方位置
  4. toXDelta代表运动到哪个位置
接下来是anim_exit.xml文件
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:duration="300"
android:fromYDelta="0"
android:toYDelta="100%">
</translate>

这里属性同上,就不详细描述,需要注意的是,fromYDelta位置是0开始,运动到不可见

接下来是在styles.xml中设置样式动画,位置src/res/values/styles.xml添加如下代码
<style name="anims" parent="AppTheme">
        <item name="android:windowEnterAnimation">@anim/anim_enter</item>
        <item name="android:windowExitAnimation">@anim/anim_exit</item>
    </style>

名称任意起,给android:windowEnterAnimation指定进入动画,给android:windowExitAnimation指定退出时动画,然后在代码中设置此样式

接下来是倒角circle.xml文件
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners android:radius="9dp"/>
    <solid android:color="@android:color/white" />
</shape>

这里属性有:

  1. shape代表选择的形状,这里选择rectangle矩形
  2. corners代表倒角设置,需要指定半径,这里直接设置四个角
  3. solid代表填充设置,指定颜色为白色,可以理解为设置背景色
接下来是MainActivity类中
        //获取窗体
        window = getWindow();
        //获取属性,为了设置透明度,呈现半透明效果
        attributes = window.getAttributes();

        //创建PopupWindow
        popupWindow = new PopupWindow(getApplication());
        //一定要设置宽和高
        popupWindow.setWidth(RelativeLayout.LayoutParams.MATCH_PARENT);
        popupWindow.setHeight(RelativeLayout.LayoutParams.WRAP_CONTENT);
        //设置背景色透明
        popupWindow.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#00ffffff")));
        //加载布局文件设置给popupWindow
        view = View.inflate(this, R.layout.popup,null);
        //将布局文件添加到popupWindow
        popupWindow.setContentView(view);
        //popupWindow.setFocusable(true);
        //设置点击任意popupWindow以外位置关闭popupWindow显示
        popupWindow.setOutsideTouchable(true);
        //设置动画样式,也可以代码设置动画4.4系统以上
        popupWindow.setAnimationStyle(R.style.anims);

        //给popupWindow添加关闭监听事件
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                //把窗体控件透明度设置为不透明(还原)
                attributes.alpha = 1f;
                window.setAttributes(attributes);
            }
        });

上面代码标注的很详细,这里需要注意的是当弹出对话框时窗体是半透明效果,当关闭对话框时窗体恢复原始效果,这里是通过getWindow();获取窗体,然后再通过window.getAttributes();方法获取WindowManager.LayoutParams类来设置透明度,给popupWindow设置关闭监听器,是为了当关闭popupWindow就会回调方法,在方法中设置恢复窗体原始透明度

接下来代码是控件设置了点击事件方法
    /**
     * 显示popupWindow
     * @param view
     */
    public void showPopup(View view) {
        if(popupWindow.isShowing()) {
            return;
        }
        //当弹出popupWindow时,将窗体透明度设置半透明
        attributes.alpha = 0.5f;
        window.setAttributes(attributes);
        //显示popupWindow,注意位置显示,对齐底部,(当没有导航栏时坐标点0,0,当有导航栏时坐标点0,导航栏高度)
        popupWindow.showAtLocation(view, Gravity.BOTTOM,0,0);

    }


    /**
     * 点击取消
     * @param view
     */
    public void printFont(View view) {
        if(popupWindow.isShowing()) {
            //当点击文字时,关闭popupWindow显示
            popupWindow.dismiss();
        }
    }

当点击Button按钮时就会执行showPopup(View view)方法,这里先判断popupWindow.isShowing()是否显示,如果已经显示了那么就退出
当点击文字控件时就会执行printFont(View view)方法,当显示时再去关闭popupWindow

接下来是PopupWindow加载的布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:paddingLeft="10dp"
    android:paddingBottom="10dp"
    android:paddingRight="10dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:gravity="center_vertical"
        android:orientation="vertical"
        android:background="@drawable/circle"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:text="选择图片"
            android:textSize="19sp"
            android:layout_marginLeft="9dp"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="45dp" />
        <View
            android:background="@android:color/darker_gray"
            android:layout_width="match_parent"
            android:layout_height="1dp"/>
        <TextView
            android:text="分享好友"
            android:textSize="19sp"
            android:layout_marginLeft="9dp"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="45dp" />
        <View
            android:background="@android:color/darker_gray"
            android:layout_width="match_parent"
            android:layout_height="1dp"/>
        <TextView
            android:text="发送位置"
            android:textSize="19sp"
            android:layout_marginLeft="9dp"
            android:gravity="center_vertical"
            android:layout_width="match_parent"
            android:layout_height="45dp" />
    </LinearLayout>

    <LinearLayout
        android:gravity="center_vertical"
        android:onClick="printFont"
        android:orientation="vertical"
        android:layout_marginTop="12dp"
        android:background="@drawable/circle"
        android:layout_width="match_parent"
        android:layout_height="45dp">
        <TextView
            android:text="取消显示"
            android:textSize="19sp"
            android:layout_marginLeft="9dp"
            android:gravity="center_vertical"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
</LinearLayout>

这个文件是通过view = View.inflate(this, R.layout.popup,null);加载到内存,然后通过方法popupWindow.setContentView(view);设置给popupWindow

接下来是布局文件activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.jakeyang.myapplication.MainActivity">

    <Button
        android:text="点击显示"
        android:onClick="showPopup"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

很简单就给了一个按钮,用于点击显示popupWindow

如果你觉得此文章对你有收获,那么给个好评吧,你的无意间的动作就是我写出好文章的动力,希望能够帮助到大家,共同进步

如果大家还有什么疑问,请在下方留言。

源码下载,请点击这里!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值