Android中PopupWindow这个类是用来实现一个弹出框,可以使用任意布局的View作为其内容,这个弹出框是悬浮在当前activity之上的。PopupWindow是Android上自定义弹出窗口。
PopupWindow的构造方法为:public PopupWindow(View contentView, int width, int height, boolean focusable);contentView为要显示的view,width和height为宽和高,值为像素值,也可以是LayoutParams.MATCH_PARENT和LayoutParams.WRAP_CONTENT。focusable为是否可以获得焦点,这是一个很重要的参数,如果focusable为false,在一个Activity弹出一个PopupWindow,按返回键,由于PopupWindow没有焦点,会直接退出Activity。如果focusable为true,PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。如果PopupWindow中有Editor的话,focusable要为true。
废话不多说,直接上代码。
PopupWindow要想实现弹出,肯定要有动画,所以先弄两个动画,为下文准备:
<style name="popwindow_anim_style"> <item name="android:windowEnterAnimation">@anim/main_pop_anim_show</item> <!-- 指定显示的动画xml --> <item name="android:windowExitAnimation">@anim/main_pop_anim_hidden</item> <!-- 指定消失的动画xml --> </style>其中显示的动画main_pop_anim_show代码为:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromYDelta="100%p" android:toYDelta="0" /> <alpha android:duration="500" android:fromAlpha="0.0" android:toAlpha="1.0" /> </set>消失的动画main_pop_anim_hidden代码为:
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" > <translate android:duration="500" android:fromYDelta="0" android:toYDelta="50%p" /> </set> PopupWindowDemo的主界面布局只实现一个ImageView,因为本人想要该Demo实现的场景为地图上点击Marker时在地图底部弹出相应的信息操作,因此用ImageView代替地图上的Marker。
主界面布局的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:orientation="vertical" > <ImageView android:id="@+id/iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_horizontal" android:layout_marginTop="80dp" android:src="@drawable/user_defalut"/> </LinearLayout> PopupWindow弹出框的内容可以是任意布局的view,因此,可以根据自己的实际需求编写布局。此处使用的布局xml如下所示:(该布局也是从项目上直接引用过来的,场景也是地图上Marker的相关操作)
<?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="@android:color/white" android:orientation="vertical" > <RelativeLayout android:id="@+id/rl_check" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1.0" > <LinearLayout android:id="@+id/linearLayout1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="50dp" android:background="@android:color/white" android:orientation="vertical" > <TextView android:id="@+id/tv_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="12dp" android:singleLine="true" android:text="name" android:textColor="@android:color/background_dark" /> <LinearLayout android:id="@+id/ll_user_des" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center_vertical" android:orientation="horizontal" android:paddingLeft="8dp" > <TextView android:id="@+id/tv_distance" android:layout_width="wrap_content" android:layout_height="wrap_content" android:drawableLeft="@drawable/location_marker" android:gravity="center_vertical" android:singleLine="true" android:text="368 m" android:textColor="@android:color/darker_gray" /> <View android:layout_width="0.5dip" android:layout_height="match_parent" android:layout_margin="5dp" android:background="@android:color/darker_gray" /> <TextView android:id="@+id/tv_consume" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:singleLine="true" android:text="消耗 20 卡路里" android:textColor="@android:color/darker_gray" /> <ImageView android:id="@+id/iv_collect" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:src="@android:drawable/star_off" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="45dp" android:gravity="center_vertical" android:orientation="horizontal" android:paddingBottom="10dp" android:paddingLeft="15dp" > <TextView android:id="@+id/tv_search_near" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:drawableLeft="@drawable/near_search" android:gravity="center" android:singleLine="true" android:text="搜周边" android:textColor="@android:color/background_dark" /> <View android:layout_width="0.5dip" android:layout_height="match_parent" android:layout_margin="10dp" android:background="@android:color/darker_gray" /> <TextView android:id="@+id/tv_sport" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:drawableLeft="@drawable/location_marker" android:gravity="center" android:singleLine="true" android:text="运动足迹" android:textColor="@android:color/background_dark" /> <View android:layout_width="0.5dip" android:layout_height="match_parent" android:layout_margin="10dp" android:background="@android:color/darker_gray" /> <TextView android:id="@+id/tv_chat" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1.0" android:drawableLeft="@drawable/phone" android:gravity="center" android:singleLine="true" android:text="对讲机聊天" android:textColor="@android:color/background_dark" /> </LinearLayout> </LinearLayout> <ImageView android:id="@+id/iv_find_friends" android:layout_width="70dp" android:layout_height="70dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:layout_marginRight="30dp" android:layout_marginTop="10dp" android:src="@drawable/find_friends" /> </RelativeLayout> </LinearLayout>该布局所对应的显示效果图如下:
MainActivity的代码如下:
package pop; import android.app.Activity; import android.graphics.drawable.ColorDrawable; import android.os.Bundle; import android.view.Gravity; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.PopupWindow; import com.example.popupwindowdemo.R; public class MainActivity extends Activity{ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView() { ImageView iv = (ImageView) findViewById(R.id.iv); iv.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showPopwindow(); } }); } private void showPopwindow() { View parent = ((ViewGroup) this.findViewById(android.R.id.content)).getChildAt(0); View popView = View.inflate(MainActivity.this, R.layout.layout_pop_check, null); /** * 对popView中的布局控件执行相关操作 * 此处不作处理 */ PopupWindow popWindow = new PopupWindow(popView, -1, -2, true); popWindow.setBackgroundDrawable(new ColorDrawable(0x30000000)); popWindow.showAtLocation(parent, Gravity.BOTTOM, 0, 0); popWindow.setAnimationStyle(R.style.popwindow_anim_style); popWindow.setFocusable(true); popWindow.setOutsideTouchable(true); popWindow.update(); } } 对以上代码进行分析:
(1)以下代码实现的是弹出框的动画效果
popWindow.setAnimationStyle(R.style.popwindow_anim_style);(2)以下代码的作用是点击空白处时popupwindow会消失
popWindow.setBackgroundDrawable(new ColorDrawable(0x30000000)); popWindow.setFocusable(true); popWindow.setOutsideTouchable(true);(3)如果不设置PopupWindow的背景,无论是点击外部区域还是Back键都无法dismiss弹框
PopupWindowDemo在真机上测试的效果如下图所示: