淺談PopupWindow的使用

一、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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章