Android利用動畫實現(xiàn)背景逐漸變暗
前言
之前寫了一篇Android-實現(xiàn)底部彈出PopupWindow并讓背景逐漸變暗,介紹利用Handler動態(tài)改變背景透明度從而達到變暗的效果?,F(xiàn)在補充一種方法,使用動畫來實現(xiàn)相同的效果。
ValueAnimator 和 Interpolator
今天的主角就是這倆,關(guān)于ValueAnimator和Interpolator(插值器)的概念請各位自行補充,這里主要講述怎么用到我們這里來(因為我也不很懂(捂臉))。
效果
跟之前沒有太大區(qū)別,只是為了演示變暗、變亮的過程 ↓
代碼
AnimUtil.java
/** * 動畫工具類 * UpdateListener: 動畫過程中通過添加此監(jiān)聽來回調(diào)數(shù)據(jù) * EndListener: 動畫結(jié)束的時候通過此監(jiān)聽器來做一些處理 */ public class AnimUtil { private ValueAnimator valueAnimator; private UpdateListener updateListener; private EndListener endListener; private long duration; private float start; private float end; private Interpolator interpolator = new LinearInterpolator(); public AnimUtil() { duration = 1000; //默認動畫時常1s start = 0.0f; end = 1.0f; interpolator = new LinearInterpolator();// 勻速的插值器 } public void setDuration(int timeLength) { duration = timeLength; } public void setValueAnimator(float start, float end, long duration) { this.start = start; this.end = end; this.duration = duration; } public void setInterpolator(Interpolator interpolator) { this.interpolator = interpolator; } public void startAnimator() { if (valueAnimator != null){ valueAnimator = null; } valueAnimator = ValueAnimator.ofFloat(start, end); valueAnimator.setDuration(duration); valueAnimator.setInterpolator(interpolator); valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { if (updateListener == null) { return; } float cur = (float) valueAnimator.getAnimatedValue(); updateListener.progress(cur); } }); valueAnimator.addListener(new Animator.AnimatorListener() { @Override public void onAnimationStart(Animator animator) {} @Override public void onAnimationEnd(Animator animator) { if(endListener == null){ return; } endListener.endUpdate(animator); } @Override public void onAnimationCancel(Animator animator) {} @Override public void onAnimationRepeat(Animator animator) {} }); valueAnimator.start(); } public void addUpdateListener(UpdateListener updateListener) { this.updateListener = updateListener; } public void addEndListner(EndListener endListener){ this.endListener = endListener; } public interface EndListener { void endUpdate(Animator animator); } public interface UpdateListener { void progress(float progress); } }
MainActivity.java
public class MainActivity extends AppCompatActivity { private AnimUtil animUtil; private float bgAlpha = 1f; private boolean bright = false; PopupWindow popupWindow; Button button; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); animUtil = new AnimUtil(); button = (Button) findViewById(R.id.btn); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { bottomwindow(button); toggleBright(); } }); } private void toggleBright() { //三個參數(shù)分別為: 起始值 結(jié)束值 時長 那么整個動畫回調(diào)過來的值就是從0.5f--1f的 animUtil.setValueAnimator(0.5f, 1f, 350); animUtil.addUpdateListener(new AnimUtil.UpdateListener() { @Override public void progress(float progress) { //此處系統(tǒng)會根據(jù)上述三個值,計算每次回調(diào)的值是多少,我們根據(jù)這個值來改變透明度 bgAlpha = bright ? progress : (1.5f - progress);//三目運算,應(yīng)該挺好懂的。 backgroundAlpha(bgAlpha);//在此處改變背景,這樣就不用通過Handler去刷新了。 } }); animUtil.addEndListner(new AnimUtil.EndListener() { @Override public void endUpdate(Animator animator) { //在一次動畫結(jié)束的時候,翻轉(zhuǎn)狀態(tài) bright = !bright; } }); animUtil.startAnimator(); } /*** * 此方法用于改變背景的透明度,從而達到“變暗”的效果 */ private void backgroundAlpha(float bgAlpha) { WindowManager.LayoutParams lp = getWindow().getAttributes(); lp.alpha = bgAlpha; //0.0-1.0 getWindow().setAttributes(lp); getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); } void bottomwindow(View view) { if (popupWindow != null && popupWindow.isShowing()) { return; } LinearLayout layout = (LinearLayout) getLayoutInflater().inflate(R.layout.window_popup, null); popupWindow = new PopupWindow(layout, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); //點擊空白處時,隱藏掉pop窗口 popupWindow.setFocusable(true); popupWindow.setBackgroundDrawable(new BitmapDrawable()); popupWindow.setAnimationStyle(R.style.Popupwindow); int[] location = new int[2]; view.getLocationOnScreen(location); popupWindow.showAtLocation(view, Gravity.LEFT | Gravity.BOTTOM, 0, -location[1]); popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() { @Override public void onDismiss() { toggleBright(); } }); } }
代碼很簡單,注釋都寫了。
小結(jié):
對比之前的那種用Handler的方法寫的,這種感覺代碼更簡潔,更容易在多處使用,也算是填坑吧,哈哈。 如果本文埋下了另一個坑,請大家指正,謝謝!
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android App開發(fā)中RecyclerView控件的基本使用教程
這篇文章主要介紹了Android App開發(fā)中RecyclerView控件的基本使用教程,RecyclerView在Android 5.0之后伴隨著Material Design出現(xiàn),管理布局方面十分強大,需要的朋友可以參考下2016-04-04Android編程之SQLite數(shù)據(jù)庫操作方法詳解
這篇文章主要介紹了Android編程之SQLite數(shù)據(jù)庫操作方法,簡單介紹了SQLite數(shù)據(jù)庫及Android操作SQLite數(shù)據(jù)庫的步驟與相關(guān)實現(xiàn)技巧,需要的朋友可以參考下2017-08-08Android網(wǎng)絡(luò)訪問之Retrofit使用教程
Retrofit?是一個?RESTful?的?HTTP?網(wǎng)絡(luò)請求框架的封裝,網(wǎng)絡(luò)請求的工作本質(zhì)上是?OkHttp?完成,而?Retrofit?僅負責?網(wǎng)絡(luò)請求接口的封裝2022-12-12Android應(yīng)用動態(tài)修改主題的方法示例
今天小編就為大家分享一篇關(guān)于Android應(yīng)用動態(tài)修改主題的方法示例,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03OpenHarmony實現(xiàn)屏幕亮度動態(tài)調(diào)節(jié)方法詳解
大家在拿到dayu之后,都吐槽說,會經(jīng)常熄屏,不利于調(diào)試,那么有沒有一種辦法,可以讓app不熄屏呢,答案是有的,今天我們就來揭秘一下,如何控制屏幕亮度2022-11-11android 應(yīng)用內(nèi)部懸浮可拖動按鈕簡單實現(xiàn)代碼
本篇文章主要介紹了android 應(yīng)用內(nèi)部懸浮可拖動按鈕簡單實現(xiàn)代碼,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10Android開發(fā)時盡管已root但是ddms還是沒有data路徑怎么辦
這篇文章主要介紹了Android開發(fā)時盡管已root但是ddms還是沒有data路徑怎么辦的相關(guān)資料,需要的朋友可以參考下2015-12-12