屬性動(dòng)畫,快速打造,練手用
image.png
預(yù)覽圖:
menu.gif
一、制作圓形圖標(biāo)
很方便地利用as自動(dòng)生成圓形圖標(biāo):
- 右擊
res
,選擇Image Asset
:
image.png
- 選擇
Launcher Icons
,然后選Square
,其余自己調(diào)整:
image.png
現(xiàn)在,mipmap中有了相關(guān)圖片~~
當(dāng)然,普通icon加個(gè)shape也是很方便的~
二、布局文件
很簡(jiǎn)單,新建一個(gè)布局文件,記得把加號(hào)圖標(biāo)放最下面,這樣就能遮住別的圖標(biāo),直接上代碼了:
//layout/circle_menu_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:orientation="vertical">
<ImageView
android:id="@+id/circle_menu_button_2"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:src="@mipmap/ic_edit1" />
<ImageView
android:id="@+id/circle_menu_button_3"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:src="@mipmap/ic_star" />
<ImageView
android:id="@+id/circle_menu_button_4"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:src="@mipmap/ic_cloud" />
<ImageView
android:id="@+id/circle_menu_button_5"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="15dp"
android:layout_marginRight="15dp"
android:src="@mipmap/ic_look" />
<ImageView
android:id="@+id/circle_menu_button_1"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_gravity="bottom|right"
android:layout_marginBottom="12dp"
android:layout_marginRight="12dp"
android:src="@mipmap/ic_add" />
</FrameLayout>
在總的布局文件中,直接include引入即可:
<include layout="@layout/circle_menu_layout" />
三、代碼中使用屬性動(dòng)畫
- 首先定義變量,分別是資源id數(shù)組,圖片隊(duì)列,用來標(biāo)明開關(guān)狀態(tài)的標(biāo)志位
//扇形菜單按鈕
private int res[] ={R.id.circle_menu_button_1,R.id.circle_menu_button_2,R.id.circle_menu_button_3,R.id.circle_menu_button_4,R.id.circle_menu_button_5};
private ArrayList<ImageView> imageViews = new ArrayList<>();
//菜單是否展開的flag,false表示沒展開
private boolean mFlag = false;
- 利用for循環(huán)初始化圖標(biāo)實(shí)例
for (int i = 0; i < res.length; i++) {
ImageView imageView = (ImageView) mContentView.findViewById(res[i]);
imageView.setOnClickListener(this);
imageViews.add(imageView);
}
- 在點(diǎn)擊事件
onClick()
中,判斷開關(guān)狀態(tài)后,開啟進(jìn)入或者退出的動(dòng)畫方法
case R.id.circle_menu_button_1:
if (mFlag == false){
showEnterAnim(100); //100為扇形半徑dp值
}else {
showExitAnim(100);
}
break;
- 下面來看看最重要的
showEnterAnim()
方法:
//顯示扇形菜單的屬性動(dòng)畫
private void showEnterAnim(int dp) {
//for循環(huán)來開始小圖標(biāo)的出現(xiàn)動(dòng)畫
for (int i = 1; i < res.length; i++) {
AnimatorSet set = new AnimatorSet();
double x = -Math.cos(0.5/(res.length-2)*(i-1)*Math.PI)* Utils.dip2px(mContext,dp);
double y = -Math.sin(0.5/(res.length-2)*(i-1)*Math.PI)* Utils.dip2px(mContext,dp);
set.playTogether(
ObjectAnimator.ofFloat(imageViews.get(i),"translationX",(float)(x*0.25),(float)x),
ObjectAnimator.ofFloat(imageViews.get(i),"translationY",(float)(y*0.25),(float)y)
,ObjectAnimator.ofFloat(imageViews.get(i),"alpha",0,1).setDuration(2000)
);
set.setInterpolator(new BounceInterpolator());
set.setDuration(500).setStartDelay(100*i);
set.start();
}
//轉(zhuǎn)動(dòng)加號(hào)大圖標(biāo)本身45°
ObjectAnimator rotate = ObjectAnimator.ofFloat(imageViews.get(0),"rotation",0,45).setDuration(300);
rotate.setInterpolator(new BounceInterpolator());
rotate.start();
//菜單狀態(tài)置打開
mFlag = true;
}
唯一的難點(diǎn)就是根據(jù)第幾個(gè)小圖標(biāo),計(jì)算小圖標(biāo)的xy軸坐標(biāo)了,注意三角函數(shù)Math.sin()
的參數(shù)不是度數(shù),而是弧度制的角度大小。
- 退出動(dòng)畫其實(shí)和上面是相反的操作,參數(shù)前后換一下即可,但是考慮到是退出,所以應(yīng)該時(shí)間短一點(diǎn),變透明得快一點(diǎn),且差值器就不用回彈效果了,可以用減速器的差值器(這樣一開始可以速度快點(diǎn)),代碼就不貼了。
- 上面用到了一個(gè)工具類函數(shù)
Utils.dip2px()
轉(zhuǎn)換dp參數(shù)為px值,如下:
public static int dip2px(Context context, float dpValue) {
final float scale = context.getResources().getDisplayMetrics().density;
return (int) (dpValue * scale);
}
四、總結(jié)
實(shí)現(xiàn)效果:
menu.gif
總的來說,屬性動(dòng)畫可以快速方便地實(shí)現(xiàn)較為炫酷的效果,要自己多寫幾個(gè)經(jīng)典的demo試試就行了。下一步可以學(xué)習(xí)更為厲害的VectorDrawable和貝塞爾曲線等等~~