PopupWindow详解与仿QQ底部弹出菜单

/ 0评 / 2

PopupWindow

PopupWindow从名字上面可以很容易看出,PopupWindow是用来弹出一个窗口的,类似于AlertDialog,不同的是,PopupWindow更灵活,在Android应用中,很多地方都可以见到它的身影。下面我们来介绍下这个PopupWindow的基本用法,以及做一个类似于QQ底部弹出菜单的效果。

构造方法

contentView为要显示的view,width和height为宽和高,值为像素值,也可以是MATCHT_PARENT和WRAP_CONTENT。focusable为是否能够获取焦点。

可以看到,其中第一种构造函数最省事,设置了要显示的View,宽度 ,高度以及是否能获得焦点。也可以调用其他构造函数,然后通过调用响应的方法设置这些属性。

设置PopupWindow的视图内容

可以通过public void setContentView(View contentView)来改变popup的显示内容,也可以用来初始化PopupWindow的View。

比如使用构造函数public PopupWindow (Context context)获得的Popupwindow就只能用setContentView来设置内容。

PopupWindow popupWindow = new PopupWindow(context);
popupWindow.setContentView(contentview);

设置PopUpWindow的焦点

我们可以通过setFocusable()来设置PopUpWindow能否获得焦点,也就是上面提到的构造方法中的第四个参数

如果setFocusable(true);则PopppWindow本身可以看作一个类似于模态对话框的东西(但有区别),PopupWindow弹出后,所有的触屏和物理按键都有PopupWindows处理。其他任何事件的响应都必须发生在PopupWindow消失之后, (home  等系统层面的事件除外)。比如这样一个PopupWindow出现的时候,按back键首先是让PopupWindow消失,第二次按才是退出activity,准确的说是想退出activity你得首先让PopupWindow消失 。如果设置为false,那么按下back键则由Activity处理

如果PopupWindow中有Editor的话,focusable要为true。一般情况下setFocusable(true);

点击空白处PopupWindow消失

关于PopupWindow最搞笑的地方是setOutsideTouchable方法,原本以为如果你setOutsideTouchable(true)则点击PopupWindow之外的地方PopupWindow会消失,其实这玩意儿一点用都没有。要让点击PopupWindow之外的地方PopupWindow消失你需要调用

setBackgroundDrawable(new BitmapDrawable());

设置背景,为了不影响样式,这个背景是空的。还可以这样写,觉得这样要保险些:

setBackgroundDrawable(new ColorDrawable(0x00000000));背景不为空但是完全透明。如此设置才能让PopupWindow在点击back的时候消失。

获取PopupWindow的宽高

在PopupWindow中,有两个函数

getHeight();

getWidth();

上面两个函数并不能很正确的获取PopupWindow的宽高,如果直接调用这两个函数而不特别处理,那么返回值往往是0或者-2。

正确获取PopupWindow的宽高。

//加载PopupWindow的布局
View view = View.inflate(this, R.layout.popwindow, null);
//测量布局的大小
view.measure(0, 0);
//将布局大小设置为PopupWindow的宽高
PopupWindow popWindow = new PopupWindow(view, view.getMeasuredWidth(), view.getMeasuredHeight(), true);
popWindow.getMeasuredHeight();
popWindow.getMeasuredWidth();

显示PopupWindow

仿QQ底部弹出菜单

老规矩,先上效果图,看是否是你需要的。

popupwindow

首先我们先设置弹出菜单的布局文件,有两个LinearLayout,最外面的LinearLayout套着一个LinearLayout和最下面的取消按钮,里层的LinearLayout套着3个按钮.

<?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:orientation="vertical" 
    android:padding="15dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@drawable/button_back"
        android:orientation="vertical" 
        android:layout_marginBottom="15dp">

        <Button
            android:id="@+id/updata"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:gravity="center"
            android:text="版本更新"
            android:textColor="#5084FE" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#cccccc" />

        <Button
            android:id="@+id/feedback"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:gravity="center"
            android:text="反馈"
            android:textColor="#5084FE" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:background="#cccccc" />

        <Button
            android:id="@+id/back"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@null"
            android:gravity="center"
            android:text="退出"
            android:textColor="#5084FE" />
    </LinearLayout>

    <Button
        android:id="@+id/cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:text="取消"
        android:background="@drawable/button_back"
        android:textColor="#5084FE" />

</LinearLayout>

在上面,使用了android:background="@drawable/button_back",button_back.xml是使用shape.xml定义的背景。分别设置给里层的LinearLayout和取消按钮。

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
    <corners android:radius="8dp" />
    <solid android:color="#ffffff" />
</shape>

使用已经定义好的背景,去显示PopupWindow

public class MainActivity extends Activity {

	private Button mShowBtmMenu;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.fragment_main);
		mShowBtmMenu = (Button) findViewById(R.id.showbottommenu);
		// 点击按钮,显示底部按钮
		mShowBtmMenu.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				showBottomMenu(v);
			}

		});
	}

	// 显示底部按钮
	private void showBottomMenu(View v) {
		// 加载PopupWindow的布局
		View view = View.inflate(this, R.layout.popwindow, null);
		PopupWindow popWindow = new PopupWindow(view,LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, true);
		popWindow.setBackgroundDrawable(new ColorDrawable(0));
		//设置动画
		popWindow.setAnimationStyle(R.style.popwin_anim_style);
		//设置popupwindow的位置
		popWindow.showAtLocation(v, Gravity.BOTTOM, 0, 0);
		//设置背景半透明
		backgroundAlpha(0.6f);
		//点击空白位置,popupwindow消失的事件监听,这时候让背景恢复正常
		popWindow.setOnDismissListener(new OnDismissListener() {
			@Override
			public void onDismiss() {
				backgroundAlpha(1.0f);
			}
		});
	}

	/**
	 * 设置屏幕的背景透明度
	 * @param bgAlpha
	 */
	public void backgroundAlpha(float bgAlpha) {
		WindowManager.LayoutParams lp = getWindow().getAttributes();
		lp.alpha = bgAlpha; // 0.0-1.0
		getWindow().setAttributes(lp);
	}
}

为PopupWindow设置进入退出动画

首先定义两个animation,分别表示进入退出动画

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fromYDelta="100%"
    android:toYDelta="0%" >
</translate>
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="100"
    android:fromYDelta="0%"
    android:toYDelta="100%" >
</translate>

然后在/values/styles文件中定义动画style

<style name="popwin_anim_style">  
     <item name="android:windowEnterAnimation">@anim/popup_anim_in</item>  
     <item name="android:windowExitAnimation">@anim/popup_anim_out</item>  
</style>

这样就可以在代码中通过setAnimationStyle(R.style.popwin_anim_style);使用了。

参考博客 : 泡在网上的日子 混日子的专栏

Demo下载地址 : 360云盘 访问密码 e45e

 

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注