【Android】对话框之PopupWindow

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/sandalphon4869/article/details/100174487


一、PopupWindow

PopupWindow比AlertDialog更灵活:
1.可以选择任意位置弹出
2.可以选择自定义布局效果
3.还支持其他的美化效果

在这里插入图片描述

二、函数

1.几个常用的构造方法

我们在文档中可以看到,提供给我们的PopupWindow的构造方法有九种之多,这里只贴实际 开发中用得较多的几个构造方法:

public PopupWindow(Context context)
public PopupWindow(View contentView)
public PopupWindow(View contentView, int width, int height)
public PopupWindow(View contentView, int width, int height, boolean focusable)

参数:

  • context:上下文
  • contentView:是PopupWindow显示的View
  • focusable:是否显示焦点。前三个方法默认不聚焦。

【contentView的创建】

View root=LayoutInflater.from(MainActivity.this).inflate(R.layout.layout,null,false);
/*
View root=MainActivity.this.getLayoutInflater().inflate(R.layout.layout,null,false);
这个不如LayoutInflater通用。
*/

LayoutInflater.from()中参数就是你所在哪个Activity的上下文。

2.常用的一些方法

(1)

setContentView(View contentView)

设置PopupWindow显示的View

getContentView()

获得PopupWindow显示的View

(2)显示

showAsDropDown(View anchor)

相对某个控件的左下角

showAsDropDown(View anchor, int xoff, int yoff)

相对某个控件的左下角,有偏移

showAtLocation(View parent, int gravity, int x, int y)

相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
PS:parent这个参数只要是activity中的view就可以了!

(3)设置属性

setWidth/setHeight(int width/height)

设置宽高,也可以在构造方法那里指定好宽高, 除了可以写具体的值,还可以用ViewGroup.LayoutParams.WRAP_CONTENTViewGroup.LayoutParams.MATCH_CONTENT, popupWindow的width和height属性直接和第一层View相对应。

setFocusable(true)

设置焦点,PopupWindow弹出后,所有的触屏和物理按键都由PopupWindows 处理。其他任何事件的响应都必须发生在PopupWindow消失之后,(home 等系统层面的事件除外)。
比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出 activity,准确的说是想退出activity你得首先让PopupWindow消失,因为不并是任何情况下按back后PopupWindow都会消失,必须在PopupWindow设置了背景的情况下 。

setAnimationStyle(int)

设置动画效果

(4)消失

dismiss()

让PopupWindow消失

popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {
        Toast.makeText(MainActivity.this,"Exit",Toast.LENGTH_SHORT).show();
    }
});

PopupWindow消失时的监听

三、示例

1.简单的PopupWindow

两步:

  • 设计PopupWindow的XML布局
  • 在Activity中创建PopupWindow

在这里插入图片描述

PopupWindow的XML布局: layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/ic_pop_bg">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="hello"
        android:textColor="@android:color/background_dark"
        android:id="@+id/fruit_name"/>

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@drawable/banana"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="close"
        android:id="@+id/close"/>
</LinearLayout>

PopupWindow的边框效果在它的布局文件的父容器属性中设置:android:background="@drawable/ic_pop_bg"

MainAcitivity的布局:activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="show"
        android:id="@+id/show"/>
    
</LinearLayout>

MainActivity.java

View root=LayoutInflater.from(MainActivity.this).inflate(R.layout.layout,null,false);
final PopupWindow popupWindow=new PopupWindow(
	root, 
	ViewGroup.LayoutParams.WRAP_CONTENT,
	ViewGroup.LayoutParams.WRAP_CONTENT,
	true
);

final Button button1=findViewById(R.id.show);
Button button2=root.findViewById(R.id.close);

button1.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        popupWindow.showAsDropDown(button1);
    }
});
button2.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        popupWindow.dismiss();
    }
});

【button1和button2按钮的区别】:
button1是在MainActivity布局activity_main中的show按钮,button是PopupWindow中的布局layout的close按钮。
所以show按钮可以在MainActivity中直接findViewById()直接找到,close按钮则是要找到父容器,root.findViewById

2.定制弹出位置

PopupWindow弹出位置解析

核心思路:
(button.width/2)-(popup.width/2)达到下方居中效果。

3.监听消失事件

popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    @Override
    public void onDismiss() {
        Toast.makeText(MainActivity.this,"Exit",Toast.LENGTH_SHORT).show();
    }
});

在这里插入图片描述

4.透明效果

(1)透明效果

透明效果就是在PopupWindow的XML布局里不写背景效果。
在这里插入图片描述

(2)图片背景

写了图片背景,自然才有效果。
在这里插入图片描述

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:background="@drawable/ic_pop_bg">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Even death,\nwhich no one can control."
        android:textColor="@android:color/background_dark"
        android:id="@+id/fruit_name"/>


    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="close"
        android:id="@+id/close"/>

</LinearLayout>

就这个android:background="@drawable/ic_pop_bg"

(3)png透过背景

在这里插入图片描述
使用png格式的图片,透明的部分会是绿色的背景。
在这里插入图片描述

5.阴影效果

private void addBackground() {
    //设置背景颜色变暗
    WindowManager.LayoutParams lp = getWindow().getAttributes();
    //调节透明度
    lp.alpha = 0.7f;
    getWindow().setAttributes(lp);
    
    //dismiss时恢复原样
    popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
        @Override
        public void onDismiss() {
            WindowManager.LayoutParams lp = getWindow().getAttributes();
            lp.alpha = 1f;
            getWindow().setAttributes(lp);
        }
    });
}

在PopupWindow部分中使用addBackground()就行。

public class MainActivity extends AppCompatActivity {

    private PopupWindow popupWindow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View root=LayoutInflater.from(MainActivity.this).inflate(R.layout.layout,null,false);
        popupWindow=new PopupWindow(root, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,true);

        final Button button1=findViewById(R.id.show);
        Button button2=root.findViewById(R.id.close);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.showAsDropDown(button1);
                addBackground();
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.dismiss();
            }
        });
    }

    private void addBackground() {
        // 设置背景颜色变暗
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.7f;//调节透明度
        getWindow().setAttributes(lp);
        //dismiss时恢复原样
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });
    }
}

在这里插入图片描述

6.动画效果

四步:

  • 建立进来时的动画效果,anim标识
  • 建立出来时的动画效果,anim标识
  • 在styles.xml里新建一个样式,联立其进出的动画效果
  • 在Activity中使用setAnimationStyle()设置动画效果

1.res/anim/popup_in.xml,进来时的动画

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromYDelta="100%"
    android:toXDelta="0"
    />

2.res/anim/popup_out.xml,出去时的动画

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fromYDelta="0"
    android:toYDelta="100%"
    />

3.styles.xml里新建一个样式

<!-- PopupWindow进出动画 -->
<style name="PopupWindowAnimation" parent="@android:style/Animation.Dialog">
    <item name="android:windowEnterAnimation">@anim/popup_in</item>
    <item name="android:windowExitAnimation">@anim/popup_out</item>
</style>

PS:怎么找不到res文件夹下的style文件夹?

是styles.xml(在values文件夹下),不是style文件夹。
在这里插入图片描述

4.设置样式

popupWindow.setAnimationStyle(R.style.PopupWindowAnimation);
public class MainActivity extends AppCompatActivity {

    private PopupWindow popupWindow;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        View root=LayoutInflater.from(MainActivity.this).inflate(R.layout.layout,null,false);
        popupWindow=new PopupWindow(root, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,true);

        popupWindow.setAnimationStyle(R.style.PopupWindowAnimation);

        final Button button1=findViewById(R.id.show);
        Button button2=root.findViewById(R.id.close);

        button1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.showAsDropDown(button1);
                addBackground();
            }
        });
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                popupWindow.dismiss();
            }
        });
    }

    private void addBackground() {
        // 设置背景颜色变暗
        WindowManager.LayoutParams lp = getWindow().getAttributes();
        lp.alpha = 0.7f;//调节透明度
        getWindow().setAttributes(lp);
        //dismiss时恢复原样
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
            @Override
            public void onDismiss() {
                WindowManager.LayoutParams lp = getWindow().getAttributes();
                lp.alpha = 1f;
                getWindow().setAttributes(lp);
            }
        });
    }
}

在这里插入图片描述


参考:
2.6.1 PopupWindow(悬浮框)的基本使用
Android PopupWindow超简单实现(一)
5分钟搞定PopUpWindow
CustomPopupWindow
【Android】在任意位置弹出PopupWindow
PopupWindow弹出位置解析

猜你喜欢

转载自blog.csdn.net/sandalphon4869/article/details/100174487