标签:
PopupWindow的官方定义如下:
A popup window that can be used to display an arbitrary view. The popup window is a floating container that appears on top of the current activity.
也就是说它是一个浮动在当前界面上方并且可以显示在任意位置的View,前面的章节我们学习了弹出框,各式各样的,那么PopupWindow应该有两点和弹出框不同,一是PopupWindow必须指定宽高属性,而弹出框则不是必须指定;二是PopupWindow必须指定其布局文件。下面总结一下常用方法:
方法 | 类型 | 说明 |
PopupWindow(Context context) | 构造方法 | Context为上下文对象 |
PopupWindow(int width, int height) | 构造方法 | 传入宽高属性 |
PopupWindow(View contentView, int width, int height) | 构造方法 | 传入布局文件及宽高属性 |
PopupWindow(View contentView, int width, int height, boolean focusable) | 构造方法 | 传入布局文件、宽高属性和是否获得焦点 |
dismiss() | 普通方法 | 隐藏PopupWindow |
setAnimationStyle(int animationStyle) | 普通方法 | 为PopupWindow添加动画 |
setBackgroundDrawable(Drawable background) | 普通方法 | 改变PopupWindow的背景 |
setContentView(View contentView) | 普通方法 | 为PopupWindow设置布局 |
setFocusable(boolean focusable) | 普通方法 | 是否获取焦点 |
setOnDismissListener(PopupWindow. OnDismissListener onDismissListener) | 普通方法 | 设置PopupWindow消失监听 |
showAsDropDown(View anchor, int xoff, int yoff, int gravity) | 普通方法 | 在某控件下方弹出PopupWindow |
showAtLocation(View parent, int gravity, int x, int y) | 普通方法 | 在父控件的什么位置弹出PopupWindow |
由上面方法可以看出,PopupWindow共有两种弹出方式,一种在某控件的下方,一种在父控件的任意方向,弹出位置可以任意设定,十分灵活。
首先通过一个实例熟悉一下PopupWindow的用法,这里采用showAtLocation方法弹出PopupWindow。
【实例17.1】主布局文件代码(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:textSize="20sp"
android:onClick="test"
android:layout_centerInParent="true"
android:text="PopupWindowTest" />
</RelativeLayout>
定义了一个Button控件,设置了其onClick属性用于单击事件监听。
【实例17.1】PopupWindow布局文件代码(popupwindow_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:background="#ffffff"
android:orientation="vertical"
android:paddingBottom="1dp">
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#10a324"
android:layout_alignParentTop="true"/>
<TextView
android:id="@+id/tv_exit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/text_style"
android:text="退出"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#d4d2d2"/>
<TextView
android:id="@+id/tv_set"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/text_style"
android:text="设置"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#d4d2d2"/>
<TextView
android:id="@+id/tv_cancel"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/text_style"
android:text="取消"/>
</LinearLayout>
这里TextView引入了样式,样式表如下:
<style name="text_style">
<item name="android:paddingTop">5dp</item>
<item name="android:paddingBottom">5dp</item>
<item name="android:gravity">center</item>
<item name="android:textColor">#10a324</item>
</style>
一些共用的属性可以提取出来做成样式表,方便后期维护,每一个属性由一个item标签包裹。
【实例17.1】MainActivity代码(MainActivity.java)
public class MainActivity extends Activity implements View.OnClickListener {
private PopupWindow popupWindow;
private TextView tvExit,tvSet,tvCancel;
private View rootView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
private void showPopup() {
View view = LayoutInflater.from(this).inflate(R.layout.popupwindow_layout,null);//PopupWindow对象
popupWindow=new PopupWindow(this);//初始化PopupWindow对象
popupWindow.setContentView(view);//设置PopupWindow布局文件
popupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);//设置PopupWindow宽
popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);//设置PopupWindow高
rootView =LayoutInflater.from(this).inflate(R.layout.activity_main, null);//父布局
popupWindow.showAtLocation(rootView, Gravity.BOTTOM,0,0);
popupWindow.setOutsideTouchable(true);
tvSet=(TextView)view.findViewById(R.id.tv_set);
tvCancel=(TextView)view.findViewById(R.id.tv_cancel);
tvExit=(TextView)view.findViewById(R.id.tv_exit);//在view对象中通过findViewById找到TextView控件
tvSet.setOnClickListener(this);//注册点击监听
tvCancel.setOnClickListener(this);//注册点击监听
tvExit.setOnClickListener(this);//注册点击监听
popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
Toast.makeText(MainActivity.this,"PupWindow消失了!",Toast.LENGTH_SHORT).show();
}
});
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.tv_cancel:
popupWindow.dismiss();//关闭PopupWindow
break;
case R.id.tv_exit:
finish();//调用Activity的finish方法退出应用程序
break;
case R.id.tv_set:
Toast.makeText(this,"设置",Toast.LENGTH_SHORT).show();
popupWindow.dismiss();
break;
}
}
public void test(View view){
if(popupWindow==null) {
showPopup();
}else{
popupWindow.showAtLocation(rootView, Gravity.BOTTOM,0,0);//设置PopupWindow的弹出位置。
}
}
}
在按钮的单击响应事件test中判断在没有初始化时调用showPopup方法, 否则调用showAtLocation弹出PopupWindow,这个方法需要传入四个参数,第一个是父布局对象,第二个是弹出位置,第三个是关于x轴偏移量,第四个是关于y轴偏移量。
ShowPopup方法首先获取到了PopupWindow的布局文件,初始化了一个PopupWindow对象,使用该对象调用setWidth方法设置宽度,调用setHeight方法设置高度。然后调用showAtLocation方法显示出PopupWindow,通过findViewById的方法获取PopupWindow中的每个控件,方便注册单击监听,进行逻辑事件的处理。
最后设置了使用setOnDismissListener方法对PopupWindow 进行了消失事件监听。
运行实例如下:
点击按钮会在主界面正下方弹出popupWindow,点击设置按钮popupWindow消失,并触发消失事件监听。
用过微信的朋友都会熟悉如下的界面,这个效果同样也可以用popupWindow模拟实现。
【实例17.2】主布局文件代码(activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_add"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_alignParentRight="true"
android:padding="10dp"
android:src="@drawable/add" />
</RelativeLayout>
主布局文件引入了一个ImageView,设置了layout_alignParentRight属性为true,将控件显示在主布局右方,设置src属性选择图片源。
【实例17.2】popupWindow布局文件代码(pop_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="match_parent"
android:background="#24a943"
android:orientation="vertical">
<LinearLayout
android:id="@+id/ll_pic"
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:padding="5dp"
android:src="@drawable/pic" />
<TextView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="40dp"
android:text="图片" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:padding="5dp"
android:src="@drawable/location" />
<TextView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="40dp"
android:text="GPS" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:padding="5dp"
android:src="@drawable/music" />
<TextView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="40dp"
android:text="音乐" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="40dp"
android:orientation="horizontal">
<ImageView
android:layout_width="35dp"
android:layout_height="35dp"
android:padding="5dp"
android:src="@drawable/wifi" />
<TextView
android:layout_width="wrap_content"
android:layout_height="35dp"
android:gravity="center"
android:paddingLeft="20dp"
android:paddingRight="40dp"
android:text="WIFI" />
</LinearLayout>
</LinearLayout>
这里设置了四个LinearLayout控件,并设置其orientation属性为horizontal,每个LinearLayout中添加了一个ImageView和一个TextView。
因为这里为popupWindow添加了动画,所以下面看一下两个动画文件:
【实例17.2】popupWindow消失动画(anim_dismiss.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromXDelta="0"
android:fromYDelta="0"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="0"
android:toYDelta="100%p" />
</set>
通过interpolator设置了内置的动画插值器用于动画加速。
【实例17.2】popupWindow显示动画(anim_show.xml)
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:duration="@android:integer/config_shortAnimTime"
android:fromXDelta="0"
android:fromYDelta="100%p"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"
android:toXDelta="0"
android:toYDelta="0"/>
</set>
设置了duration属性,选择内置的时间值:config_shortAnimTime=200ms。
PopupWindow设置动画调用setAnimationStyle方法需要传入style样式,因此定义如下样式表:
【实例17.2】样式表代码(styles.xml)
<style name="popupAnim" parent="@android:style/Animation.Activity">
<item name="android:windowEnterAnimation">@anim/anim_show</item>
<item name="android:windowExitAnimation">@anim/anim_dismiss</item>
</style>
设置了windowEnterAnimation(窗口进入动画)和windowExitAnimation(窗口消失动画)属性,其值分别对应显示和消失动画。
【实例17.2】MainActivity.java代码(MainActivity.java)
public class MainActivity extends AppCompatActivity {
private ImageView imageView;
private PopupWindow popupWindow;
private LinearLayout linearLayoutPic;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView=(ImageView)findViewById(R.id.iv_add);
imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
addAnimation();
if(popupWindow==null){
showPopupWindow();
}else if(popupWindow.isShowing()){
popupWindow.dismiss();
}
else{
popupWindow.showAsDropDown(imageView,-300,0);
}
}
});
}
private void addAnimation() {//加入了旋转动画
RotateAnimation rotateAnimation=new RotateAnimation(0,360, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(500);//设置动画时间
imageView.setAnimation(rotateAnimation);//设置动画
imageView.startAnimation(rotateAnimation);//开始动画
}
private void showPopupWindow() {
View view= LayoutInflater.from(this).inflate(R.layout.pop_layout,null);//获取popupWindow子布局对象
popupWindow =new PopupWindow(view, ViewGroup.LayoutParams.WRAP_CONTENT,ViewGroup.LayoutParams.WRAP_CONTENT,false);//初始化
popupWindow.showAsDropDown(imageView,-300,0);//在ImageView控件下方弹出
popupWindow.setAnimationStyle(R.style.popupAnim);//设置动画
linearLayoutPic=(LinearLayout)view.findViewById(R.id.ll_pic);
linearLayoutPic.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "单击了图片按钮!", Toast.LENGTH_SHORT).show();
popupWindow.dismiss();
}
});
}
}
为了提供用户体验,这里对ImageView图片也设置了旋转动画,每次点击图片显示出popupWindow时同样ImageView也会进行旋转。调用showAsDropDown方法在ImageView下方显示出popupWindow,并调用了setAnimationStyle为popupWindow设置了消失和显示时的动画,这个方法需要传入一个样式表。
运行项目实例如下:
通过快速截图可以看出,popupWindow通过动画从下方弹出,并且ImgeView也有了旋转动画。
喜欢的朋友,请关注,谢谢
Android实战简易教程-第七十二枪(PopupWindow浮动窗)
标签:
原文地址:http://blog.csdn.net/yayun0516/article/details/51093606