Android懸浮縮放選單的實現
阿新 • • 發佈:2019-01-03
先看效果圖:(文章結尾有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就可以繪製一個實心圓了,不用使用圖片。二、選單佈局:
結構就是使用相對佈局,底層一個listview或者是viewpager等,然後在右下角再使用一個相對佈局來實現選單欄的佈局就OK了。<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>
三、動畫的實現:
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中。通過以上步驟就實現瞭如效果圖的效果,哈哈 現在想想還是多麼簡單的。很多問題看似複雜,通過分解成小問題後,就不是什麼大問題了,解決辦法就很多了,然後大問題也就迎刃而解了! 例項原始碼下載