PopupWindow可以实现浮层效果,主要方法有:可以自定义view,通过LayoutInflator方法;可以出现和退出时显示动画;可以指定显示位置等。
为了将PopupWindow的多个功能展现并力求用简单的代码实现,编写了一个点击按钮左侧弹出菜单的功能,实现出现和退出时显示动画效果并点击其他区域时弹出层自动消失,效果图如下:
源码:
1.PopwindowOnLeftActivity.java
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
package
com.pop.main;
import
android.app.Activity;
import
android.os.Bundle;
import
android.view.MotionEvent;
import
android.view.View;
import
android.view.View.OnClickListener;
import
android.view.View.OnTouchListener;
import
android.widget.Button;
import
android.widget.PopupWindow;
public
class
PopwindowOnLeftActivity
extends
Activity {
// 声明PopupWindow对象的引用
private
PopupWindow popupWindow;
/** Called when the activity is first created. */
@Override
public
void
onCreate(Bundle savedInstanceState) {
super
.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 点击按钮弹出菜单
Button pop = (Button) findViewById(R.id.popBtn);
pop.setOnClickListener(popClick);
}
//点击弹出左侧菜单的显示方式
OnClickListener popClick =
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
getPopupWindow();
// 这里是位置显示方式,在按钮的左下角
popupWindow.showAsDropDown(v);
// 这里可以尝试其它效果方式,如popupWindow.showAsDropDown(v,
// (screenWidth-dialgoWidth)/2, 0);
// popupWindow.showAtLocation(findViewById(R.id.layout),
// Gravity.CENTER, 0, 0);
}
};
/**
* 创建PopupWindow
*/
protected
void
initPopuptWindow() {
// TODO Auto-generated method stub
// 获取自定义布局文件pop.xml的视图
View popupWindow_view = getLayoutInflater().inflate(R.layout.pop,
null
,
false
);
// 创建PopupWindow实例,200,150分别是宽度和高度
popupWindow =
new
PopupWindow(popupWindow_view,
200
,
150
,
true
);
// 设置动画效果
popupWindow.setAnimationStyle(R.style.AnimationFade);
//点击其他地方消失
popupWindow_view.setOnTouchListener(
new
OnTouchListener() {
@Override
public
boolean
onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
if
(popupWindow !=
null
&& popupWindow.isShowing()) {
popupWindow.dismiss();
popupWindow =
null
;
}
return
false
;
}
});
// pop.xml视图里面的控件
Button open = (Button) popupWindow_view.findViewById(R.id.open);
Button save = (Button) popupWindow_view.findViewById(R.id.save);
Button close = (Button) popupWindow_view.findViewById(R.id.close);
// pop.xml视图里面的控件触发的事件
// 打开
open.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
// 这里可以执行相关操作
System.out.println(
"打开操作"
);
// 对话框消失
popupWindow.dismiss();
}
});
// 保存
save.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
// 这里可以执行相关操作
System.out.println(
"保存操作"
);
popupWindow.dismiss();
}
});
// 关闭
close.setOnClickListener(
new
OnClickListener() {
@Override
public
void
onClick(View v) {
// TODO Auto-generated method stub
// 这里可以执行相关操作
System.out.println(
"关闭操作"
);
popupWindow.dismiss();
}
});
}
/***
* 获取PopupWindow实例
*/
private
void
getPopupWindow() {
if
(
null
!= popupWindow) {
popupWindow.dismiss();
return
;
}
else
{
initPopuptWindow();
}
}
}
|
主要界面
2.main.xml
01
02
03
04
05
06
07
08
09
10
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
android:orientation=
"vertical"
>
<Button android:id=
"@+id/popBtn"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:text=
"@string/pop_left"
/>
</LinearLayout>
|
弹出层的布局
3.pop.xml
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<LinearLayout xmlns:android=
"http://schemas.android.com/apk/res/android"
android:orientation=
"vertical"
android:layout_width=
"fill_parent"
android:layout_height=
"fill_parent"
android:background=
"@android:color/darker_gray"
>
<Button android:id=
"@+id/open"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/btn"
android:text=
"@string/open"
/>
<Button android:id=
"@+id/save"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/btn"
android:text=
"@string/save"
/>
<Button android:id=
"@+id/close"
android:layout_width=
"fill_parent"
android:layout_height=
"wrap_content"
android:background=
"@drawable/btn"
android:text=
"@string/close"
/>
</LinearLayout>
|
value下的style文件
4.style
01
02
03
04
05
06
07
08
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<resources>
<style name=
"AnimationFade"
>
<!-- PopupWindow左右弹出的效果-->
<item name=
"android:windowEnterAnimation"
>
@anim
/in_lefttoright</item>
<item name=
"android:windowExitAnimation"
>
@anim
/out_righttoleft</item>
</style>
</resources>
|
value下的string文件
5.string.xml
01
02
03
04
05
06
07
08
09
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<resources>
<string name=
"hello"
>Hello World, PopwindowOnLeftActivity!</string>
<string name=
"app_name"
>PopwindowOnLeft</string>
<string name=
"pop_left"
>弹出左侧菜单</string>
<string name=
"open"
>打开</string>
<string name=
"save"
>保存</string>
<string name=
"close"
>关闭</string>
</resources>
|
anim目录下的文件
出现时从左往右的动画文件
6.in_lefttoright.xml
01
02
03
04
05
06
07
08
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<set xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<!-- 定义从左向右进入的动画 -->
<translate
android:fromXDelta=
"-100%"
android:toXDelta=
"0"
android:duration=
"500"
/>
</set>
|
退出时从右往左消失的动画
7.out_righttoleft.xml
01
02
03
04
05
06
07
08
|
<?xml version=
"1.0"
encoding=
"utf-8"
?>
<set xmlns:android=
"http://schemas.android.com/apk/res/android"
>
<!-- 定义从右向左动画退出动画 -->
<translate
android:fromXDelta=
"0"
android:toXDelta=
"-100%"
android:duration=
"500"
/>
</set>
|
PopupWindow顾名思义为弹出菜单,不同于AlertDialog对话框,PopupWindow弹出的位置可以很多变化,按照有无偏移分,可以分为无偏移和偏移两种;按照参照类型不同又可以分为两种:相对某个控件(Anchor锚)的位置和父容器内部的相对位置。具体如下:
函数 | 简介 |
showAsDropDown(View anchor) | 相对某个控件的位置(正左下方),无偏移 |
showAsDropDown(View anchor, int xoff, int yoff) | 相对某个控件的位置,有偏移(正数表示下方右边,负数表示(上方左边)) |
showAtLocation(View parent, int gravity, int x, int y) | 父容器容器相对位置,例如正中央Gravity.CENTER,下方Gravity.BOTTOM等 |