一、PopupWindow與AlertDialog的區別
最關鍵的區別是AlertDialog不能指定顯示位置,只能默認顯示在屏幕最中間(當然也可以通過設置WindowManager參數來改變位置)。而PopupWindow是可以指定顯示位置的,隨便哪個位置都可以,更加靈活。
二、PopupWindow的顯示方法
// 相對於某個控件的位置(正左下方),無偏移
showAsDropDown(View anchor)
// 相對於某個控件的位置,有偏移;xoff表示x軸的偏移,正值表示向右,負值表示向左;
// yoff表示y軸的偏移,正值表示向下,負值表示向上
showAsDropDown(View anchor, int xoff, int yoff);
// 相對於整個窗口的位置(例如:正中央Gravity.CENTER,下方Gravity.BOTTOM等),
// 可以設置偏移或無偏移無偏移
showAtLocation(View parent, int gravity, int x, int y);
【注意:】
第一個參數anchor:是View類型的parent,雖然這裏參數名是parent,其實,不是把PopupWindow放到這個parent裏,並不要求這個parent是一個ViewGroup,這個參數名讓人誤解。官方文檔”a parent view to get the android.view.View.getWindowToken() token from”,這個parent的作用應該是調用其getWindowToken()方法獲取窗口的Token,所以,只要是該窗口上的控件就可以了。
三、案例演示
1. PopupWindow顯示在某個控件的下方
代碼如下:
package com.danny_jiang.day10_popupwindow_introduce;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.TextView;
/**
* PopupWindow控件,可以在屏幕任何地方以彈出框的方式顯示任何View
* 1 初始化彈出框所需要顯示的View對象
* 2 初始化彈出框,並將View對象傳遞給彈出框
* 3 調用PopupWindow.showXXX方法將彈出框顯示到屏幕上的具體位置
*
*/
public class MainActivity extends Activity implements OnClickListener{
private Button btn;
private PopupWindow popWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn = (Button) findViewById(R.id.btn);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
// 將所點擊的View控件傳遞給showPopupWindow方法
showPopupWindow(v);
}
private void showPopupWindow(View anchor) {
// 1 初始化彈出框所需要顯示的View
TextView text = new TextView(this);
text.setText("This is a TextView");
// 2 初始化彈出框,並傳遞View對象,以及彈出框的寬高
popWindow = new PopupWindow(text,
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// 3 顯示彈出框
popWindow.showAsDropDown(anchor, 30, 50);
}
}
效果圖如下:
2.PopupWindow顯示在整個窗口的任意位置
代碼如下:
package com.danny_jiang.day10_popwindow_menu;
import android.app.Activity;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.PopupWindow;
/**
* 使用PopupWindow實現自定義Menu
* 1 將系統的Menu按鍵點擊事件攔截
* 2 當攔截Menu的點擊事件之後,通過PopupWindow來顯示自定義Menu View
* 2.1 初始化PopupWindow所需要顯示視圖對象
* 2.2 初始化PopupWindow對象,並傳遞View
*
*/
public class MainActivity extends Activity {
// 聲明彈出框所需要顯示的View對象
private View popView;
private PopupWindow popWindow;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
popView = getLayoutInflater().inflate(R.layout.popup_layout, null);
// 如果在代碼中重新設置了popupWindow的寬和高,那就以代碼中所設置爲準
// 此時popup_layout.xml佈局文件中的LinearLayout佈局的match_parent將失效
popWindow = new PopupWindow(popView, LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
popWindow.setOutsideTouchable(true);
popWindow.setBackgroundDrawable(new BitmapDrawable());
}
/**
* 監聽手機實體按鍵的點擊事件:MENU、BACK、HOME、VOLUME、POWER
* @param keyCode
* 實體鍵碼,在不同的設置上值不一定相同,但是以靜態變量的方式封裝在KeyEvent當中
* KeyEvent.KEYCODE_MENU 表示菜單鍵
* KeyEvent.KEYCODE_BACK 表示返回鍵
* @param event
* 實體按鍵的處理事件
* DOWN 點擊,或者手指按下事件
* MOVE 手指在實體鍵上滑動
* UP 手指離開實體按鍵
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
// 攔截實體Menu鍵的點擊事件
case KeyEvent.KEYCODE_MENU: // 說明點擊了Menu實體鍵
// 判斷PopUpWindow是否已經顯示
if (popWindow.isShowing()) {
popWindow.dismiss();
} else {
// 如果當前沒有顯示彈出框,則將其顯示在屏幕的最下方
popWindow.showAtLocation(popView, Gravity.BOTTOM, 0, 0);
}
return true;
case KeyEvent.KEYCODE_BACK:
if (popWindow.isShowing()) {
popWindow.dismiss();
return true;
}
default:
break;
}
/**
* 注意onKeyDown返回值,儘量不要統一返回true
*/
return super.onKeyDown(keyCode, event);
}
}
popup_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:orientation="horizontal" >
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="@drawable/collectcontent" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="@drawable/contentshare" />
<ImageView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:scaleType="fitXY"
android:src="@drawable/contentback" />
</LinearLayout>
效果圖如下:
更多有關PopupWindow的詳細介紹,見博客
http://blog.csdn.net/harvic880925/article/details/49272285