編輯:關於Android編程
1.Toast源碼分析
老規矩,我們先去看Toast的源碼。
Toast有兩種顯示布局方式,一種最常見調用Toast.makeText()
,看源碼是這樣寫的
public static Toast makeText(Context context, CharSequence text, @Duration int duration) { Toast result = new Toast(context); LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null); TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message); tv.setText(text); result.mNextView = v; result.mDuration = duration; return result; }
transient_notification這個布局文件代碼是這樣的
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:background="?android:attr/toastFrameBackground"> <TextView android:id="@android:id/message" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:layout_gravity="center_horizontal" android:textAppearance="@style/TextAppearance.Toast" android:textColor="@color/bright_foreground_dark" android:shadowColor="#BB000000" android:shadowRadius="2.75" /> </LinearLayout>
那麼我們想要修改Toast的文字消息樣式,其實就是修改Toast根布局和message這個TextView。
Toast的另外一種顯示模式就是自定義布局顯示。這個方法不調用Toast.makeText()
方法,而是new一個Toast對象,然後調用setView()
方法。當然自定義布局就不會加載transient_notification
布局了。
2.實現自定義Toast
先給大家看下我封裝的工具類ToastUtil。
import android.content.Context; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; /** * Created by 趙晨璞 on 2016/8/11. */ public class ToastUtil { private Toast toast; private LinearLayout toastView; /** * 修改原布局的Toast */ public ToastUtil() { } /** * 完全自定義布局Toast * @param context * @param view */ public ToastUtil(Context context, View view,int duration){ toast=new Toast(context); toast.setView(view); toast.setDuration(duration); } /** * 向Toast中添加自定義view * @param view * @param postion * @return */ public ToastUtil addView(View view,int postion) { toastView = (LinearLayout) toast.getView(); toastView.addView(view, postion); return this; } /** * 設置Toast字體及背景顏色 * @param messageColor * @param backgroundColor * @return */ public ToastUtil setToastColor(int messageColor, int backgroundColor) { View view = toast.getView(); if(view!=null){ TextView message=((TextView) view.findViewById(android.R.id.message)); message.setBackgroundColor(backgroundColor); message.setTextColor(messageColor); } return this; } /** * 設置Toast字體及背景 * @param messageColor * @param background * @return */ public ToastUtil setToastBackground(int messageColor, int background) { View view = toast.getView(); if(view!=null){ TextView message=((TextView) view.findViewById(android.R.id.message)); message.setBackgroundResource(background); message.setTextColor(messageColor); } return this; } /** * 短時間顯示Toast */ public ToastUtil Short(Context context, CharSequence message){ if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message, Toast.LENGTH_SHORT); toastView=null; }else{ toast.setText(message); toast.setDuration(Toast.LENGTH_SHORT); } return this; } /** * 短時間顯示Toast */ public ToastUtil Short(Context context, int message) { if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message, Toast.LENGTH_SHORT); toastView=null; }else{ toast.setText(message); toast.setDuration(Toast.LENGTH_SHORT); } return this; } /** * 長時間顯示Toast */ public ToastUtil Long(Context context, CharSequence message){ if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message, Toast.LENGTH_LONG); toastView=null; }else{ toast.setText(message); toast.setDuration(Toast.LENGTH_LONG); } return this; } /** * 長時間顯示Toast * * @param context * @param message */ public ToastUtil Long(Context context, int message) { if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message, Toast.LENGTH_LONG); toastView=null; }else{ toast.setText(message); toast.setDuration(Toast.LENGTH_LONG); } return this; } /** * 自定義顯示Toast時間 * * @param context * @param message * @param duration */ public ToastUtil Indefinite(Context context, CharSequence message, int duration) { if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message,duration); toastView=null; }else{ toast.setText(message); toast.setDuration(duration); } return this; } /** * 自定義顯示Toast時間 * * @param context * @param message * @param duration */ public ToastUtil Indefinite(Context context, int message, int duration) { if(toast==null||(toastView!=null&&toastView.getChildCount()>1)){ toast= Toast.makeText(context, message,duration); toastView=null; }else{ toast.setText(message); toast.setDuration(duration); } return this; } /** * 顯示Toast * @return */ public ToastUtil show (){ toast.show(); return this; } /** * 獲取Toast * @return */ public Toast getToast(){ return toast; } }
修改Toast背景色的使用法方法如下:
ToastUtil toastUtil=new ToastUtil(); toastUtil.Short(MainActivity.this,"自定義message字體、背景色").setToastColor(Color.WHITE, getResources().getColor(R.color.colorAccent)).show();
修改Toast背景色
方形的Toast看上去有些呆板,我自定義了一個名為toast_radius.xml的背景,代碼如下:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <!-- 填充的顏色 --> <solid android:color="#ffc107" /> <!-- android:radius 弧形的半徑 --> <corners android:radius="20dip" /> </shape>
然後上面設置背景的代碼改成:
toastUtil.Short(MainActivity.this,"自定義message字體顏色和背景").setToastBackground(Color.WHITE,R.drawable.toast_radius).show();
修改了背景的Toast
雖然官方認為Toast和Snackbar都應該是短文本的形式,不能包含圖標,但是個人感覺加上圖標還是挺好玩的...
向Toast中添加圖標可以這樣:
ImageView toastImage = new ImageView(getApplicationContext()); toastImage.setImageResource(R.mipmap.ic_launcher); toastUtil.Short(MainActivity.this,"向Toast添加了一個ImageView").setToastBackground(Color.WHITE,R.drawable.toast_radius).addView(toastImage,0).show();
添加圖標的Toast
如果你想要Toast顯示自定義的布局,可以這樣:
View view = LayoutInflater.from(MainActivity.this).inflate(R.layout.image,null); new ToastUtil(MainActivity.this,view,Toast.LENGTH_SHORT).show();
自定義布局Toast,我的布局文件中只有一個默認圖標的ImageView
大家都知道,連續觸發Toast的show()
方法的時候,Toast就會排著隊連續展示,感覺上不太友好。所以我先判斷了toast是否沒被創建或者是否被添加了額外的view,如果是的話就重新生成一個toast對象;如果否的話就只修改message文字和顯示時間。
Toast布局修改,不排隊顯示
總結
我這個工具類不是完全體,大家再根據自己項目的具體需求進行修改。以上就是Android中Toast的花式使用的全部內容,感興趣的小伙伴們快快自己動手實踐起來吧。
1. Handler + Thread 異步執行任務在UI線程中開啟子線程,使用Handler 發消息,通知主線程更新UI直接在UI線程中開啟子線程來更新TextView
在Android開發當中,經常需要用到定位功能,尤其是依賴於地理位置功能的應用,很多人喜歡使用百度地圖,高德地圖提供的sdk,開放API,但是在僅僅需要經緯度,或者城市,
我們在安裝某個APP的時候,基本都會有一個引導頁的提示,他們可以打廣告,或者介紹新功能的加入和使用說明等。一般都支持滑動並且下面有幾個點,顯示共有多少頁和當前圖片的位置,
Android 開源項目第一篇——個性化控件(View)篇包括ListView、ActionBar、Menu、ViewPager、Gallery、