PopUpWindow 的使用筆記

最接作需求的時候,碰到了 PopUpWindow,可是也沒作過多瞭解,就是照搬別人的代碼改改邏輯。後面視覺看了以後,說讓我加一些動畫效果,使用起來更加舒服。但是我看別人之前也沒有寫,因而就開始搗鼓 PopUpWindow。同時也寫一篇文章記錄下,後續忘了也能夠查看。html

 

相關方法解讀

1)幾個經常使用的構造方法

咱們在文檔中能夠看到,提供給咱們的PopupWindow的構造方法有九種之多,這裏只貼實際 開發中用得較多的幾個構造方法:android

  • public PopupWindow (Context context)ide

  • public PopupWindow(View contentView, int width, int height)佈局

  • public PopupWindow(View contentView)動畫

  • public PopupWindow(View contentView, int width, int height, boolean focusable)this

參數就不用多解釋了吧,contentView是PopupWindow顯示的View,focusable是否顯示焦點spa

2)經常使用的一些方法

下面介紹幾個用得較多的一些方法,其餘的可自行查閱文檔:code

  • setContentView(View contentView):設置PopupWindow顯示的Vieworm

  • getContentView():得到PopupWindow顯示的Viewxml

  • showAsDropDown(View anchor):相對某個控件的位置(正左下方),無偏移

  • showAsDropDown(View anchor, int xoff, int yoff):相對某個控件的位置,有偏移

  • showAtLocation(View parent, int gravity, int x, int y): 相對於父控件的位置(例如正中央Gravity.CENTER,下方Gravity.BOTTOM等),能夠設置偏移或無偏移 PS:parent這個參數只要是activity中的view就能夠了!

  • setWidth/setHeight:設置寬高,也能夠在構造方法那裏指定好寬高, 除了能夠寫具體的值,還能夠用WRAP_CONTENT或MATCH_PARENT, popupWindow的width和height屬性直接和第一層View相對應。

  • setFocusable(true):設置焦點,PopupWindow彈出後,全部的觸屏和物理按鍵都由PopupWindows 處理。其餘任何事件的響應都必須發生在PopupWindow消失以後,(home 等系統層面的事件除外)。 好比這樣一個PopupWindow出現的時候,按back鍵首先是讓PopupWindow消失,第二次按纔是退出 activity,準確的說是想退出activity你得首先讓PopupWindow消失,由於不併是任何狀況下按back PopupWindow都會消失,必須在PopupWindow設置了背景的狀況下 。

  • setAnimationStyle(int):設置動畫效果

建立佈局

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:clipChildren="false" android:orientation="vertical">
    <View android:id="@+id/empty_view" android:layout_width="match_parent" android:layout_height="100dp" android:layout_weight="1"
        />

    <LinearLayout android:id="@+id/container" android:layout_width="match_parent" android:layout_height="200dp" android:background="@color/colorPrimary" android:orientation="vertical" android:gravity="center_vertical">

        <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="60dp" android:text="test" />
        
    </LinearLayout>
</LinearLayout>

注意其中這行代碼:

android:layout_weight="1"

因爲其餘 view 沒有使用這個屬性,默認爲0,使用該屬性的view將剩餘的空間鋪滿。這樣就至關於爲咱們設置了一個蒙層了。

寫好佈局後,須要將佈局文件傳到容器中去。

 

PopUpWindow 使用

因爲相關代碼比較長,直接附上完整代碼,方便你們查看。

完整代碼以下:

public class TestActivity extends AppCompatActivity implements View.OnClickListener { private PopupWindow mPopupWindow; private ViewGroup mContentView; private Button mBtn; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_test); mBtn = (Button) findViewById(R.id.result); mPopupWindow = new PopupWindow(this); mPopupWindow.setContentView(getContentView(this)); mPopupWindow.setHeight(ViewGroup.LayoutParams.MATCH_PARENT); mPopupWindow.setWidth(ViewGroup.LayoutParams.MATCH_PARENT); mPopupWindow.setClippingEnabled(false); // 若是不設置PopupWindow的背景,有些版本就會出現一個問題:不管是點擊外部區域仍是Back鍵都沒法dismiss彈框
        mPopupWindow.setBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color .empty_view_background))); mPopupWindow.setOutsideTouchable(true); mPopupWindow.setFocusable(true); mPopupWindow.update(); mBtn.setOnClickListener(this); } /** * popup window view 初始化 * * @return View */
    private View getContentView(Context ctx) { mContentView = (ViewGroup) LayoutInflater.from(ctx) .inflate(R.layout.popup, null); View emptyViewAbovePanel = mContentView.findViewById(R.id.empty_view); emptyViewAbovePanel.setOnClickListener(this); return mContentView; } @Override public void onClick(View v) { int i = v.getId(); if (i == R.id.empty_view) { Animation animation = AnimationUtils.loadAnimation(this, R.anim.pop_gone); mContentView.startAnimation(animation); animation.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { mPopupWindow.dismiss(); } @Override public void onAnimationRepeat(Animation animation) { } }); } else if (i == R.id.result) { mContentView.startAnimation(AnimationUtils.loadAnimation(this, R.anim.pop_in)); mPopupWindow.showAsDropDown(mBtn, 50, 50); } } }

 上面的代碼設置了蒙層,出場入場的動畫效果。

 

動畫設置

出場動畫文件xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:duration="400" android:fromXDelta="0" android:fromYDelta="0" android:toXDelta="0" android:toYDelta="100%" />
</set>

進場動畫文件xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:duration="400" android:fromXDelta="0" android:fromYDelta="100%" android:toXDelta="0" android:toYDelta="0" />
</set>

 爲何出場動畫不用 PopUpWindow 默認動畫設置呢。這是由於視覺只但願下面藍色部分有動畫效果,蒙層不須要這個動畫效果。所以咱們就必須添加額外的處理邏輯。若是採用默認的動畫設置效果,將會使得蒙層也有動畫效果。

在資源文件的values的style.xml中添加以下代碼

<style name="pop_animation" parent="android:Animation">
    <item name="android:windowEnterAnimation">@anim/pop_in</item>
    <item name="android:windowExitAnimation">@anim/pop_gone</item>
</style>

android:windowEnterAnimation:爲窗體進入時執行;
android:windowExitAnimation:爲窗體退出時執行;

將其使用到PopupWindow中:

mPopupWindow.setAnimationStyle(R.style.pop_animation); mPopupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);

setAnimationStyle() 便是爲 PopupWindow 添加動畫的方法,因爲 PopupWindow 不能像其餘的 View 同樣使用 ObjectAnimator, 因此使用動畫須要在 style 中定義,而且使用 PopupWindow 的 setAnimationStyle() 方法。這樣的話就可使用。

 

蒙層的處理

除了上面的個人蒙層方法,還有其餘添加蒙層的方法:

1)添加一層view

private void addMaskView(IBinder token) { WindowManager.LayoutParams p = new WindowManager.LayoutParams(); p.width = WindowManager.LayoutParams.MATCH_PARENT; p.height = WindowManager.LayoutParams.MATCH_PARENT; p.format = PixelFormat.TRANSLUCENT; p.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL; p.token = token; p.windowAnimations = android.R.style.Animation_Toast; maskView = new View(context); maskView.setBackgroundColor(0x7f000000); maskView.setFitsSystemWindows(false); maskView.setOnKeyListener(new OnKeyListener() { @Override public boolean onKey(View v, int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { removeMaskView(); return true; } return false; } }); wm.addView(maskView, p); }

而後在消失的時候進行移除:

public void dismiss() { if (maskView != null) { wm.removeViewImmediate(maskView); maskView = null; } super.dismiss(); }

2) 透明度

還有人是直接使用透明度來實現的。

private void bgAlpha(float alpha) { WindowManager.LayoutParams lp = ((Activity)context).getWindow().getAttributes(); lp.alpha = alpha;// 0.0-1.0
 ((Activity)context).getWindow().setAttributes(lp); }

 

原文出處:https://www.cnblogs.com/huansky/p/11574932.html

相關文章
相關標籤/搜索