自Google Io 2014發(fā)布Material Design以來(lái),非常多知名應(yīng)用岳枷,如Evernote芒填、Teambition、Inbox等都使用了攜帶多個(gè)子按鈕的FloatingActionButton空繁。我個(gè)人非常喜歡這個(gè)效果殿衰,但是一個(gè)個(gè)的去布局寫動(dòng)畫,代碼還是蠻多的盛泡,所以想了想就把整個(gè)效果封裝起來(lái)了闷祥。順便也把它開源了,雖然不是什么很厲害的東西傲诵,不過(guò)還是希望大家能去點(diǎn)個(gè)fork啥的凯砍! 哈哈哈哈...??
OK,話不多說(shuō)拴竹,直接看我下面的Readme悟衩。
注意事項(xiàng)
該控件理論上最低支持到API版本14也就是Android4.0,并且由于是官方Support Library中FloatingActionButton的二次封裝殖熟,陰影的生成在API21以上和21以下并不太一樣局待,所以在不同版本的系統(tǒng)中的效果會(huì)存在一定的差異斑响。
該控件依賴了以下兩個(gè)support library菱属,使用者無(wú)需在項(xiàng)目里再次添加。
com.android.support:design:23.1.1
com.android.support:cardview-v7:23.1.0
項(xiàng)目地址
https://github.com/550609334/FloatingActionButtonPlus
如何使用
實(shí)現(xiàn)上圖的效果
btns.xml
<com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
android:id="@+id/FabPlus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:switchFabColor="#DB4537"
app:switchFabIcon="@mipmap/ic_add_white_48dp"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<com.lzp.floatingactionbuttonplus.FabTagLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tagText="Download"
>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_get_app_white_48dp"
app:backgroundTint="#468cb7"
app:fabSize="mini" />
</com.lzp.floatingactionbuttonplus.FabTagLayout>
<com.lzp.floatingactionbuttonplus.FabTagLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tagText="Favorites"
>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_stars_white_48dp"
app:backgroundTint="#818aa7"
app:fabSize="mini" />
</com.lzp.floatingactionbuttonplus.FabTagLayout>
<com.lzp.floatingactionbuttonplus.FabTagLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tagText="Send mail"
>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_send_white_48dp"
app:backgroundTint="#4BB7A7"
app:fabSize="mini" />
</com.lzp.floatingactionbuttonplus.FabTagLayout>
<com.lzp.floatingactionbuttonplus.FabTagLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tagText="shopping list"
>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_shopping_cart_white_48dp"
app:backgroundTint="#ff9800"
app:fabSize="mini" />
</com.lzp.floatingactionbuttonplus.FabTagLayout>
<com.lzp.floatingactionbuttonplus.FabTagLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:tagText="Search this page"
>
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_search_white_48dp"
app:backgroundTint="#4284E4"
app:fabSize="mini" />
</com.lzp.floatingactionbuttonplus.FabTagLayout>
</com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlwaysCollapsed"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
</android.support.v7.widget.RecyclerView>
<include layout="@layout/btns" />
</android.support.design.widget.CoordinatorLayout>
這樣就完成了上圖的效果舰罚。
最外層的com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
會(huì)帶有一個(gè)主按鈕纽门。FloatingActionButtonPlus中包含了多個(gè)FabTagLayout,而每一個(gè)FabTagLayout則就是一個(gè)item营罢。FabTagLayout帶有一個(gè)lable標(biāo)簽赏陵,你需要在FabTagLayout中再添加一個(gè)FloatingActionButton。請(qǐng)記住為每個(gè)item的FloatingActionButton添加上app:fabSize="mini"
饲漾,將其設(shè)置為mini型蝙搔。可通過(guò)app:backgroundTint="color"
更改這些fab的顏色考传。
定位
GIF會(huì)掉幀吃型,實(shí)際效果很流暢
如圖提供了四種position方式,默認(rèn)為right_bottom僚楞。其他為right_top勤晚、left_bottom枉层、left_top。在CoordinatorLayout中建議不要定位到top赐写,會(huì)被toolbar擋住鸟蜡。
position可在XML布局中設(shè)置,也可在JAVA代碼中設(shè)置挺邀。
XML
在com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus中添加
app:position="left_top"
value還可以是right_bottom揉忘、left_bottom、left_top
Java Code
首先有四個(gè)常量分別為
public static final int POS_LEFT_TOP = 0;
public static final int POS_LEFT_BOTTOM = 1;
public static final int POS_RIGHT_TOP = 2;
public static final int POS_RIGHT_BOTTOM = 3;
通過(guò)FloatingActionButtonPlus對(duì)象設(shè)置
mActionButtonPlus = (FloatingActionButtonPlus) findViewById(R.id.FabPlus);
mActionButtonPlus.setPosition(FloatingActionButtonPlus.POS_LEFT_TOP);
動(dòng)畫
動(dòng)畫暫時(shí)給了三種端铛,分別為fade癌淮、scale、bounce沦补,默認(rèn)為scale乳蓄。后續(xù)會(huì)可能會(huì)提供接口供使用者擴(kuò)展。動(dòng)畫同樣可以在XML中或Java中設(shè)置夕膀。
XML
在com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus中添加 fade虚倒、scale、bounce三個(gè)值中的一個(gè)产舞。如:
app:animationMode = "scale"
另可設(shè)置動(dòng)畫持續(xù)時(shí)間魂奥,單位為毫秒,默認(rèn)為150毫秒
app:animationDuration = "300"
Java code
首先有四個(gè)常量分別為
public static final int ANIM_FADE = 0;
public static final int ANIM_SCALE = 1;
public static final int ANIM_BOUNCE = 2;
通過(guò)FloatingActionButtonPlus對(duì)象設(shè)置
mActionButtonPlus.setPosition(FloatingActionButtonPlus.POS_LEFT_TOP);
mActionButtonPlus.setAnimation(FloatingActionButtonPlus.ANIM_SCALE);
動(dòng)畫持續(xù)時(shí)間可通過(guò)
mActionButtonPlus.setAnimationDuration(300);
事件
暫時(shí)只給出了item的點(diǎn)擊事件易猫,如果有更多類型事件的需求耻煤,歡迎Email聯(lián)系我。
mActionButtonPlus.setOnItemClickListener(new FloatingActionButtonPlus.OnItemClickListener() {
@Override
public void onItemClick(FabTagLayout tagView, int position) {
Toast.makeText(MainActivity.this, "Click btn" + position, Toast.LENGTH_SHORT).show();
}
});
滑動(dòng)顯示和滑動(dòng)隱藏
關(guān)于滑動(dòng)顯示隱藏准颓,這里有兩種方法哈蝇,
1、使用CoordinatorLayout
使用CoordinatorLayout的話攘已,首先要確保你的外層layout是android.support.design.widget.CoordinatorLayout
炮赦,如我上面activity_main.xml中的實(shí)例代碼。之后你需要在com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
中添加上app:layout_behavior="com.lzp.floatingactionbuttonplus.FabBehavior"
样勃,如下
<com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
android:id="@+id/FabPlus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:switchFabColor="#DB4537"
app:switchFabIcon="@mipmap/ic_add_white_48dp"
app:layout_behavior="com.lzp.floatingactionbuttonplus.FabBehavior"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
</com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus>
2吠勘、監(jiān)聽滑動(dòng)距離(judge scorll distance)
在沒(méi)有使用CoordinatorLayout的情況下,我給出了兩個(gè)public method峡眶。 分別為showFab() 和 hideFab()剧防。通過(guò)FloatingActionButtonPlus對(duì)象去調(diào)用。所以你如果想要實(shí)現(xiàn)通過(guò)這個(gè)效果辫樱,需要你去獲取當(dāng)前Scroll的距離峭拘。例如在RecyclerView中你可以這么寫:
mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (recyclerView.getScrollState() == RecyclerView.SCROLL_STATE_DRAGGING) {
if (dy > 0) {
mActionButtonPlus.hideFab();
} else {
mActionButtonPlus.showFab();
}
}
}
});
更多設(shè)置
XML
com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
app:switchFabIcon="@mipmap/ic_add_white_48dp" <!--設(shè)置主Fab的icon圖標(biāo)-->
app:switchFabColor="#DB4537" <!--設(shè)置主Fab的顏色-->
app:mBackgroundColor="#99ffffff" <!--設(shè)置item展開后的背景顏色,默認(rèn)為alpha99的白色-->
com.lzp.floatingactionbuttonplus.FabTagLayout
app:tagText="text" <!--設(shè)置item中l(wèi)able中顯示的文字-->
Java Code
com.lzp.floatingactionbuttonplus.FloatingActionButtonPlus
mActionButtonPlus.setContentIcon(getResources().getDrawable(R.mipmap.ic_add_white_48dp)); //設(shè)置主Fab的icon圖標(biāo)
mActionButtonPlus.setRotateValues(45); //設(shè)置主Fab被點(diǎn)擊時(shí)旋轉(zhuǎn)的度數(shù),默認(rèn)為45度
boolean state = mActionButtonPlus.getSwitchFabDisplayState(); //獲取當(dāng)前Fab的顯示狀態(tài)棚唆,顯示時(shí)返回true暇赤,隱藏返回false
com.lzp.floatingactionbuttonplus.FabTagLayout
tagView.setTagText("text"); //設(shè)置label中顯示的文字
其他
關(guān)于為什么不直接在FabTagLayout里集成FloatingActionButton
主要是因?yàn)镚oogle并沒(méi)有給出用java代碼設(shè)置FloatingActionButton的size的方法,所以沒(méi)辦法設(shè)置成mini型宵凌。我試過(guò)用反射去更改FloatingActionButton中的mSize這個(gè)private變量鞋囊,在api21之后,可行瞎惫,但21以下就會(huì)出現(xiàn)很多問(wèn)題溜腐,例如icon不會(huì)跟著變小,陰影會(huì)變成矩形瓜喇。這是因?yàn)樵贔loatingActionButton中是根據(jù)mSize的值去繪制陰影和決定icon大小的挺益。而這一切操作都是在它的constructor中完成,所以我選擇了讓使用者來(lái)指定每一個(gè)FloatingActionButton乘寒。 當(dāng)然日后也許我會(huì)試著制作一個(gè)獨(dú)立的FloatingActionButton來(lái)解決這個(gè)問(wèn)題望众。
關(guān)于遇到Bug
如果出現(xiàn)Bug,或者你有什么建議或需求伞辛,可以Email連系我烂翰。