Android悬浮缩放菜单的实现

我的视频课程:《FFmpeg打造Android万能音频播放器


先看效果图:(文章结尾有Demo下载地址)


最近在做一个电商平台的应用,里面有一个效果就是在商品列表上层有一个圆形菜单,在列表滑动时菜单会收缩滑动停止时会展开。刚看到这个效果时感觉不好实现,首先是这个半圆,然后还会收缩变小,但是当我们把这个菜单拆分开来后就很好理解了:

1、首先是菜单背景那个圆,其实就是一个实体圆,只是向右偏离了一段距离,所以就呈现了半圆的效果;

2、然后是收缩效果,其实也不难,只是位移动画和缩放动画的合用而已,在大小缩放的同时再向左便宜就可以了;

3、然后就是里面的菜单项,也是用了位移,缩放和透明度的动画合集实现的。

原理就是这样的,只是具体位移多少,缩放多少就看自己的需求然后进行测试了。这里用到了View.animate().(...)属性动画。这个动画很简单也很实用,只是在3.0以后才有的,不过现在大多数都是基于4.0开发的APP,所以这个属性动画可以放心的用的。

现在看看实现步骤:

一、首先是绘制菜单背景圆:

<?xml version="1.0" encoding="utf-8"?>
<shape
    xmlns:android= "http://schemas.android.com/apk/res/android"
    android:shape= "oval"
    android:useLevel= "false" >
    <solid android:color= "#FF4081" />
</shape>
这里用shape就可以绘制一个实心圆了,不用使用图片。
二、菜单布局:

<RelativeLayout 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="${relativePackage}.${activityClass}" >
	<ListView 
	    android:id="@+id/listview"
	    android:layout_width="match_parent"
	    android:layout_height="match_parent"
	    >
	</ListView>
    <RelativeLayout
        android:id="@+id/rl_circle_menu"
        android:layout_width="162dp"
        android:layout_height="162dp"
        android:clickable="true"
        android:background="@drawable/circle_drawable"
        android:layout_alignParentBottom="true"
        android:layout_alignParentRight="true"
        android:layout_marginBottom="24dp"
        android:layout_marginRight="-92dp">
        <ImageView
            android:id="@+id/iv_show"
            android:layout_width="26dp"
            android:layout_height="34dp"
            android:src="@drawable/icon_show"
            android:layout_centerVertical="true"
            android:layout_marginLeft="8dp"/>
        <ImageView
            android:id="@+id/iv_home"
            android:layout_width="26dp"
            android:layout_height="34dp"
            android:src="@drawable/icon_homepage"
            android:layout_toRightOf="@+id/iv_show"
            android:layout_above="@+id/iv_show"
            android:layout_marginBottom="4dp"/>

        <ImageView
            android:id="@+id/iv_find"
            android:layout_width="26dp"
            android:layout_height="34dp"
            android:src="@drawable/icon_find"
            android:layout_toRightOf="@+id/iv_show"
            android:layout_below="@+id/iv_show"
            android:layout_marginTop="4dp"/>

        <ImageView
            android:id="@+id/iv_home_menu"
            android:layout_width="26dp"
            android:layout_height="34dp"
            android:src="@drawable/icon_menu"
            android:layout_centerVertical="true"
            android:layout_marginRight="8dp"
            android:layout_alignParentRight="true"/>
        
    </RelativeLayout>

</RelativeLayout>
结构就是使用相对布局,底层一个listview或者是viewpager等,然后在右下角再使用一个相对布局来实现菜单栏的布局就OK了。

三、动画的实现:

1、展开动画:

public void openMenu() {
		reCircleMenu.animate().scaleX(1f).scaleY(1f).translationX(0).setDuration(300).start();
		mivShow.animate().alpha(1).scaleX(1f).scaleY(1f).translationX(0f).setDuration(300).start();
		mivHome.animate().alpha(1).scaleX(1f).scaleY(1f).translationX(0).translationY(0).setDuration(300).start();
		mivfind.animate().alpha(1).scaleX(1f).scaleY(1f).translationX(0).translationY(0).setDuration(300).start();
		mivMenu.animate().scaleX(1f).scaleY(1f).translationX(0).setDuration(300).start();
	}

主要就是几种动画(透明度、缩放、位移)的集合实现,展开后的效果就是刚开始初始化的效果,所以这里把透明度、位移、缩放还原就行了。

2、缩放动画:

public void closeMenu() {
		reCircleMenu.animate().scaleX(0.3f).scaleY(0.3f).translationX(-dip2px(50)).setDuration(300).start();
		mivShow.animate().alpha(0).scaleX(10 / 3f).scaleY(10 / 3f).translationX(dip2px(60)).setDuration(300).start();
		mivHome.animate().alpha(0).scaleX(10 / 3f).scaleY(10 / 3f).translationX(dip2px(35)).translationY(dip2px(40)).setDuration(300)
				.start();
		mivfind.animate().alpha(0).scaleX(10 / 3f).scaleY(10 / 3f).translationX(dip2px(35)).translationY(-dip2px(40)).setDuration(300)
				.start();
		mivMenu.animate().scaleX(10 / 3f).scaleY(10 / 3f).translationX(-dip2px(60)).setDuration(300).start();
	}
这个就稍微复杂点,首先要同个多次测试找到合适的位移距离,其他的都不难。

四、滑动的监听:

listView.setOnScrollListener(new OnScrollListener() {

			@Override
			public void onScrollStateChanged(AbsListView view, int scrollState) {
				if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
					System.out.println("HOME PAGE SCROLL_STATE_TOUCH_SCROLL----");
					// isScrool = true;
					closeMenu();
				} else if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
					System.out.println("HOME PAGE SCROLL_STATE_FLING");
				} else if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE) {
					System.out.println("HOME PAGE SCROLL_STATE_IDLE");
					// isScrool = false;
					openMenu();
				}

			}

			@Override
			public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
				// TODO Auto-generated method stub

			}
		});
在刚开始滑动时就关闭菜单,滑动停止时打开菜单即可,这个监听可以放到任何可以监听到滑动状态的事件中,不止是在listview中。

通过以上步骤就实现了如效果图的效果,哈哈 现在想想还是多么简单的。很多问题看似复杂,通过分解成小问题后,就不是什么大问题了,解决办法就很多了,然后大问题也就迎刃而解了! 实例源码下载






  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ywl5320

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值