widget中使用動畫效果
阿新 • • 發佈:2019-02-09
在activity中實現動畫,非常簡單。得益於Animation類。但是在widget中實現動畫效果,確很麻煩。由於widget中的限制太多,可以使用的控制元件太少。Gallery之類的都不支援,除非自己在原始碼環境中自定義新增,使RemoteViews支援。但是不是很實用,只合適編譯到Rom中的應用。
由於專案需要實現在一個widget中的imageView裡面,多張圖片定時切換,並且須帶淡入淡出的效果。並且該widget的佈局還相對有點複雜,並非簡單的就一個imageView控制元件,其中還包含GridView以及StackView這種顯示資料比較多的控制元件。
檢視資料,發現widget中只能使用LayoutAnimation,而LayoutAnimation這個類呢很特別,只有第一次載入的時候才會使包含在該佈局內的控制元件使用指定的動畫效果,之後就不會執行內部指定的動畫。因此首先想到的是,把動畫的執行次數設為infinite,即無限次,那麼動畫就不會停止了。但是這種方式只合適初始化時的等待動畫。在該專案中不適合,因為,需要定時去切換圖片,比如3秒,而RemoteViews支援的貼圖介面就是setImageView類似這種,一次貼一張的,那麼肯定需要一個定時器去計時,時間到了,則去貼一張新圖。如果把動畫的repeatCount設為無限次,而且動畫本身的duration就相當於一個定時器,動畫一旦開始,就會按照該時間,無限迴圈。,因此必須兩個動作,即貼圖的動作週期和動畫執行週期完全一致,才有可能做到上一張圖片執行完動畫,下一張圖片剛好貼上,繼續從頭開始執行動畫。但是這兩個定時器之間的同步是不可能的。因為動畫的執行時間非常嚴格沒有延時,而貼圖動作確存在延時,首先不可能完全同時開始計時,其次貼圖動作須在主執行緒中,加入的是主執行緒的訊息佇列,所以就會出現訊息處理的延時。
那麼唯一的方法就是,遵循載入佈局的時候,重新執行動畫。這就需要兩個完全一樣的佈局,在貼圖前進行切換,但是網上的資料,都是直接把主佈局切換掉,對於介面非常簡單的資料不多的widget可以這樣,但是複雜佈局的話,開銷太大,不現實。
仔細看了官方文件,發現了RemoteViews的兩個介面,哈哈,利用這兩個介面,則可以實現,切換掉單個控制元件的佈局,來達到實現輪訓動畫的目的。 一個是removeAllViews(viewId),另一個是addViews(viewId,nestedView) removeAllVIew則是將制定viewId中的子view清空,而addViews,則是將nestedView中的子view加入到viewId中,同時放入呼叫者的RemoteViews中。有這樣兩個介面,那麼實現區域性的佈局切換就簡單了。在Res下新建兩個佈局檔案,佈局完全一樣,只是檔名不同,在佈局中就包含單個imageView。在需要切圖之前把之前的佈局remove掉,放入新的佈局。那麼就會執行一次動畫,以此迴圈呼叫,就ok了。
由於專案需要實現在一個widget中的imageView裡面,多張圖片定時切換,並且須帶淡入淡出的效果。並且該widget的佈局還相對有點複雜,並非簡單的就一個imageView控制元件,其中還包含GridView以及StackView這種顯示資料比較多的控制元件。
檢視資料,發現widget中只能使用LayoutAnimation,而LayoutAnimation這個類呢很特別,只有第一次載入的時候才會使包含在該佈局內的控制元件使用指定的動畫效果,之後就不會執行內部指定的動畫。因此首先想到的是,把動畫的執行次數設為infinite,即無限次,那麼動畫就不會停止了。但是這種方式只合適初始化時的等待動畫。在該專案中不適合,因為,需要定時去切換圖片,比如3秒,而RemoteViews支援的貼圖介面就是setImageView類似這種,一次貼一張的,那麼肯定需要一個定時器去計時,時間到了,則去貼一張新圖。如果把動畫的repeatCount設為無限次,而且動畫本身的duration就相當於一個定時器,動畫一旦開始,就會按照該時間,無限迴圈。,因此必須兩個動作,即貼圖的動作週期和動畫執行週期完全一致,才有可能做到上一張圖片執行完動畫,下一張圖片剛好貼上,繼續從頭開始執行動畫。但是這兩個定時器之間的同步是不可能的。因為動畫的執行時間非常嚴格沒有延時,而貼圖動作確存在延時,首先不可能完全同時開始計時,其次貼圖動作須在主執行緒中,加入的是主執行緒的訊息佇列,所以就會出現訊息處理的延時。
那麼唯一的方法就是,遵循載入佈局的時候,重新執行動畫。這就需要兩個完全一樣的佈局,在貼圖前進行切換,但是網上的資料,都是直接把主佈局切換掉,對於介面非常簡單的資料不多的widget可以這樣,但是複雜佈局的話,開銷太大,不現實。
仔細看了官方文件,發現了RemoteViews的兩個介面,哈哈,利用這兩個介面,則可以實現,切換掉單個控制元件的佈局,來達到實現輪訓動畫的目的。 一個是removeAllViews(viewId),另一個是addViews(viewId,nestedView) removeAllVIew則是將制定viewId中的子view清空,而addViews,則是將nestedView中的子view加入到viewId中,同時放入呼叫者的RemoteViews中。有這樣兩個介面,那麼實現區域性的佈局切換就簡單了。在Res下新建兩個佈局檔案,佈局完全一樣,只是檔名不同,在佈局中就包含單個imageView。在需要切圖之前把之前的佈局remove掉,放入新的佈局。那麼就會執行一次動畫,以此迴圈呼叫,就ok了。