属性动画-菜单以散开的方式弹出

                                                                                            属性动画-菜单以散开的方式弹出

我们先来看XML文件,文件名是activity_main.

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/img_b"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@mipmap/ic_launcher"/>

    <ImageView
        android:id="@+id/img_c"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@mipmap/ic_launcher"/>
    <ImageView
        android:id="@+id/img_d"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@mipmap/ic_launcher"/>
    <ImageView
        android:id="@+id/img_e"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="20dp"
        android:src="@mipmap/ic_launcher"/>
    <ImageView
        android:id="@+id/img_a"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:src="@mipmap/ic_launcher"/>
</FrameLayout>

很简单,一个framlayout布局,然后,将所有的子按钮和菜单按钮叠放在一起。需要注意的是,要将最后显示的图片(也就是所谓的菜单按钮)放在最上面。


public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //数组存放图片ID,通过list进行图片遍历
    private int[] res = {R.id.img_a,R.id.img_b,
            R.id.img_c,R.id.img_d,R.id.img_e};
    private List<ImageView> list_img =
            new ArrayList<ImageView>();
    /*
     1.  flag为true,当点击按钮的时候,弹出菜单
     2.  flag为false,当点击按钮的时候,收回菜单
    */
    private boolean flag = true;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        for(int i=0;i<res.length;i++){
            ImageView img = (ImageView)
                    findViewById(res[i]);
            img.setOnClickListener(this);
            list_img.add(img);
        }
    }
    @Override
    public void onClick(View view){
        switch (view.getId()){
            case R.id.img_a:
                if(flag){
                    startAnim();  //弹出菜单动画
                }else{
                    closeAnim();  //收回菜单动画
                }
                break;
            default:
//这里只是简单的对弹出按钮的点击响应进行了处理,具体应用时可以进行完善
                Toast.makeText(MainActivity.this,"click"+view.getId(),
                        Toast.LENGTH_SHORT).show();
                break;
        }
    }

    private void closeAnim(){
        for(int i =1;i<res.length;i++){
//给出一个沿Y轴移动的动画
            ObjectAnimator animator = ObjectAnimator.ofFloat(
                    list_img.get(i),"translationY",(res.length-i-1)*50f,0f );
//给出一个沿X轴移动的动画
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(
                    list_img.get(i),"translationX",(i-1)*50f,0f );
            //定义属性动画集合的对象
            AnimatorSet animSet = new AnimatorSet();
            //通过with方法,让两个动画同时进行
            animSet.play(animator).with(animator1);
            //设置延迟时间,让菜单内容相继弹出
            animSet.setStartDelay(500);
            animSet.start();
            //然后,设置flag为true,当再次点击的时候,收回菜单
            flag = true;
        }
    }
    //两种方法的内容大体相同,只是动画属性的参数相反
    private void startAnim() {
        for(int i =1;i<res.length;i++){
            ObjectAnimator animator = ObjectAnimator.ofFloat(
                    list_img.get(i),"translationY",
                    0f,(res.length-i-1)*50f );
            ObjectAnimator animator1 = ObjectAnimator.ofFloat(
                    list_img.get(i),"translationX", 0f , (i-1)*50f );
            AnimatorSet animSet = new AnimatorSet();
            animSet.play(animator).with(animator1);
            animSet.setStartDelay(500);
            animSet.start();
            flag = false;
        }
    }
}

对照上面的代码,进行下面的一些解释:
1、这里解释一下ObjectAnimator对象的参数的含义:
ObjectAnimator animator = ObjectAnimator.ofFloat(
list_img.get(i),”translationY”,
0f,(res.length-i-1)*50f );
第一个是object对象,添加的是我们所要赋予动画效果的对象,
如我们的list_img.get(i)
第二个是动画属性,也就是我们想要的动画效果
之后的就是设置动画属性的参数,跟animation动画参数设置一样。

2、下面说明一下动画属性的参数设置:
再来明确一下我们的目的:我们的目的,是想让菜单里的子按钮依次散布在菜单按钮的周围,形成直角。因此,各个子按钮的Y值应该是依次减小的,而它们的X值则是依次增加,并且这个动画变化过程是同时进行的。 好,下面,我们借助list来进行参数设置。
对于”translationY”,我们让它从Y=0 的地方,依次往外弹出(res.length-i-1)*50f 的距离。50F是我们设置的各个子按钮之间Y轴的距离。i则代表我们加载的图片资源的序号。这里要注意!我们的i是从1开始的。也就是让菜单按钮保持不动,所以,为了让最后一个子按钮的Y值为零,也就是跟屏幕上端平行,我们还要再减一,即我们的乘数因子为(res.length-i-1)。当i=1的时候,第一个子按钮的Y值最大,距离屏幕上端最远,然后,随着i值的增大,子按钮的Y值逐渐减小,距离屏幕上端也越来越近。
同理,对于”translationX”,则是从X=0的地方,依次弹出(i-1)*50f的距离。

2、closeAnim()方法内容跟startAnim()大体相同,只是参数设置上略有区别。收回菜单的是,子按钮的动画轨迹跟弹出的时候是相反的,所以,我们只需要把动画属性的参数调换一下位置即可。如有疑问,请参考代码进行对比。


















  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值