[安卓] 18、一個簡單的例子做自定義動畫按鈕和自定義Actionbar


 

在做安卓UI的時候有時候需自定義具有動畫效果的按鈕或需要自定義一下actionbar~

本節用一個簡單的demo講如何自定義具有動畫效果的按鈕,以及個性化的actionbar

下面是效果

其中:

自定義button是由  個ImageView animation動畫構成

actionbar是自定義的效果,按鈕按動也用到了動畫

 

下面是整個工程的結構

 

 需要引用v7工程,因為繼承了v7的ActionBarActivity

 

 其中MyAnimation.java包含按鈕動畫的方法

 其中MyActionBar.java封裝自定義ActionBar的構造和監聽函數

 其中MyButton.java封裝自定義Button的構造和監聽函數

 MainActivity.java是主Activity

 

 

 

 

 

 自定義actionbar上面的按鈕偶數次按下施加的動畫定義(順時針旋轉90度)

 自定義actionbar上面的按鈕奇數次按下施加的動畫定義(逆時針選轉90度)

 自定義button偶數次按下施加的旋轉動畫(順時針360度)

 自定義button奇數次按下施加的旋轉動畫(逆時針360度)

 bar1-4自定義actionbar上面的從左到右四個圖片

 icon

 ...down自定義button黃色

 ...up自定義button綠色

 自定義button橙色

 activity_main.xml 主頁面

 layout_actionbar.xml 自定義actionbar樣式

 colors.xml 定義了actionbar和主頁面的背景顏色(銀灰色)

 styles.xml 定義了主頁面的主題(需要在Manifiest文件中用到,且一定得是Theme.Base.AppCompat.Light同一款的主題,否則出錯)

 

 

 

 

首先來看MainActivity.java

其中黃色的是自定義Button相關的部分,紅色的是自定義ActionBar相關的部分

其中自定義Button包含3個ImageView,所以第18行要用這三個ImageView構造自定義Button

 1 public class MainActivity extends ActionBarActivity{
 2 
 3     private ImageView mImageViewMain, mImageViewMainUp, mImageViewMainDown;  4     private MyButton mMyButton;  5     private MyActionBar mMyActionBar;  6     
 7 
 8     
 9     protected void onCreate(Bundle savedInstanceState) {
10         super.onCreate(savedInstanceState);
11         this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
12                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
13         setContentView(R.layout.activity_main);
14         
15         mImageViewMain = (ImageView) findViewById(R.id.imageView_btn_bottom); 16         mImageViewMainUp = (ImageView) findViewById(R.id.imageView_btn_top); 17         mImageViewMainDown = (ImageView) findViewById(R.id.imageView_btn_middle); 18         mMyButton=new MyButton(this,mImageViewMain,mImageViewMainUp,mImageViewMainDown); 19         
20 mMyActionBar=new MyActionBar(this); 21  mMyActionBar.setActionBar(); 22     }
23     
24     public void onMyButtonClick(View view){ 25  mMyButton.onClick(view); 26  } 27     
28     public void onMyActionBarClick(View view){ 29  mMyActionBar.onClick(view); 30  } 31 }

這里重點說一下自定義按鈕和自定義actionBar的監聽函數:

其實在MyButton和MyActionBar中實現的只是onClick監聽函數,並沒有和具體事件綁定

我們最常見的是XXXX.setOnClickListener(....)

這里是用了直接在相應控件的XML中定義:

類似的也采用同樣的方法給ActionBar上的左1、3、4按鈕加了一個同樣的onMyActionBarClick監聽事件

注:一旦在MXL中注冊一定要在activity.java中實現!!!

 

接着看MyButton.java的具體實現:

構造函數不說了~

在onClick函數中用view.getId()區分點擊的按鈕是哪一個

這個自定義按鈕有兩種狀態

未被按——橙紅色的按鈕在上面不透明;黃色和綠色按鈕在下面透明

被按下——黃色按鈕向上移200單位,綠色向上400單位,兩個均變成不透明

在未被按狀態點擊橙紅色按鈕——橙紅色逆時針旋轉360度,黃色和綠色同時向上移動200和400單位,同時兩個ImageView大小從0倍到1倍放大,透明度從完全透明到不透明

在被點擊狀態點擊三個按鈕中任何一個——所有按鈕的動畫逆向回歸

 1 public class MyButton {
 2 
 3     private ImageView mImageViewMain, mImageViewMainUp, mImageViewMainDown;
 4     private Context context;
 5     private boolean isPressed;
 6     private MyAnimation mMyAnimation;//動畫相關
 7     
 8     public MyButton(Context context,
 9             ImageView mImageViewMain,ImageView mImageViewMainUp,ImageView mImageViewMainDown){
10         isPressed=false;
11         this.context=context;
12         this.mImageViewMain=mImageViewMain;
13         this.mImageViewMainUp=mImageViewMainUp;
14         this.mImageViewMainDown=mImageViewMainDown;
15         mMyAnimation=new MyAnimation(context);
16     }
17     
18     /**
19      * 三個按鈕的點擊事件
20      * @param view
21      */
22     private static int[] button_animation_id={R.anim.my_button_rotate_go,R.anim.my_button_rotate_back};
23     public void onClick(View view) {
24         
25         switch (view.getId()) {
26         case R.id.imageView_btn_bottom:
27             mMyAnimation.rotation(view,button_animation_id[isPressed==false ? 0:1]);
28             mMyAnimation.animationShow(mImageViewMainUp, 400,!isPressed);
29             mMyAnimation.animationShow(mImageViewMainDown, 200,!isPressed);
30             break;
31         case R.id.imageView_btn_top:
32             mMyAnimation.rotation(mImageViewMain,button_animation_id[isPressed==false ? 0:1]);
33             mMyAnimation.animationShow(mImageViewMainUp, 400,!isPressed);
34             mMyAnimation.animationShow(mImageViewMainDown, 200,!isPressed);
35             break;
36         case R.id.imageView_btn_middle:
37             mMyAnimation.rotation(mImageViewMain,button_animation_id[isPressed==false ? 0:1]);
38             mMyAnimation.animationShow(mImageViewMainUp, 400,!isPressed);
39             mMyAnimation.animationShow(mImageViewMainDown, 200,!isPressed);
40             break;
41         default:
42             break;
43         }
44         isPressed=!isPressed;
45     }
46 }

 

相同的,MyActionBar.java中:

左1、3、4三個按鈕有一個旋轉90度的動畫效果~

 1 public class MyActionBar {
 2 
 3     private ActionBar actionBar;
 4     private LayoutInflater inflator;
 5     private Context context;
 6     private MyAnimation mMyAnimation;//動畫相關
 7     private boolean bar1_isPressed,bar2_isPressed,bar3_isPressed,bar4_isPressed;
 8     
 9     public MyActionBar(Context context){
10         this.context=context;
11         bar1_isPressed=bar2_isPressed=bar3_isPressed=bar4_isPressed=false;
12         mMyAnimation=new MyAnimation(context);
13     }
14     
15     public void setActionBar() {// 自定義actionbar
16         inflator = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
17         actionBar = ((ActionBarActivity)context).getSupportActionBar();
18         actionBar.setDisplayShowHomeEnabled(false);
19         actionBar.setDisplayShowCustomEnabled(true);
20         actionBar.setDisplayShowTitleEnabled(false);
21         actionBar.setDisplayHomeAsUpEnabled(false);
22 
23         View view = inflator.inflate(R.layout.layout_actionbar, null);
24         ActionBar.LayoutParams layout = new ActionBar.LayoutParams(
25                 LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
26         actionBar.setCustomView(view, layout);
27     }
28     
29     private static int[] actionbar_animation_id={R.anim.my_actionbar_rotate_go,R.anim.my_actionbar_rotate_back};
30     public void onClick(View view) {
31         switch (view.getId()) {
32         case R.id.imageView_bar1:
33             mMyAnimation.rotation(view,actionbar_animation_id[bar1_isPressed==false ? 0:1]);
34             bar1_isPressed=!bar1_isPressed;
35             break;
36         case R.id.imageView_bar3:
37             mMyAnimation.rotation(view,actionbar_animation_id[bar3_isPressed==false ? 0:1]);
38             bar3_isPressed=!bar3_isPressed;
39             break;
40         case R.id.imageView_bar4:
41             mMyAnimation.rotation(view,actionbar_animation_id[bar4_isPressed==false ? 0:1]);
42             bar4_isPressed=!bar4_isPressed;
43             break;
44         }
45     }
46

 

上面兩個自定義控件中的動畫效果功能函數封裝在Animation.java中:

rotation函數負責將id所指的動畫資源作用於view上

animationShow是作用與view使之出現或消失並可以帶有向上或向下、變大或變小的運動效果

 1 public class MyAnimation {
 2     
 3     private Context context;
 4     
 5     public MyAnimation(Context context){
 6         this.context=context;
 7     }
 8     
 9     /**
10      * 讓view執行id的動畫
11      * @param view
12      * @param id
13      */
14     public void rotation(View view,int id) {
15     
16         Animation operatingAnim;
17         operatingAnim = AnimationUtils.loadAnimation(context,id);
18         LinearInterpolator lin = new LinearInterpolator();
19         operatingAnim.setInterpolator(lin);
20         view.clearAnimation();
21         view.startAnimation(operatingAnim);
22     }
23     
24     /**
25      * 讓view從無到有顯示出來(大小1:1,up為正為向下走,為負向上走)
26      * @param view
27      * @param up
28      */
29     /**
30      * 讓view從無到有顯示出來
31      * @param view
32      * @param dis 去或者回來的距離(去是從原點到上面dis距離),來是從dis距離向下到原點
33      * @param isGo 為true是去,為fasle是回
34      */
35     public void animationShow(View view, int dis,boolean isGo) {
36         
37         AnimatorSet set = new AnimatorSet();
38         if(isGo==true){
39             set.playTogether(ObjectAnimator.ofFloat(view, "translationY", 0, -dis),
40                     ObjectAnimator.ofFloat(view, "scaleX", 0f, 1f),
41                     ObjectAnimator.ofFloat(view, "scaleY", 0f, 1f),
42                     ObjectAnimator.ofFloat(view, "alpha", 0f, 1f));
43         }else{
44             set.playTogether(ObjectAnimator.ofFloat(view, "translationY", -dis, 0),
45                     ObjectAnimator.ofFloat(view, "scaleX", 1f, 0f),
46                     ObjectAnimator.ofFloat(view, "scaleY", 1f, 0f),
47                     ObjectAnimator.ofFloat(view, "alpha", 1f, 0f));
48         }
49         
50         set.start();
51     }
52 }

 

下面是res/anim下的個動畫集合,他們的id就是傳入rotation的id~

其中button相關的兩個負責自定義button中橙紅色按鈕旋轉360用;其中actionbar相關的負責actionbar上的按鈕旋轉90度用

注意:下面綠色的部分是為了防止動畫結束之后又恢復原狀而加的屬性,一定要加在set中!!!

其中from和to表示:該動畫從角度為from旋轉到to的位置,其中正表示順時針角度,負表示逆時針角度,0為最初狀態角度

其中duration表示:該動畫持續的時間ms

其中pivotX/Y表示:該旋轉繞哪里旋轉

my_button_rotate_back.xml

 1 <set xmlns:android="http://schemas.android.com/apk/res/android"
 2            android:fillAfter="true"  > 
 3         
 4     <rotate  
 5         android:fromDegrees="0"  
 6  android:toDegrees="359"  
 7  android:duration="200"  
 8  android:pivotX="50%"  
 9  android:pivotY="50%"/>  
10 </set>  

my_button_rotate_go.xml

 1 <set xmlns:android="http://schemas.android.com/apk/res/android"
 2  android:fillAfter="true"  > 
 3            
 4     <rotate  
 5         android:fromDegrees="0"  
 6         android:toDegrees="-359"  
 7         android:duration="200"  
 8         android:pivotX="50%"  
 9         android:pivotY="50%"/>  
10 </set>  

my_actionbar_rotate_go.xml

 1 <?xml version="1.0" encoding="utf-8"?>  
 2 <set xmlns:android="http://schemas.android.com/apk/res/android"
 3  android:fillAfter="true"  > 
 4              
 5     <rotate 
 6         android:fromDegrees="0"  
 7         android:toDegrees="-90"  
 8         android:duration="200"  
 9         android:pivotX="50%"  
10         android:pivotY="50%"/>  
11 </set>  

my_actionbar_rotate_back.xml

 1 <set xmlns:android="http://schemas.android.com/apk/res/android"
 2  android:fillAfter="true"  > 
 3            
 4     <rotate  
 5         android:fromDegrees="-90"  
 6         android:toDegrees="0"  
 7         android:duration="200"  
 8         android:pivotX="50%"  
 9         android:pivotY="50%"/>  
10 </set>  

其中:shape_main_adding.xml負責自定按鈕下面遮罩層的從上到下的白色模糊效果(類似於iPad上面的扁平狀ICON條)

1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3     <gradient
4         android:startColor="#AAFFFFFF"
5         android:endColor="#00EEEEEE"
6         android:angle="90" />
7 </shape>
8 
9 <!-- http://l62s.iteye.com/blog/1659433  -->

 

相關鏈接:

本講的工程代碼:http://pan.baidu.com/s/1o65ZOca

Android使用Animation完成動畫淡出效果避免重新恢復最后一幀亮度的辦法(用這個解決了動畫播放完就恢復的問題,加了代碼中綠色的那條)

Android應用開發筆記(10):制作自定義背景Button按鈕、自定義形狀Button的全攻略(我沒用這個的)

Android自定義ActionBar(我沒用這個的)

android 圍繞中心旋轉動畫(這個我有參考,設計旋轉360度view效果的時候,里面比較詳細)

Android屬性動畫(Property Animation) 完全解析 (上)(這個講的挺全的,我沒仔細看)

android用NineOldAndroid實現的彈出按鈕(我從這個找到靈感設計自己的button)

Android背景漸變色(shape,gradient)(用這個解決了設計模糊遮罩的效果,很好的)

Android布局----讓一個控件居底部(有看看,沒用)

 

 

@beautifulzzzz 

  2015-11-18 持續更新中~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM