谷歌在android 5.0 發(fā)布后雀扶,隨后公布了design庫和設(shè)計(jì)理念(需翻墻)焰络,意圖在于規(guī)范安卓app的風(fēng)格弦叶,類似而不僅僅ios的扁平風(fēng)。我認(rèn)為每個(gè)android的開發(fā)和設(shè)計(jì)人員都應(yīng)該看一看這個(gè)抱环,站在巨人的肩膀上摘甜品何樂而不為。
之前寫的是基于design支持包25版本的API,沒想到的是snackbar在升級(jí)后的源碼發(fā)生了改變镇草,這版是基于android 8.0sdk眶痰、design 26.1.0、gradle 4.1陶夜、android studio 3.0.1所編寫凛驮。
??下面進(jìn)入正題。首先我們需要集成design庫:
????implementation 'com.android.support:design:26.1.0'
庫中分別有FloatingActionButton(懸浮操作按鈕)条辟、CollapsingToolbarLayout(可伸縮折疊的ToolBar)黔夭、TabLayout(選項(xiàng)卡)、Snackbar等組件羽嫡。今天只說Snackbar本姥,官方文檔在此,英文好的少年建議先看官方文檔杭棵。先放一張爛大街的圖
Snackbar的出現(xiàn)旨在替換Toast婚惫。它比Toast的拓展性更高,源碼相對(duì)比較簡(jiǎn)單魂爪。使用方法也和Toast極其類似先舷。可以透過源碼看到它的顯示主體叫做SnackbarLayout滓侍,一個(gè)內(nèi)部類蒋川,繼承于LinearLayout。所以Snackbar就是一個(gè)LinearLayout撩笆。其public方法主要有以下幾個(gè):
make(View view, CharSequence text, int duration)
這個(gè)靜態(tài)方法是使用Snackbar的入口捺球,因?yàn)镾nackbar的構(gòu)造是私有的。第一個(gè)參數(shù)是一個(gè)View夕冲。這個(gè)view可以傳子view氮兵,傳進(jìn)去會(huì)判斷并拿到根ViewGroup,Snackbar即添加到此ViewGroup歹鱼。判斷方法如下
<pre><code>
private static ViewGroup findSuitableParent(View view) {
ViewGroup fallback = null;
do {
if (view instanceof CoordinatorLayout) {
return (ViewGroup) view;
} else if (view instanceof FrameLayout) {
if (view.getId() == android.R.id.content) {
return (ViewGroup) view;
} else {
fallback = (ViewGroup) view;
}
}
if (view != null) {
final ViewParent parent = view.getParent();
view = parent instanceof View ? (View) parent : null;
}
} while (view != null);
return fallback;
}
</pre></code>
??第二個(gè)參數(shù)是Snackbar顯示的文字內(nèi)容泣栈,可以穿字符串,也可以傳string resID弥姻,不再累述秩霍。
??第三個(gè)參數(shù)是顯示時(shí)長(zhǎng),三個(gè)值供選擇:
名稱 | 意義 |
---|---|
LENGTH_INDEFINITE | 始終顯示蚁阳,點(diǎn)擊Snackbar上的按鈕才會(huì)消失 |
LENGTH_SHORT | 顯示1500毫秒 |
LENGTH_LONG | 顯示2750毫秒 |
setText(CharSequence message)
修改文字铃绒,可穿字符串和string resID。
setAction(CharSequence text, final View.OnClickListener listener)
第一個(gè)參數(shù)設(shè)置點(diǎn)擊部分的文字螺捐。第二個(gè)參數(shù)則是給Snackbar設(shè)置點(diǎn)擊事件颠悬,不需要再在onClick里去寫dismiss矮燎,點(diǎn)擊事件執(zhí)行完會(huì)自動(dòng)dismiss。
setActionTextColor(ColorStateList colors)
設(shè)置按鈕文字顏色赔癌,可傳色值和color resID诞外。
setCallback(Callback callback)
給Snackbar添加一個(gè)顯示和隱藏的監(jiān)聽,分別對(duì)應(yīng)Callback接口里的onShown和onDismissed方法灾票。
show()和dismiss()
顯示和隱藏峡谊。
說了這么多,其實(shí)就是3行代碼:
Snackbar.make(parentLayout, R.string.snackbar_text,Snackbar.LENGTH_LONG) .setAction(R.string.snackbar_action, myOnClickListener) .show();
以上就是Snackbar的使用方法刊苍。感覺好像少了點(diǎn)什么既们?沒錯(cuò),Snackbar只能在底部顯示正什!可是我想把提示做在頂部啥纸,沒辦法只好把Snackbar的源碼拷貝出來,自己動(dòng)手改!不先看效果的文章不是好作者婴氮,上一張效果圖:
??我們需要從源碼中拷貝6個(gè)類:AnimationUtils.java斯棒、BaseTransientBottomBar.java、Snackbar.java主经、SnackbarManager.java荣暮、SnackbarContentLayout.java、ThemeUtils.java罩驻,兩個(gè)布局文件:design_layout_snackbar.xml渠驼、design_layout_snackbar_include.xml。建議把Snackbar.java鉴腻、design_layout_snackbar.xml和design_layout_snackbar_include.xml的名字改了。下面開始修改源碼:
??首先百揭,我們打開BaseTransientBottomBar.java爽哎,里面的animateViewIn()和animateViewOut()就是定義Snackbar彈出動(dòng)畫和彈入動(dòng)畫的方法。在in方法里器一,可以看到定義動(dòng)畫初始Y坐標(biāo)是給了一個(gè)mView.getHeight()的值课锌,我們給改成負(fù)的,即-mView.getHeight()祈秕。移步out方法渺贤,可以看到定義了一個(gè)動(dòng)畫結(jié)束的Y坐標(biāo)是mView.getHeight(),再改成負(fù)的-mView.getHeight()请毛,但是這還不夠志鞍,還需要在方法伊始加上ViewCompat.setTranslationY(mView, 0);這句,定義動(dòng)畫初始Y軸坐標(biāo)為0方仿。
??最后再把design_layout_snackbar.xml里的layout_gravity由bottom改為top固棚,class改為自己拷出來的SnackBarLayout统翩;把design_layout_snackbar_include.xml中的class改為自己拷出來的SnackbarContentLayout。至此此洲,你的Snackbar就變成在頂部的了厂汗。如需頂部底部都支持請(qǐng)自己封裝...因?yàn)槲姨Я恕?br> ??demo地址:http://pan.baidu.com/s/1cvwF7K。