最近做一个全屏的popupWindow弹窗,类似于QQ创建讨论组或者添加讨论组成员所出现的选择弹窗,需要在弹窗的底部固定一个布局,由于有ListView
的存在,这个布局怎么弄都显示不出来,虽然通过android:layout_weight 属性可以将效果展现出来,但是这种按照屏幕的比例来进行布局的,在不同的
手机上效果差别会非常大,我所希望的是底部布局的高度是固定的,而且经过仔细观察我发现QQ的这个布局底部高度似乎也是固定的,所以更加坚定了
我这个想法。接下来就是实现了,我所采用的是相对布局。
<?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"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:id="@+id/navbar"
android:background="@drawable/bg_1" >
<TextView
android:id="@+id/add_temp_group_members_cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="15dp"
android:layout_centerInParent="true"
android:textSize="20sp"
android:textColor="#e8f3fb"
android:text="@string/add_temp_group_members_cancel"/>
<TextView
android:id="@+id/add_temp_group_members_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:textSize="20sp"
android:textColor="#e8f3fb"
android:text="@string/phoenix_tempgrp_list_entry_icon"/>
<TextView
android:id="@+id/add_temp_group_members_finish"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="15dp"
android:layout_centerInParent="true"
android:textSize="20sp"
android:textColor="#e8f3fb"
android:text="@string/add_temp_group_members_sure"/>
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/members_list"
android:layout_below="@+id/navbar"
android:layout_marginBottom="60dp"
android:orientation="vertical">
<ListView
android:id="@+id/group_members"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:divider="@color/color_dark_grey"
android:dividerHeight="0.5dip" >
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_height="60dp">
<TextView
android:id="@+id/add_temp_group_members_sure"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="20sp"
android:textColor="#e8f3fb"
android:background="@drawable/bg_1"
android:text="@string/add_temp_group_members_sure"/>
</LinearLayout>
</RelativeLayout>
在上面的布局中,最下面的一个线性布局就是我说要的底部布局,我将这个布局高度固定为60dp,利用父布局为RelativeLayout的缘故,可以设置
android:layout_alignParentBottom="true" 这个属性,于是我所要的布局就处在了底部,但是由于在这个布局中存在了ListView,这个底部布局会出
现被覆盖的现象,还是利用父布局是RelativeLayout的缘故,可以设置android:layout_marginBottom="60dp"属性,这个属性就是将ListView所在的
布局距离他的父布局底部空出60dp的高度以供底布局来显示。得到的效果如下图下图所示:
但是别以为就此结束了,由于要做一个全屏显示的popupwindon,在显示的时候发现,当ListView的滑到底部时,最后一个Item的显示效果在不同
的手机上完全不同,有的是显示了一部分,有的是显示不了,找了很久,终于让我发现了一个原因,我在设置popupwindow的显示高度的时候设置
的是全屏高度,所获取的也是整个屏幕的高度,问题也正是出现在这个地方,在手机的显示屏上,当打开应用的时候,我们知道其实应用并不是全
屏显示,在其上方还有一个手机的状态栏,而且有的手机用的还是虚拟按键,比如我用的手机是魅族,所以这个虚拟按键又要占去全屏高度的一部
分,因此我们所设置的popupwindow高度应该为:
一、 height=displayHeight-statusHeight-virtualBarHeight。
二、我们可以根据父控件的长宽去设置高度LayoutParams.MATCH_PARENT,利用这个属性就能够使popupwindow全屏显示。
通过上面两个方法就能够实现popupwindow全屏显示,无论是否具有虚拟按键。第一种方法有点问题,就是虚拟按键栏的高度根本就无法获取到,
我使用的是魅族手机,通过Native API所获取的屏幕高度为全屏幕的高度,而不是除去虚拟按键栏的高度,而虚拟按键栏的高度又没有API能够获
取,所以只有采用第二中方法。
屏幕高度以及状态栏高度的获取:
public void getTelInfo(){
int sdk = android.os.Build.VERSION.SDK_INT;
if(sdk < 13) {
Display display =((Activity)context).getWindowManager().getDefaultDisplay();
displayWidth = display.getWidth();
displayHeight = display.getHeight();
}else {
Display display =((Activity)context).getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
displayWidth = size.x;
displayHeight = size.y;
}
//获取状态栏高度
Rect frame = new Rect();
((Activity)context).getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
statusHeight = frame.top;
}
popupWindow的创建及隐藏:
public void startPopupWindow(){
if(popupWindow==null){
//popupWindow = new PopupWindow(view, displayWidth,(displayHeight-statusHeight));//第一种方式
popupWindow = new PopupWindow(view, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);//第二中方式
popupWindow.setAnimationStyle(R.style.PopupWindow_task_animation);
popupWindow.setOutsideTouchable(false);
popupWindow.setFocusable(true);
popupWindow.setBackgroundDrawable(new BitmapDrawable(context.getResources()));
//popupWindow.update();
}
popupWindow.showAtLocation(tv, Gravity.BOTTOM,displayWidth/2,0);
}
public void hidePopupWindow(){
if(popupWindow!=null&&popupWindow.isShowing()){
popupWindow.dismiss();
popupWindow = null;
}
}
显示动画:
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="700"
android:fromXDelta="0%p"
android:fromYDelta="100%p"
android:toYDelta="0%p"
android:toXDelta="0%p"
android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
</set>
隐藏动画:
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="700"
android:fromXDelta="0%p"
android:fromYDelta="0%p"
android:toYDelta="100%p"
android:toXDelta="0%p"
android:interpolator="@android:anim/accelerate_interpolator"/>
</set>