Android开发 PathButton 简单实现

偶然看到Path的动画很炫酷,所以摸索写了一个,无非是一个主按钮+卫星按钮,摆放好位置即可。
本来想写成一个拓展性的,结果脑袋卡壳半天不知道怎么写,所以还是贴一个固定位置的,有时间在改吧。
动画效果:位移+旋转+透明
点击效果:放大+透明(没做)

效果图
这里写图片描述
代码比较简单,直接贴

package com.zhou.pathbuttonview;

import java.util.ArrayList;
import java.util.List;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;

public class SimpleActivity extends Activity implements OnClickListener {

    private ImageView home, top, topleft, topleftleft, topright, toprightright;
    private List<ImageView> list = new ArrayList<ImageView>();
    private List<ObjectAnimator> anim_list = new ArrayList<ObjectAnimator>();
    private boolean home_flag = true, isFirst = true;// 卫星按钮打开关闭, 卫星按钮设置是否显示
    private int startX, startY;// 主按钮位置

    private RotateAnimation homeStartAnim, homeBackAnim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_simple);
        init();
        addListener();
    }

    private void init() {
        home = (ImageView) findViewById(R.id.home);
        top = (ImageView) findViewById(R.id.top);
        topleft = (ImageView) findViewById(R.id.topleft);
        topleftleft = (ImageView) findViewById(R.id.topleftleft);
        topright = (ImageView) findViewById(R.id.topright);
        toprightright = (ImageView) findViewById(R.id.toprightright);

        // 主按钮旋转动画
        homeStartAnim = new RotateAnimation(0, -135.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        homeStartAnim.setDuration(150);
        homeStartAnim.setFillAfter(true);
        homeBackAnim = new RotateAnimation(-135.0f, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
                0.5f);
        homeBackAnim.setDuration(150);
        homeBackAnim.setFillAfter(true);

        list.add(topleftleft);
        list.add(topleft);
        list.add(top);
        list.add(topright);
        list.add(toprightright);
        // 隐藏卫星按钮
        for (int i = 0; i < 5; i++) {
            list.get(i).setVisibility(View.INVISIBLE);
        }
    }

    private void addListener() {
        home.setOnClickListener(this);
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        // 获取home的坐标,作为展开时的起点/收缩时的终点
        int[] startXY = new int[2];
        home.getLocationOnScreen(startXY);
        startX = startXY[0] + home.getMeasuredWidth() / 2;
        startY = startXY[1] + home.getMeasuredWidth() / 2;
        for (int i = 0; i < list.size(); i++) {
            initStartAnimatorSet(list.get(i));// 初始化展开动画
        }
        for (int i = 0; i < list.size(); i++) {
            initFinishAnimatorSet(list.get(i));// 初始化收缩动画
        }
        super.onWindowFocusChanged(hasFocus);
    }

    // 坐标(0,0)是指view本身为原点,两view坐标差值为伸缩值。
    // 展开动画
    private void initStartAnimatorSet(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        ObjectAnimator set = getObjectAnimator(view, startX - view.getWidth() / 2 - location[0], 0,
                startY - view.getHeight() / 2 - location[1], 0, -360, 0f, 1f, 600);
        anim_list.add(set);
    }

    // 收缩动画
    private void initFinishAnimatorSet(View view) {
        int[] location = new int[2];
        view.getLocationOnScreen(location);
        ObjectAnimator set = getObjectAnimator(view, 0, startX - view.getWidth() / 2 - location[0], 0,
                startY - view.getHeight() / 2 - location[1], 360, 1f, 0f, 600);
        anim_list.add(set);
    }
    // 下面(startX, startX, endX,endX)写两次就是让它在外面多旋一会,最好是 (startX, startX, endX)
    /**
     * 
     * @param view
     *            传入的子view
     * @param startX
     *            起始位置X
     * @param endX
     *            结束位置X
     * @param startY
     *            起始位置Y
     * @param endY
     *            结束位置Y
     * @param degree
     *            旋转角度
     * @param startA
     *            开始透明度
     * @param endA
     *            结束透明度
     * @param time
     *            动画持续时间
     * @return
     */
    private ObjectAnimator getObjectAnimator(View view, float startX, float endX, float startY, float endY,
            float degree, float startA, float endA, long time) {
        PropertyValuesHolder pvh1 = PropertyValuesHolder.ofFloat("translationX", startX, startX, endX, endX);
        PropertyValuesHolder pvh2 = PropertyValuesHolder.ofFloat("translationY", startY, startY, endY, endY);
        PropertyValuesHolder pvh3 = PropertyValuesHolder.ofFloat("rotation", degree);
        PropertyValuesHolder pvh4 = PropertyValuesHolder.ofFloat("alpha", startA, endA);

        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(view, pvh1, pvh2, pvh3, pvh4)
                .setDuration(time);
        return objectAnimator;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.simple, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (R.id.home == id) {
            if (home_flag) {
                home.startAnimation(homeStartAnim);
                //第一次 让卫星按钮显示出来
                if (isFirst) {
                    for (int j = 0; j < 5; j++) {
                        list.get(j).setVisibility(View.VISIBLE);
                    }
                    isFirst = false;
                }

                for (int i = 0; i < 5; i++) {
                    anim_list.get(i).start();
                }
                home_flag = false;
            } else {
                home.startAnimation(homeBackAnim);
                for (int i = 5; i < 10; i++) {
                    anim_list.get(i).start();
                }
                home_flag = true;
            }
        }

    }
}

布局文件

<?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:background="#EED8AE" >

    <ImageView
        android:id="@+id/top"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_above="@+id/home"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="40dp"
        android:background="@drawable/shape_pathbutton"
        android:contentDescription="@string/app_name"
        android:scaleType="centerInside"
        android:src="@drawable/home" />

    <ImageView
        android:id="@+id/topleft"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_above="@+id/home"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp"
        android:layout_marginRight="15dp"
        android:layout_toLeftOf="@+id/top"
        android:background="@drawable/shape_pathbutton"
        android:contentDescription="@string/app_name"
        android:scaleType="centerInside"
        android:src="@drawable/light" />

    <ImageView
        android:id="@+id/topleftleft"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_above="@+id/home"
        android:layout_centerHorizontal="true"
        android:layout_marginRight="8dp"
        android:layout_toLeftOf="@+id/topleft"
        android:background="@drawable/shape_pathbutton"
        android:contentDescription="@string/app_name"
        android:scaleType="centerInside"
        android:src="@drawable/download" />

    <ImageView
        android:id="@+id/topright"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_above="@+id/home"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp"
        android:layout_marginLeft="15dp"
        android:layout_toRightOf="@+id/top"
        android:background="@drawable/shape_pathbutton"
        android:contentDescription="@string/app_name"
        android:scaleType="centerInside"
        android:src="@drawable/setting" />

    <ImageView
        android:id="@+id/toprightright"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:layout_above="@+id/home"
        android:layout_centerHorizontal="true"
        android:layout_marginLeft="8dp"
        android:layout_toRightOf="@+id/topright"
        android:background="@drawable/shape_pathbutton"
        android:contentDescription="@string/app_name"
        android:scaleType="centerInside"
        android:src="@drawable/location" />

    <ImageView
        android:id="@+id/home"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="20dp"
        android:background="@drawable/bg_pathhome"
        android:contentDescription="@string/app_name"
        android:scaleType="centerCrop"
        android:src="@drawable/add" />

</RelativeLayout>

在 drawable自定义两个shape就是一个圆,大小不一样而已,这里贴一个
shape_pathbutton

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >

    <corners
        android:bottomLeftRadius="15dip"
        android:bottomRightRadius="15dip"
        android:topLeftRadius="15dip"
        android:topRightRadius="15dip" />

    <stroke
        android:width="1px"
        android:color="@android:color/black" />

    <solid android:color="#DEDEDE" />

</shape>

另一个类似,不贴了。

Demo 戳我下载

猜你喜欢

转载自blog.csdn.net/ganfanzhou/article/details/50403899
今日推荐