編輯:關於Android編程
Snackbar是Android Support Design Library庫中的一個控件,可以在屏幕底部快速彈出消息,比Toast更加好用。本文對原生Snackbar進行了修改,使其更加靈活。
使用Snackbar要導入com.android.support:design庫。
Snackbar顯示在所有屏幕其它元素之上(屏幕最頂層),同一時間只能顯示一個snackbar。
Snackbar的基本使用很簡單,與Toast類似。
Snackbar.make(view, message_text, duration) .setAction(action_text, click_listener) .show();
make()方法是生成Snackbar的。Snackbar需要一個控件容器view用來容納,官方推薦使用CoordinatorLayout來確保Snackbar和其他組件的交互,比如滑動取消Snackbar、Snackbar出現時FloatingActionButton上移。顯示時間duration有三種類型LENGTH_SHORT、LENGTH_LONG和LENGTH_INDEFINITE。
setAction()方法可設置Snackbar右側按鈕,增加進行交互事件。如果不使用setAction()則只顯示左側message。
Snackbar.make(coordinatorLayout,"這是massage", Snackbar.LENGTH_LONG).setAction("這是action", new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MainActivity.this,"你點擊了action",Toast.LENGTH_SHORT).show(); } }).show();
下面這張圖演示了上面代碼所實現的效果:Snackbar長顯示、點擊Action彈出toast提示以及Snackbar在CoordinatorLayout中滑動取消。
如果你想在Snackbar的顯示時或消失時做些什麼,可以調用Snackbar的setCallback()方法。
Snackbar和Toast的默認樣式都很單一,但是有時我們希望把不同類型信息區別顯示,從而使用戶更容易注意到提示信息。所以使Snackbar變色是一個好主意。
Snackbar的官方API只提供了setActionTextColor()這個方法修改Action的文字顏色,這怎麼辦?查源碼吧,哪裡不會點哪裡。(><)
在源碼中我們看到Snackbar中定義了一個繼承自LinearLayout的內部類SnackbarLayout,Snackbar的樣子就是由這個SnackbarLayout實現的。
SnackbarLayout中加載了R.layout.design_layout_snackbar_include布局文件,打開後看到下面這段代碼(我把padding、margin的具體數值也打了出來):
由命名可知,以snackbar_text為名的TextView就是Snackbar左側的message。
好了,我們開始修改Snackbar的背景顏色和message字體顏色吧。
public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) { View view = snackbar.getView();//獲取Snackbar的view if(view!=null){ view.setBackgroundColor(backgroundColor);//修改view的背景色 ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor);//獲取Snackbar的message控件,修改字體顏色 } }
很簡單,沒有幾行代碼。
本文最後提供的Snackbar封裝類代碼中定義了4種不同類型的信息:Info(妹子向你發來一條消息)、Confirm(妹子已收到你發出的消息)、Warning(妹子刪除了你發出的消息)、Alert(妹子已將你拉黑),分別用藍色、綠色、橙色、紅色來表示。
短文本
通常 Snackbar 的高度應該僅僅用於容納所有的文本,而文本應該與執行的操作相關。Snackbar 中不能包含圖標,操作只能以文本的形式存在。
最多0-1個操作,不包含取消按鈕
當一個動作發生的時候,應當符合提示框和可用性規則。當有2個或者2個以上的操作出現時,應該使用提示框而不是 Snackbar,即使其中的一個是取消操作。如果 Snackbar 中提示的操作重要到需要打斷屏幕上正在進行的操作,那麼理當使用提示框而非 Snackbar。
上面這段是谷歌Material Design設計規范中的話。
但是我就是想在Snackbar中加圖標增加趣味性,引起用戶注意怎麼辦?我就是想在Snackbar中放兩個按鈕進行可選非必要操作怎麼辦?我就是想整幺蛾子。︿( ̄︶ ̄)︿
設計規范中的說法是有道理的,因為官方認為“Snackbar是一種針對操作的輕量級反饋機制”,做的麻煩了影響視覺感受。但是對於上述任性的開發者(或者是接了奇葩需求的苦逼開發者)我們也有解決方法。
前面我們提到過Snackbar的view是由SnackbarLayout實現的,而SnackbarLayout是繼承自LinearLayout,那麼我們新建一個布局添加進去不就行了麼。(~o ̄ ̄)~o...
public static void SnackbarAddView(Snackbar snackbar,int layoutId,int index) { View snackbarview = snackbar.getView();//獲取snackbar的View(其實就是SnackbarLayout) Snackbar.SnackbarLayout snackbarLayout=(Snackbar.SnackbarLayout)snackbarview;//將獲取的View轉換成SnackbarLayout View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId,null);//加載布局文件新建View LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT);//設置新建布局參數 p.gravity= Gravity.CENTER_VERTICAL;//設置新建布局在Snackbar內垂直居中顯示 snackbarLayout.addView(add_view,index,p);//將新建布局添加進snackbarLayout相應位置 }
上面的代碼中,如果我們不設置向Snackbar中添加的布局文件的布局參數,新布局會顯示在Snackbar內的頂部。使用上述任性方法的時候要注意新加布局的大小和Snackbar內文字長度,Snackbar過大或過於花哨了可不好看。
下面是使用示例。我們先新建一個布局,暫時命名為snackbar_addview.xml,簡單的放進了一個ImageView,圖片就是android默認圖標。
然後在activity中寫下snackbar的設置:
Snackbar snackbar= Snackbar.make(coordinatorLayout,"這是massage", Snackbar.LENGTH_LONG); SnackbarUtil.setSnackbarColor(snackbar,SnackbarUtil.blue); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview,0); snackbar.show();
我將我常用的Snackbar相關設置封裝成了一個類,大家可以根據自己的需求使用。
/** * Created by 趙晨璞 on 2016/5/1. */ public class SnackbarUtil { public static final int Info = 1; public static final int Confirm = 2; public static final int Warning = 3; public static final int Alert = 4; public static int red = 0xfff44336; public static int green = 0xff4caf50; public static int blue = 0xff2195f3; public static int orange = 0xffffc107; /** * 短顯示Snackbar,自定義顏色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */ public static Snackbar ShortSnackbar(View view, String message, int messageColor, int backgroundColor){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_SHORT); setSnackbarColor(snackbar,messageColor,backgroundColor); return snackbar; } /** * 長顯示Snackbar,自定義顏色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */ public static Snackbar LongSnackbar(View view, String message, int messageColor, int backgroundColor){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_LONG); setSnackbarColor(snackbar,messageColor,backgroundColor); return snackbar; } /** * 自定義時常顯示Snackbar,自定義顏色 * @param view * @param message * @param messageColor * @param backgroundColor * @return */ public static Snackbar IndefiniteSnackbar(View view, String message,int duration,int messageColor, int backgroundColor){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_INDEFINITE).setDuration(duration); setSnackbarColor(snackbar,messageColor,backgroundColor); return snackbar; } /** * 短顯示Snackbar,可選預設類型 * @param view * @param message * @param type * @return */ public static Snackbar ShortSnackbar(View view, String message, int type){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_SHORT); switchType(snackbar,type); return snackbar; } /** * 長顯示Snackbar,可選預設類型 * @param view * @param message * @param type * @return */ public static Snackbar LongSnackbar(View view, String message,int type){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_LONG); switchType(snackbar,type); return snackbar; } /** * 自定義時常顯示Snackbar,可選預設類型 * @param view * @param message * @param type * @return */ public static Snackbar IndefiniteSnackbar(View view, String message,int duration,int type){ Snackbar snackbar = Snackbar.make(view,message, Snackbar.LENGTH_INDEFINITE).setDuration(duration); switchType(snackbar,type); return snackbar; } //選擇預設類型 private static void switchType(Snackbar snackbar,int type){ switch (type){ case Info: setSnackbarColor(snackbar,blue); break; case Confirm: setSnackbarColor(snackbar,green); break; case Warning: setSnackbarColor(snackbar,orange); break; case Alert: setSnackbarColor(snackbar,Color.YELLOW,red); break; } } /** * 設置Snackbar背景顏色 * @param snackbar * @param backgroundColor */ public static void setSnackbarColor(Snackbar snackbar, int backgroundColor) { View view = snackbar.getView(); if(view!=null){ view.setBackgroundColor(backgroundColor); } } /** * 設置Snackbar文字和背景顏色 * @param snackbar * @param messageColor * @param backgroundColor */ public static void setSnackbarColor(Snackbar snackbar, int messageColor, int backgroundColor) { View view = snackbar.getView(); if(view!=null){ view.setBackgroundColor(backgroundColor); ((TextView) view.findViewById(R.id.snackbar_text)).setTextColor(messageColor); } } /** * 向Snackbar中添加view * @param snackbar * @param layoutId * @param index 新加布局在Snackbar中的位置 */ public static void SnackbarAddView( Snackbar snackbar,int layoutId,int index) { View snackbarview = snackbar.getView(); Snackbar.SnackbarLayout snackbarLayout=(Snackbar.SnackbarLayout)snackbarview; View add_view = LayoutInflater.from(snackbarview.getContext()).inflate(layoutId,null); LinearLayout.LayoutParams p = new LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT,LinearLayout.LayoutParams.WRAP_CONTENT); p.gravity= Gravity.CENTER_VERTICAL; snackbarLayout.addView(add_view,index,p); } }
簡單的使用示例:
SnackbarUtil.ShortSnackbar(coordinator,"妹子向你發來一條消息",SnackbarUtil.Info).show();
整出幺蛾子的使用示例:
Snackbar snackbar= SnackbarUtil.ShortSnackbar(coordinator,"妹子刪了你發出的消息",SnackbarUtil.Warning).setActionTextColor(Color.RED).setAction("再次發送", new View.OnClickListener() { @Override public void onClick(View v) { SnackbarUtil.LongSnackbar(coordinator,"妹子已將你拉黑",SnackbarUtil.Alert).setActionTextColor(Color.WHITE).show(); } }); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview,0); SnackbarUtil.SnackbarAddView(snackbar,R.layout.snackbar_addview2,2); snackbar.show();
這個示例中調用了兩次SnackbarAddView()方法向Snackbar中添加了兩個不同的自定義布局,效果如下(不建議大家這麼玩 _(:з」∠)_ ):
暫時就是這些。[]~( ̄ ̄)~*
如何能讓我們的應用能夠在系統後台持續地運行是一個自Android從娘(ma)胎(bi)裡出來時就議論不停的話題,而且這似乎成了一個牛(liu)逼(mang)應用標配的功能
Activity最為android開發者最熟悉的組件,由ActivityManagerService服務進行調度管理,本文基於其對Activity的啟動過程進行分析,同時
android矢量動畫!直接來個例子就明白了!(這裡我把與動畫無關的屬性都用…表示)首先你要有個矢量圖比如這個矢量圖xml文件叫”vector1
FloatingActionButton項目在github上的主頁:https://github.com/futuresimple/android-floating-ac