文章目錄
- 一、前言
- PopupWindow
- 構造函數
- 方法
- 範例
- 設定popupWindow的按鍵監聽
- 參考
一、前言
Android 中的彈窗基本有兩種,一種是 AlertDialog,另一種是 PopupWindow,AlertDialog 的顯示位置是固定的,PopWindow 的顯示位置是我們可以設定和調整的,是以,像項目中的一些場景如:某個功能的提示說明、點選按鈕在按鈕上方或者下方彈出菜單、新功能彈窗引導等。
Android PopupWindow (懸浮框) 是一個彈出視窗控件,可以用來顯示任意 View,而且會浮動在目前 activity 的頂部,一般用于懸浮在其它 UI 控件旁邊,如果你經常使用過 QQ ,那麼一定見過,就是在某個清單上長按彈出的那個

和 AlertDialog 對話框不同的是,PopupWindow 的位置可以是随意的
而且 AlertDialog 是非堵塞線程的,而 PopupWindow 則是堵塞線程的
PopupWindow
可以通過 XML 代碼來建立一個懸浮框,還可以通過執行個體化
PopupWindow
來實作,不過,這貨的構造方法也太多了吧
構造函數
PopupWindow()
PopupWindow(Context context)
PopupWindow(Context context, AttributeSet attrs)
PopupWindow(Context context, AttributeSet attrs, int defStyleAttr)
PopupWindow(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)
PopupWindow(View contentView)
PopupWindow(int width, int height)
PopupWindow(View contentView, int width, int height)
PopupWindow(View contentView, int width, int height, boolean focusable)
參數簡直就是簡單明了,這裡就不再解釋了
方法
這貨的構造方法很多,但是,它的方法更多…淚崩了,我們隻挑幾個重要的講講
方法 | 說明 |
setContentView(View contentView) | 設定 PopupWindow 顯示的 View |
getContentView() | 獲得 PopupWindow 顯示的 View |
showAsDropDown(View anchor) | 相對某個控件的位置(正左下方),無偏移 |
showAsDropDown(View anchor, int xoff, int yoff) | 相對某個控件的位置,有偏移 |
showAtLocation(View parent, int gravity, int x, int y) | 相對于父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),可以設定偏移或無偏移 parent這個參數隻要是activity中的view就可以了! |
setWidth/setHeight | 設定寬高,也可以在構造方法那裡指定好寬高,除了可 |
setFocusable(true) | 設定焦點,PopupWindow 彈出後,所有的觸屏和實體按鍵都由 PopupWindow 處理。其他任何事件的響應都必須發生在PopupWindow消失之後,(home 等系統層面的事件除外)是以,當 PopupWindow 出現的時候,按back鍵首先是讓PopupWindow消失,第二次按才是退出 activity,準确的說是想退出activity你得首先讓PopupWindow消失,因為不并是任何情況下按back PopupWindow都會消失,必須在PopupWindow設定了背景的情況下 |
setAnimationStyle(int) | 設定動畫效果 |
範例
作為基礎教程,很多方法就不深入了,我們直接上最簡單的代碼吧
- 建立一個 空的 Android 項目
cn.twle.android.PopupWindow
- 修改
建立一個按鈕彈出 activity_main.xml
PopupWindow
<?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:padding="16dp"
android:orientation="vertical" >
<Button
android:id="@+id/btn_pop"
android:text="彈出 PopupWindow"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
- 建立一個懸浮框彈出的動畫,在
建立一個目錄 res
,然後在 anim
目錄下建立一個檔案 res/anim
anim_pop.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0"
android:toAlpha="1"
android:duration="2000">
</alpha>
</set>
- 然後建立懸浮框的布局,在
目錄下建立檔案 res/layout
popwin_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="vertical">
<Button
android:id="@+id/btn_web"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="簡單教程"
android:textSize="18sp" />
<Button
android:id="@+id/btn_wap"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="簡單程式設計"
android:textSize="18sp" />
</LinearLayout>
- 修改
MainActivity.java
package cn.twle.android.popupwindow;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.ViewGroup;
import android.view.View;
import android.widget.Button;
import android.widget.PopupWindow;
import android.widget.Toast;
import android.content.Context;
public class MainActivity extends AppCompatActivity {
private Context mContext;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
Button btn_pop = (Button) findViewById(R.id.btn_pop);
btn_pop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initPopWindow(v);
}
});
}
private void initPopWindow(View v) {
View view = LayoutInflater.from(mContext).inflate(R.layout.popwin_layout, null, false);
Button btn_web = (Button) view.findViewById(R.id.btn_web);
Button btn_wap = (Button) view.findViewById(R.id.btn_wap);
//1.構造一個PopupWindow,參數依次是加載的 View,寬高
final PopupWindow popWindow = new PopupWindow(view,
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT, true);
popWindow.setAnimationStyle(R.anim.anim_pop); //設定加載動畫
//這些為了點選非PopupWindow區域,PopupWindow會消失的,如果沒有下面的
//代碼的話,你會發現,當你把PopupWindow顯示出來了,無論你按多少次後退鍵
//PopupWindow并不會關閉,而且退不出程式,加上下述代碼可以解決這個問題
popWindow.setTouchable(true);
popWindow.setTouchInterceptor(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return false;
// 這裡如果傳回true的話,touch事件将被攔截
// 攔截後 PopupWindow的onTouchEvent不被調用,這樣點選外部區域無法dismiss
}
});
popWindow.setBackgroundDrawable(new ColorDrawable(0x00000000)); //要為popWindow設定一個背景才有效
//設定 popupWindow 顯示的位置,參數依次是參照 View,x軸的偏移量,y軸的偏移量
popWindow.showAsDropDown(v, 50, 0);
//設定 popupWindow 裡的按鈕的事件
btn_web.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "你點選了簡單教程", Toast.LENGTH_SHORT).show();
}
});
btn_wap.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this, "你點選了簡單程式設計", Toast.LENGTH_SHORT).show();
popWindow.dismiss();
}
});
}
}
設定popupWindow的按鍵監聽
用自定以的View的PopupWindow的時候,例如其中有兩個按鈕,一個響應向左按鍵,一個響應向右按鍵。是以要加一個按鍵監聽,或者有時候要監聽掃碼槍的掃碼完成監聽也行
但是在
popupWindow
所在的
Activity
裡監聽,在
popupWindow
彈出時候,是
不會觸發
。
修改的地方就是在
popupWindow
的
主View
上,我這裡變量為
View popView
,設定一個參數,如下
ps 這裡的主View popView 就是上述代碼的 View view = LayoutInflater.from(mContext).inflate(R.layout.popwin_layout, null, false);
popView = view;
popView.setFocusableInTouchMode(true);
這樣就可以添加
popupWindow
的按鍵監聽事件了,如下:
popView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
return true;
}
return false;
}
});
參考
Android PopupWindow