PopupWindow學習之彈出方向(一)
阿新 • • 發佈:2019-02-01
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>
再上一下圖片,(長得醜怪我咯)
二、寫彈出動畫的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);
}
最後,有啥說錯的,歡迎指正