安卓自定义Toast,调整Toast位置大小等的方法

本文介绍如何在Android中自定义Toast,包括调整其位置和样式。通过使用`setGravity`方法改变Toast的显示位置,并创建自定义布局文件以修改样式。此外,还解决了连击按钮导致Toast显示时间累加的问题,确保了用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

安卓自带的 Toast 其实还是不错的,但是,不折腾一下怎么能显示出我们的与众不同呢。所以,让我们先看一下默认的 Toast 长什么样。
这里写图片描述
圆角,灰底白字,个人感觉还是不错的,都是一种形势,难免有些单调。
xml 文件如下:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    tools:context="com.ll.fy.ftoast.MainActivity">

    <Button
        android:id="@+id/btn_toast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/btn_text"/>

</LinearLayout>

java 文件如下:

package com.ll.fy.ftoast;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn=(Button)findViewById(R.id.btn_toast);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Toast.makeText(getApplicationContext(),"Hello fengyulang",Toast.LENGTH_LONG).show();
            }
        });
    }
}

OK,开始修改,额,改什么呢,将 Toast 弹出框的位置修改一下,查一下 Android 的 API (https://developer.android.google.cn/reference/android/widget/Toast.html),里面有一个 setGravity 的方法,可以修改 Toast 弹出框的位置,

void    
setGravity(int gravity, int xOffset, int yOffset)
Set the location at which the notification should appear on the screen.

将 MainActivity.java 修改如下

package com.ll.fy.ftoast;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button btn;
    private Toast fylToast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn=(Button)findViewById(R.id.btn_toast);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fylToast=Toast.makeText(getApplicationContext(),"Hello fengyulang",Toast.LENGTH_LONG);
                fylToast.setGravity(Gravity.LEFT,0,0);
                fylToast.show();
            }
        });
    }
}

运行之后,
这里写图片描述
弹出框在左中的位置,将 setGravity(Gravity.LEFT,0,0) 改为 setGravity(Gravity.LEFT,100,100) ,提示框的内容也修改为 “Hello fengyulang 100 100”,继续
这里写图片描述
可见,弹框的内容在 X,Y 轴上都偏移了 100 个像素。

OK,继续修改,这次,不进要调整 Toast 的位置,还要调整 Toast 的样式,一说到样式我们会想到的是啥,layout?Xml?
Yes,这种想法是正常的,也正确的,来给Toast加一个样式 fyl_toast.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="#B0000000"
    android:gravity="center"
    android:paddingTop="8dp"
    android:paddingBottom="8dp"
    android:paddingLeft="25dp"
    android:paddingRight="25dp" >

    <TextView
        android:id="@+id/textToast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="45dp"
        android:textColor="#FFFFFF"/>
</FrameLayout>

然后,新增一个类,FylToast,

package com.ll.fy.ftoast;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by fy on 2017/6/21.
 */

public class FylToast {
    private Toast mToast;
    private FylToast(Context context, CharSequence text, int duration) {
        View v = LayoutInflater.from(context).inflate(R.layout.fyl_toast, null);
        TextView textView = (TextView) v.findViewById(R.id.textToast);
        textView.setText(text);
        mToast = new Toast(context);
        mToast.setDuration(duration);
        mToast.setView(v);
    }

    public static FylToast makeText(Context context, CharSequence text, int duration) {
        return new FylToast(context, text, duration);
    }
    public void show() {
        if (mToast != null) {
            mToast.show();
        }
    }
    public void setGravity(int gravity, int xOffset, int yOffset) {
        if (mToast != null) {
            mToast.setGravity(gravity, xOffset, yOffset);
        }
    }
}

将 MainActivity.java 修改如下:

package com.ll.fy.ftoast;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private Button btn;
    private FylToast fylToast;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn=(Button)findViewById(R.id.btn_toast);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                fylToast=FylToast.makeText(getApplicationContext(),"Hello fengyulang 100 -100",Toast.LENGTH_LONG);
                fylToast.setGravity(Gravity.LEFT,100,-100);
                fylToast.show();
            }
        });
    }
}

再次运行,
这里写图片描述
自此,Toast 的样式也被我们修改完毕,点击一次按钮,Toast 大约显示 3.5s,似乎完美了,但是,当我们连击按钮N次的时候,就有些不完美了,Toast 显示的时间变成了 3.5*Ns。这个提醒时间,有些长啊,即使用户切换到了其他的界面,Toast 还是会显示那么久。
这是 Toast 自带的属性,显示时长会随着点击次数的增加而累加,这逻辑,说起来貌似也没有什么错,但是,用起来有缺陷啊,那就,看样子,得接着改了,防止Toast重复弹出。
将 FylToast.java 修改成以下内容:

package com.ll.fy.ftoast;

import android.content.Context;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by fy on 2017/6/21.
 */

public class FylToast {
    private Toast mToast;
    private static long lastTime=0;
    private int showDuration;
    private static CharSequence lastText;
    private static CharSequence nowText;

    private FylToast(Context context, CharSequence text, int duration) {
        View v = LayoutInflater.from(context).inflate(R.layout.fyl_toast, null);
        TextView textView = (TextView) v.findViewById(R.id.textToast);
        textView.setText(text);
        showDuration=duration;
        if (duration==0){
            showDuration=2000;//这里转换的原因是因为Toast.LENGTH_SHORT实际对应的数字是0
        }
        if (duration==1){
            showDuration=4000;//这里转换的原因是因为Toast.LENGTH_SHORT实际对应的数字是1,如果不转换,后面的时间判断就会出错
        }
        nowText=text;
        mToast = new Toast(context);
        mToast.setDuration(duration);
        mToast.setView(v);
    }

    public static FylToast makeText(Context context, CharSequence text, int duration) {
        return new FylToast(context, text, duration);
    }

    //显示 Toast 之前,判断 Toast 的内容是否与上次一样,不一样就排队在后面展示即可,一样判断上一次的是否已经显示完,未显示完,则本次不显示
    public void show() {
        if (!nowText.equals(lastText) && mToast!=null){
            mToast.show();
            lastTime=System.currentTimeMillis();
            lastText=nowText;
        }else {
            if((System.currentTimeMillis()-lastTime)>showDuration && mToast != null){
                mToast.show();
                lastTime=System.currentTimeMillis();
                lastText=nowText;
            }
        }
    }

    public void setGravity(int gravity, int xOffset, int yOffset) {
        if (mToast != null) {
            mToast.setGravity(gravity, xOffset, yOffset);
        }
    }
}

上面要注意的一个问题为 Toast.LENGTH_SHORT Toast.LENGTH_LONG ,这位置有点儿坑,并不对应的毫秒数,而是分别对应 0,1,然后还有一个比较坑的位置就是虽然 duration 可以设置为其他的参数,但是实际表现出来并没有什么用,比如说设为 5000,实际上 Toast 也就停留了 2s 左右,所以,还是建议 duration 设置为安卓默认的 Toast.LENGTH_SHORT 或 Toast.LENGTH_LONG,不再另外设置值。

源码下载链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值