最近写程序第一次用到了PopupWindow,便简单了学习了一下。特此记下自己的收获。PopupWindow是一种悬浮框,比AlertDialog要灵活的多。先简单了实现一个PopWindow的效果,然后再一下相应的总结吧。因为有些东西,如果没有代码的话是很难说的清楚的。先说明,PopupWindow是位于android.widget.PopupWindow包下面的,方便你查看源码。
一、简单实现一个PopupWindow
先看一个实现的效果图吧。如下:
效果说明:最底部就是一个PopupWindow,只要点击popWindow按钮,就会从底部的位置弹出来。下面我们就开始写代码吧。
新建项目,然后修改它的activity_main.xml,代码如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:background="@drawable/bgd" 6 android:orientation="vertical"> 7 8 <TextView 9 android:id="@+id/tv" 10 android:layout_width="match_parent" 11 android:layout_height="wrap_content" 12 android:text="我是PupopWindow的背景" 13 android:textSize="30sp" 14 /> 15 16 --> 17 <Button 18 android:id="@+id/btn_reflect" 19 android:layout_width="match_parent" 20 android:layout_height="wrap_content" 21 android:text="popWindow" 22 /> 23 24 25 26 </LinearLayout>
代码超级简单,就不用我说了,然后再为PopupWindow写布局,新建pup.xml,代码如下:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical"> 6 7 <Button 8 android:id="@+id/btn_pop" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content" 11 android:text="我是按钮" 12 /> 13 <TextView 14 android:layout_width="match_parent" 15 android:layout_height="wrap_content" 16 android:text="我是PupopWindow" 17 android:textSize="30sp"/> 18 19 </LinearLayout>
代码不解释了。接着呢,就是为PopupWindow准备动画了。首先在res下建立文件夹anim。然后再里面新建anim_enter.xml。代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <translate 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:fromXDelta="0" 5 android:toXDelta="0" 6 android:fromYDelta="100%" 7 android:toYDelta="0" 8 android:duration="300"> 9 10 </translate>
然后再在里面新建anim_exit.xml,代码如下:
1 <?xml version="1.0" encoding="utf-8"?> 2 <translate 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:fromXDelta="0" 5 android:toXDelta="0" 6 android:fromYDelta="0" 7 android:toYDelta="100%" 8 android:duration="300"> 9 10 </translate>
最后在values文件夹下的styles.xml添加语句:
1 <resources> 2 3 <!-- 4 Base application theme, dependent on API level. This theme is replaced 5 by AppBaseTheme from res/values-vXX/styles.xml on newer devices. 6 --> 7 <style name="AppBaseTheme" parent="android:Theme.Light"> 8 <!-- 9 Theme customizations available in newer API levels can go in 10 res/values-vXX/styles.xml, while customizations related to 11 backward-compatibility can go here. 12 --> 13 </style> 14 15 <!-- Application theme. --> 16 <style name="AppTheme" parent="AppBaseTheme"> 17 <!-- All customizations that are NOT specific to a particular API-level can go here. --> 18 </style> 19 <style name="pupopWindow_anim"> 20 <item name="android:windowEnterAnimation">@anim/anim_enter</item> 21 <item name="android:windowExitAnimation">@anim/anim_exit</item> 22 </style> 23 24 </resources>
绿色部分,即第19到22行就是添加的代码。这个style就是为PopupWindow准备的动画了,即进入和退出时的动画。
最后修改MainActiivty的代码,在这里面将PopWindow显示出来即可。代码如下:
1 package com.fuly.kun; 2 3 import android.os.Bundle; 4 import android.app.Activity; 5 import android.graphics.Color; 6 import android.graphics.drawable.ColorDrawable; 7 import android.view.Gravity; 8 import android.view.LayoutInflater; 9 import android.view.MotionEvent; 10 import android.view.View; 11 import android.view.View.OnClickListener; 12 import android.view.View.OnTouchListener; 13 import android.view.ViewGroup.LayoutParams; 14 import android.widget.Button; 15 import android.widget.PopupWindow; 16 import android.widget.Toast; 17 18 public class MainActivity extends Activity { 19 20 private Button btnReflect; 21 private PopupWindow popWindow; 22 23 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.activity_main); 27 28 btnReflect = (Button) findViewById(R.id.btn_reflect); 29 30 btnReflect.setOnClickListener(new OnClickListener() { 31 32 public void onClick(View v) { 33 34 showPupopWindow();//显示出popWindow 35 } 36 }); 37 } 38 39 /** 40 * 将PupopWindow显示出来 41 */ 42 private void showPupopWindow() { 43 //PupopWindow的view 44 View pupView = LayoutInflater.from(this).inflate(R.layout.pup, null); 45 46 Button btn = (Button) pupView.findViewById(R.id.btn_pop); 47 btn.setOnClickListener(new OnClickListener() { 48 49 public void onClick(View v) { 50 51 Toast.makeText(getApplicationContext(), "我是popWindow的按钮", Toast.LENGTH_SHORT).show(); 52 } 53 }); 54 55 //实例化PupopWindow,参数中直接为其设置了view以及它的宽和高 56 popWindow = new PopupWindow(pupView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); 57 58 //设置PupopWindow捕获焦点 59 popWindow.setFocusable(true); 60 61 popWindow.setTouchable(true);//设置popWindow可点击 62 63 64 //为popWindow设置背景 65 ColorDrawable cd = new ColorDrawable(Color.parseColor("#FFFF00")); 66 popWindow.setBackgroundDrawable(cd); 67 68 //为popWindow设置进入和退出动画 69 popWindow.setAnimationStyle(R.style.pupopWindow_anim); 70 //将popWindwo显示出来 71 popWindow.showAtLocation(this.findViewById(R.id.tv), Gravity.BOTTOM, 0, 0); 72 } 73 74 75 }
代码注释很详细,逻辑也超级简单。运行程序,就是前面我们贴出来的效果了。
二、总结
总结一下在使用PopWindow时常用的方法吧,更详细的可以翻看API文档。如下:
- showAsDropDown(View anchor):相对某个控件的位置(正左下方),无偏移
- showAsDropDown(View anchor, int xoff, int yoff):相对某个控件的位置,有偏移
- showAtLocation(View parent, int gravity, int x, int y):相对于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以设置偏移或无偏移
- setFocusable(true):设置捕获焦点,默认为false
- setTouchable(true):设置PopupWindow可点击,默认为true。如果为false,则Touch事件或者点击事件会传递给下面的view,PopupWindow不处理。
- setOutsideTouchable(true):设置PopWindow的外部区域可点击,默认为false。只有当PopupWindow没有获取焦点且是可点击的,设置这个值才有意义。
- setTouchInterceptor(new OnTouchListener()):设置PopupWindow监听所有的触摸事件
-
为PopupWindow设置背景:ColorDrawable cd = new ColorDrawable(Color.parseColor("#FFFF00"));
popWindow.setBackgroundDrawable(cd); - setAnimationStyle(R.style.pupopWindow_anim):为PopupWindow设置动画(进入动画和退出动画)
- dismiss():退出
注意事项:
可能会出现问题,点击PupopWindow外部区域无效。此时给PupopWindow设置好背景就可以了。所以为了避免出现问题,一定要给其设置背景,哪怕是透明的。