在安卓應用中Toast的使用頻率是非常高的徽职,關于Toast的基本使用這里就不再啰嗦,這里只說一下怎么去更改Toast的顯示風格佩厚,讓Toast不再是千年不變的黑框框姆钉。
先上效果圖:
1 方式1 :使用Toast類的setView( )
在Toast類中,有一個 setView( view ) 方法抄瓦,該方法的作用就是用傳入的view替換默認的那個黑框框潮瓶。
使用setView( ) 方法自定義Toast時大致步驟如下:
- 通過Toast 的構造方法創(chuàng)建一個toast對象
- 使用LayoutInflater 填充一個view
- 將填充起來的view通過setView( ) 設置給toast對象
- 調(diào)用show( ) 展示吐司。
具體實現(xiàn)代碼:
ImageToastActivity.java
/**
* 作者:CnPeng
* <p>
* 時間:2017/2/27:上午10:50
* <p>
* 說明:展示帶有圖片的Toast钙姊,自定義吐司布局時毯辅,主要依靠setView 方法
* <p>
* 關于 負的margin值的注意事項 查看 activity_imagetoast22222222222.xml
*/
public class ImageToastActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imagetoast);
Button button = (Button) findViewById(R.id.bt_imageToast);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_imageToast:
//自定義Toast 方式1 ,直接setView
//填充view煞额,官方guide說根布局必須設置id為custom_toast_container思恐,且inflate的第二個參數(shù)必須按照這個模式寫沾谜,實際測試無所謂
// View toastView = getLayoutInflater().inflate(R.layout.imagetoast, (ViewGroup)findViewById(R.id
// .custom_toast_container));
// 填充view
View toastView = getLayoutInflater().inflate(R.layout.imagetoast, null);
Toast toast = new Toast(getApplicationContext()); //構造方法創(chuàng)建吐司對象
toast.setDuration(Toast.LENGTH_SHORT); //設置吐司時長
//toast.setGravity(Gravity.BOTTOM | Gravity.RIGHT, 100, 300); //更改吐司的展示位置(默認的位置就挺好)
toast.setView(toastView); //設置吐司的新view
toast.show(); //展示吐司
break;
}
}
}
activity的布局文件中只有一個button,代碼省略胀莹。
布局文件:imagetoast.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/custom_toast_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<!--風格2 吐司左上角展示圖標-->
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_marginLeft="28dp"
android:layout_marginTop="50dp"
android:background="@drawable/shape_bk_imagetoast"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:text="這是一個帶有圖片的Toast提示框"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
shape_imagetoast.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<corners android:radius="10dp"/>
<solid android:color="#ffdd00"/>
<stroke android:color="@color/colorAccent" android:width="@dimen/dp1"/>
</shape>
注意:
- setView(view)方法中傳入的view可以任意定義基跑,但需要注意的是,有些控制view位置的屬性可能會不生效描焰。比如負的margin值媳否,具體效果將列舉在文章末尾。
- 官方guide說根布局view必須設置id為custom_toast_container荆秦,且inflate的第二個參數(shù)必須按照這個模式寫篱竭,實際測試無所謂
View toastView =getLayoutInflater().inflate(R.layout.imagetoast, (ViewGroup)findViewById(R.id.custom_toast_container));
2 方式2 :通過java代碼直接修改原生布局
如果要展示的Toast 只是在上方(或者下方、左方步绸、右方)添加一個圖片或者更改字號字體背景色等內(nèi)容掺逼,可以直接在java代碼中獲取原生的布局view并去修改它。
大致步驟如下:
- 通過Toast 中的靜態(tài)方法 makeText( ) 創(chuàng)建一個Toast 對象瓤介。
- 通過調(diào)用toast對象的 getView( ) 方法獲取 toast展示的view
- 在java代碼中修改Toast的顯示風格
- 調(diào)用show( ) 展示Toast
效果圖:
具體實現(xiàn)代碼:
ImageToastActivity.java
/**
* 作者:CnPeng
* <p>
* 時間:2017/2/27:上午10:50
* <p>
* 說明:展示帶有圖片的Toast吕喘,自定義吐司布局時,主要依靠setView 方法
* <p>
* 關于 負的margin值的注意事項 查看 activity_imagetoast22222222222.xml
*/
public class ImageToastActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_imagetoast);
Button button = (Button) findViewById(R.id.bt_imageToast);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_imageToast:
//自定義Toast方式2 : 直接修改原生的toast布局(效果同setView時惑朦,view只是一個TextView的情況)
Toast toast = Toast.makeText(ImageToastActivity.this, "直接改寫原生的Toast布局", Toast.LENGTH_SHORT);
View toastView = toast.getView();
toastView.setBackgroundResource(R.drawable.shape_bk_imagetoast);
toastView.setPadding(20, 5, 20, 5);
TextView tv = (TextView) toastView.findViewById(android.R.id.message);
tv.setTextSize(16);
tv.setTextColor(Color.BLUE);
tv.setGravity(Gravity.CENTER);
tv.setCompoundDrawablesWithIntrinsicBounds(R.mipmap.ic_launcher, 0, 0, 0);
tv.setCompoundDrawablePadding(20);
toast.show();
break;
}
}
}
activity的布局文件中只有Button,代碼省略兽泄。
注意:
- toast.getView( ) 可以獲取toast展示的布局view
- textView 中的drawableLeft 等drawableXXX屬性對應的java中的方法是:setCompoundDrawablesWithIntrinsicBounds(leftDrawable , topDrawable, rightDrawable, bottomDrawable); 該方法中傳入的四個參數(shù)分別對應 drawableLeft , drawableRight, drawableTop , drawableBottom 漾月。如果在某個方向上不需要設置圖片就直接傳入0病梢。
- 通過查看toast的 makeText( ) 方法的源碼可以知道,默認的布局文件是:com.android.internal.R.layout.transient_notification梁肿,該文件中textView的id是 android:id="@android:id/message"
3 未生效的一個布局文件 :
在這個布局文件中蜓陌,使用了相對布局,先添加了一個TextView ,然后通過 layout_above 再添加一個ImageView吩蔑,之后再通過負的margin值控制 imageView 與TextView的相對位置钮热,并通過 layout_alignLeft 讓圖片的左邊框與textView的左邊框對齊。然而烛芬,這種方式在布局預覽中看著是正常的隧期,but,運行之后確實不好使赘娄,卻展示成下圖中的模式仆潮,沒想明白為啥。如果你知道了請一定要告訴我遣臼。性置。。
詳細布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/custom_toast_container"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!--這種在預覽的時候沒問題揍堰,但實際上并不好使E羟场P嵋濉!-->
<TextView
android:id="@+id/tv_imagetoast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/shape_bk_imagetoast"
android:paddingBottom="10dp"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:paddingTop="10dp"
android:text="這是一個帶有圖片的Toast提示框"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/tv_imagetoast"
android:layout_alignLeft="@id/tv_imagetoast"
android:layout_marginBottom="-15dp"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
4 關于負的margin值 :
關于負的margin 的詳細介紹隐砸,請參考我之前在CSDN中寫的文章之碗,http://blog.csdn.net/north1989/article/details/52922564
(我的CSDN已經(jīng)暫停更新,以后有新內(nèi)容會一直在簡書更新)
這里只是說明一點:如果負的margin值是相對于Button的凰萨,那么button依舊會覆蓋該控件<炭亍P倒荨E志臁!如下圖:
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/bt_imageToast"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:text="點擊展示帶有圖片的Toast"/>
<!--相對于Button使用負的margin值時霹崎,位置雖然發(fā)生了變化珊搀,但是button 自帶的灰色背景會覆蓋控件-->
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/bt_imageToast"
android:layout_alignLeft="@id/bt_imageToast"
android:layout_marginBottom="-20dp"
android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
以上的代碼均為測試過的完整的可用的代碼。也可以直接到github下載代碼:
https://github.com/CnPeng/CrazyAndroid , 其中的a_36 對應該文章