我的视频课程:《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中。
通过以上步骤就实现了如效果图的效果,哈哈 现在想想还是多么简单的。很多问题看似复杂,通过分解成小问题后,就不是什么大问题了,解决办法就很多了,然后大问题也就迎刃而解了! 实例源码下载