一 、前言
前面為了在專案中使用Popupwindow簡單方便,自己簡易封裝了一個PopupWindow,可以在專案很方便的使用。還沒有看過的可以去看一下文章介紹,通用PopupWindow,幾行程式碼搞定PopupWindow彈窗,前段時間看到有留言說彈出PopupWindow同時使背景變暗這個功能沒有,能不能加上?想著這是個比較常見的需求,因此把它加到了這個庫中,本篇文章就簡單談談怎麼實現這個功能。
專案地址:github.com/pinguo-zhou…
最終效果圖:
二 、彈出PopupWindow 同時背景變暗
我們知道,一個Activity包含了一個Window物件,Activity是不直接顯示View,View 被繫結到Window上來得以呈現,也就是說View必須是依附Window而存在的,同樣PopupWindow也是如此。因此要控制整個螢幕的背景的變暗和變亮,我們只需要控制當前Activity的window的亮度,通過alpha屬性的值來控制就行了。
我們先來寫個例子測試一下:通過一個seekbar來控制alpha值來改變螢幕的亮度。
1, 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.support.v7.widget.AppCompatSeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:layout_marginBottom="20dp"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="改變當前window亮度:"
android:textColor="@android:color/darker_gray"
android:textSize="16sp"
android:layout_above="@+id/seek_bar"
android:layout_marginBottom="10dp"
android:layout_marginLeft="10dp"
/>
</RelativeLayout>複製程式碼
2, 程式碼如下:
mAppCompatSeekBar = (AppCompatSeekBar) findViewById(R.id.seek_bar);
mAppCompatSeekBar.setMax(100);
mAppCompatSeekBar.setProgress(100);
mAppCompatSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
float alpha = seekBar.getProgress() * 1.0f / 100 ;
if(alpha < 0.2){
alpha = 0.2f;
}
Window mWindow = getWindow();
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = alpha;
mWindow.setAttributes(params);
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});複製程式碼
效果如下:
看到沒?隨著拖動seekBar,螢幕的亮度就跟著改變了,這不就是我們想要的效果嘛。
PopupWindow 彈出和消失時改變當前window的alpha 來控制螢幕亮度。
有了上面的測試,我們就可以讓PopupWindow彈出時,同時螢幕變暗了。在build()
方法中新增如下程式碼:
// 獲取當前Activity的window
Activity activity = (Activity) mContentView.getContext();
if(activity!=null && mIsBackgroundDark){
//如果設定的值在0 - 1的範圍內,則用設定的值,否則用預設值
final float alpha = (mBackgroundDrakValue > 0 && mBackgroundDrakValue < 1) ? mBackgroundDrakValue : DEFAULT_ALPHA;
mWindow = activity.getWindow();
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = alpha;
mWindow.setAttributes(params);
}複製程式碼
加了上面的程式碼,在彈出PopupWindow的時候,螢幕就會變暗了,但是你會發現一個問題,PopupWindow消失之後,螢幕仍然是暗的,這當然不是我們想要的,因此在PopupWindow消失的時候,需要改回原來的值。重寫onDismiss
方法,新增如下程式碼:
//如果設定了背景變暗,那麼在dissmiss的時候需要還原
if(mWindow!=null){
WindowManager.LayoutParams params = mWindow.getAttributes();
params.alpha = 1.0f;
mWindow.setAttributes(params);
}複製程式碼
現在,這個功能就完成了。看一下效果圖:
三、CustomPopWindow 使用背景變暗配置
上面講了背景變暗的思路和方法,那麼我們看一下CustomPopWindow 怎麼使用這個功能,非常簡單,新增了2個配置方法:
- enableBackgroundDark(boolean isDark):是否開啟背景變暗,使用預設亮度值,也可以使用
setBgDarkAlpha
改變亮度值。 - setBgDarkAlpha(float darkValue):改變背景亮度值。
示例程式碼如下:
//建立並顯示popWindow
mCustomPopWindow= new CustomPopWindow.PopupWindowBuilder(this)
.setView(contentView)
.enableBackgroundDark(true) //彈出popWindow時,背景是否變暗
.setBgDarkAlpha(0.7f) // 控制亮度
.create()
.showAsDropDown(mButton5,0,20);複製程式碼
四、新增PopupWindow顯示和消失動畫
有時候,我們可能需要在PopupWindow 顯示和消失的時候新增上一些動畫,Popwindow是可以自己新增顯示和消失的動畫的,通過setAnimationStyle
方法設定,顯示動畫和消失動畫分別由android:windowEnterAnimation
和android:windowExitAnimation
2個屬性控制。
如下步驟:
(1) 在res/anim 下新增兩個動畫檔案
popwindow_anim_in:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="0"
android:toAlpha="1.0"
android:duration="100"
/>
<scale android:fromXScale="0"
android:toXScale="1.0"
android:fromYScale="0"
android:toYScale="1.0"
android:duration="100"
/>
</set>複製程式碼
popwindow_anim_out:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<alpha android:fromAlpha="1.0"
android:toAlpha="0.0"
android:duration="100"
/>
<scale android:fromXScale="1.0"
android:toXScale="0"
android:fromYScale="1.0"
android:toYScale="0"
android:duration="100"
/>
</set>複製程式碼
(2) 在styles.xml 中新增一個style
<style name="CustomPopWindowStyle">
<item name="android:windowEnterAnimation">@anim/popwindow_anim_in</item>
<item name="android:windowExitAnimation">@anim/popwindow_anim_out</item>
</style>複製程式碼
(3) 通過setAnimationStyle 應用動畫
CustomPopWindow popWindow = new CustomPopWindow.PopupWindowBuilder(this)
.setView(R.layout.pop_layout1)
.setFocusable(true)
.setOutsideTouchable(true)
.setAnimationStyle(R.style.CustomPopWindowStyle) // 新增自定義顯示和消失動畫
.create()
.showAsDropDown(mButton1,0,10);複製程式碼
通過上面就可以給PopupoWindow的顯示和消失新增動畫,除此之外,在API 21 以上,Google 給PopupWindow 新增了2個新方法用來新增顯示和消失時的過渡動畫,setEnterTransition
和setExitTransition
,有興趣的可以去研究一下。
五、總結
以上就是對於給PopupWindow的新增背景變暗和動畫的一些思路分析和實踐總結,如果你覺得每次新增一個PopupWindow很麻煩,那麼你不妨試一下這個簡單的庫,github.com/pinguo-zhou…。如果你還有什麼需要的功能,可以留言,我會新增到這個庫上面。