1. 程式人生 > >PopupWindow學習之彈出方向(一)

PopupWindow學習之彈出方向(一)

PopupWindow直接繼承於Object,通過WindowManager來新增和移除view;
相對於AlertDialog來說,AlertDialog預設顯示在螢幕中央,PopupWindow需要指定顯示位置。
AlertDialog不阻塞執行緒,PopupWindow阻塞執行緒。
AlertDialog的確認和取消按鈕,在Android原始碼裡面是預設點選後消失Dialog。

所以這次有不同彈出方向的對話方塊我選擇了PopupWindow;

一、為PopupWindow建立xml佈局

<?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:gravity="center">
<LinearLayout android:id="@+id/phone_menu" android:layout_width="match_parent"
android:layout_height="wrap_content" android:background="@color/material_deep_teal_200" android:gravity="center" android:orientation="vertical" android:visibility="visible">
<TextView android:id="@+id/call_up" android:layout_width
="match_parent" android:layout_height="wrap_content" android:layout_marginTop="2dp" android:gravity="center" android:padding="6dp" android:text="撥打電話" android:textColor="@android:color/black" android:textSize="@dimen/text_size_medium"/>
<TextView android:id="@+id/change_phone" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:gravity="center" android:padding="6dp" android:text="修改電話" android:textColor="@android:color/black" android:textSize="@dimen/text_size_medium"/> </LinearLayout> </RelativeLayout>

再上一下圖片,(長得醜怪我咯)
PopupWindow的佈局

二、寫彈出動畫的xml效果
在anim資料夾下新建幾個動畫效果資料夾
1.底部進入的動畫,移動進入效果
push_bottom_in.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
       android:fromYDelta="100%p"
       android:toYDelta="0"
       android:duration="200"
        />
</set>

2.底部退出的動畫,移動退出效果
push_bottom_out.xml

<?xml version="1.0" encoding="utf-8"?>

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
       android:fromYDelta="0"
       android:toYDelta="50%p"
       android:duration="200"
        />
</set>

這裡的屬性及傳入值在下一篇部落格寫。這裡只放底部彈出動畫的xml

三、新增style
在values資料夾下的style檔案裡面新增四個style

    <!--視窗彈出動畫-->
    <style name="windowAnimTop" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/push_top_in</item>
        <item name="android:windowExitAnimation">@anim/push_top_out</item>
    </style>
    <style name="windowAnimBottom" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/push_bottom_in</item>
        <item name="android:windowExitAnimation">@anim/push_bottom_out</item>
    </style>
    <style name="windowAnimLeft" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/push_left_in</item>
        <item name="android:windowExitAnimation">@anim/push_left_out</item>
    </style>
    <style name="windowAnimRight" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/push_right_in</item>
        <item name="android:windowExitAnimation">@anim/push_right_out</item>
    </style>

這裡就是繼承了”android:Animation”,改變裡面window進入動畫和退出動畫

四、自定義一個類繼承PopupWindow

package com.code4god.heartway.common.widget;

import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.PopupWindow;

import com.code4god.heartway.R;
/**
 * Created by kang on 2016/1/8.
 * 帶進入動畫的PopUpWindow
 */
public class EntryAnimPop extends PopupWindow {
    private View mMenuView;


    public EntryAnimPop(Context context) {
        super(context);
        mMenuView = LayoutInflater.from(context).inflate(R.layout.pop_bottom_menu, null);
        //設定EntryAnimPop的View
        this.setContentView(mMenuView);
        //設定EntryAnimPop彈出窗體的寬
        this.setWidth(ViewGroup.LayoutParams.MATCH_PARENT);
        //設定EntryAnimPop彈出窗體的高
        this.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        //設定EntryAnimPop獲取焦點,彈出窗體可點選
        this.setFocusable(true);
        //例項化一個ColorDrawable顏色為半透明
        ColorDrawable dw = new ColorDrawable(0xb0000000);
        //設定EntryAnimPop彈出窗體的背景
        this.setBackgroundDrawable(dw);
        //設定EntryAnimPop點選到窗體外面就銷燬彈出框
        this.setOutsideTouchable(true);
    }

    /**
     * 位於控制元件下方,彈出動畫為自頂部彈出
     *
     * @param view
     * @param x
     * @param y
     */
    public void showAsDropDownTop(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimTop);
        this.showAsDropDown(view, x, y, Gravity.TOP);
    }

    public void showAsDropDownBottom(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimBottom);
        this.showAsDropDown(view, Gravity.BOTTOM, x, y);
    }

    public void showAsDropDownStart(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimLeft);
        this.showAsDropDown(view, Gravity.START, x, y);
    }

    public void showAsDropDownEnd(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimRight);
        this.showAsDropDown(view, Gravity.END, x, y);
    }

    /**
     * 基於位置,彈出動畫為自頂部彈出
     * @param view
     * @param x
     * @param y
     */
    public void showAtLocationTop(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimTop);
        this.showAtLocation(view, x, y, Gravity.TOP);
    }

    public void showAtLocationBottom(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimBottom);
        this.showAtLocation(view, Gravity.BOTTOM, x, y);
    }

    public void showAtLocationStart(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimLeft);
        this.showAtLocation(view, Gravity.START, x, y);
    }

    public void showAtLocationEnd(View view, int x, int y) {
        //設定EntryAnimPop彈出窗體動畫效果
        this.setAnimationStyle(R.style.windowAnimRight);
        this.showAtLocation(view, Gravity.END, x, y);
    }
}

showAsDropDown就是位於傳入的view的下方
showAtLocation就是基於指定位置,跟傳入的view的位置無關
這裡傳入的x,y就是PopupWindow窗體顯示時在x/y軸的偏移量.
需要注意一下的是Gravity.START和Gravity.END就是指Left和Right
在API 19 之後,使用的是Gravity.START和Gravity.END;

五、就是在activity裡面呼叫一下咯

 /**
     * 彈出popwindow
     */
    @OnClick(R.id.pop_top)
    void popTop(){
        EntryAnimPop entryAnimPop = new EntryAnimPop(this);
        entryAnimPop.showAsDropDownTop(showPopFromTop,0,0);
    }

最後,有啥說錯的,歡迎指正