文章目录
一、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_CONTENT
或ViewGroup.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.定制弹出位置
核心思路:
(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弹出位置解析