当前位置: 首页 > news >正文

android 支持自定义布局、线程安全、避免内存泄漏的 Toast 工具类

支持自定义布局:可以灵活地显示自定义样式的 Toast。

线程安全:确保在主线程中显示 Toast,避免崩溃。

避免内存泄漏:使用 ApplicationContext 和取消机制,防止内存泄漏问题。

工具类:作为一个通用的工具类,方便在项目中复用。

ToastUtil

import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;public class ToastUtil {private static Toast toast; // 全局Toast对象,避免重复创建private static final int DEFAULT_GRAVITY = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL; // 默认显示位置private static final int DEFAULT_Y_OFFSET = 100; // 默认Y轴偏移量private static final Handler mainHandler = new Handler(Looper.getMainLooper()); // 主线程Handler/*** 显示短时间的Toast** @param context 上下文* @param message 要显示的消息*/public static void showShort(Context context, String message) {showToast(context, message, Toast.LENGTH_SHORT, DEFAULT_GRAVITY, 0, DEFAULT_Y_OFFSET);}/*** 显示长时间的Toast** @param context 上下文* @param message 要显示的消息*/public static void showLong(Context context, String message) {showToast(context, message, Toast.LENGTH_LONG, DEFAULT_GRAVITY, 0, DEFAULT_Y_OFFSET);}/*** 显示短时间的Toast(使用字符串资源ID)** @param context 上下文* @param resId   字符串资源ID*/public static void showShort(Context context, int resId) {showShort(context, context.getString(resId));}/*** 显示长时间的Toast(使用字符串资源ID)** @param context 上下文* @param resId   字符串资源ID*/public static void showLong(Context context, int resId) {showLong(context, context.getString(resId));}/*** 显示自定义位置的Toast** @param context  上下文* @param message  要显示的消息* @param gravity  显示位置(例如 Gravity.TOP)* @param xOffset  X轴偏移量* @param yOffset  Y轴偏移量*/public static void showAtPosition(Context context, String message, int gravity, int xOffset, int yOffset) {showToast(context, message, Toast.LENGTH_SHORT, gravity, xOffset, yOffset);}/*** 显示自定义布局的Toast** @param context     上下文* @param layoutResId 自定义布局资源ID* @param message     要显示的消息*/public static void showCustom(Context context, int layoutResId, String message) {runOnUiThread(() -> {if (toast != null) {toast.cancel(); // 取消之前的Toast}// 使用ApplicationContext,避免内存泄漏Context appContext = context.getApplicationContext();LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);View layout = inflater.inflate(layoutResId, null);// 查找布局中的TextView(假设id为text)TextView textView = layout.findViewById(R.id.text);if (textView != null) {textView.setText(message);}toast = new Toast(appContext);toast.setDuration(Toast.LENGTH_SHORT);toast.setView(layout);toast.show();});}/*** 显示自定义布局的Toast(支持自定义显示时长)** @param context     上下文* @param layoutResId 自定义布局资源ID* @param message     要显示的消息* @param duration    显示时长(Toast.LENGTH_SHORT 或 Toast.LENGTH_LONG)*/public static void showCustom(Context context, int layoutResId, String message, int duration) {runOnUiThread(() -> {if (toast != null) {toast.cancel(); // 取消之前的Toast}// 使用ApplicationContext,避免内存泄漏Context appContext = context.getApplicationContext();LayoutInflater inflater = (LayoutInflater) appContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);View layout = inflater.inflate(layoutResId, null);// 查找布局中的TextView(假设id为text)TextView textView = layout.findViewById(R.id.text);if (textView != null) {textView.setText(message);}toast = new Toast(appContext);toast.setDuration(duration);toast.setView(layout);toast.show();});}/*** 核心方法:显示Toast** @param context  上下文* @param message  要显示的消息* @param duration 显示时长(Toast.LENGTH_SHORT 或 Toast.LENGTH_LONG)* @param gravity  显示位置* @param xOffset  X轴偏移量* @param yOffset  Y轴偏移量*/private static void showToast(Context context, String message, int duration, int gravity, int xOffset, int yOffset) {runOnUiThread(() -> {if (toast != null) {toast.cancel(); // 取消之前的Toast}// 使用ApplicationContext,避免内存泄漏Context appContext = context.getApplicationContext();toast = Toast.makeText(appContext, message, duration);toast.setGravity(gravity, xOffset, yOffset); // 设置显示位置toast.show();});}/*** 取消Toast*/public static void cancelToast() {if (toast != null) {toast.cancel();toast = null; // 释放引用}}/*** 确保在主线程中运行** @param runnable 需要执行的任务*/private static void runOnUiThread(Runnable runnable) {if (Looper.myLooper() == Looper.getMainLooper()) {runnable.run(); // 当前是主线程,直接运行} else {mainHandler.post(runnable); // 当前是子线程,切换到主线程运行}}
}

使用示例

  1. 显示自定义布局的 Toast
ToastUtil.showCustom(MainActivity.this, R.layout.custom_toast, "这是一个自定义Toast");

在子线程中调用:

new Thread(() -> {// 在子线程中调用ToastUtil.showCustom(MainActivity.this, R.layout.custom_toast, "子线程中的自定义Toast");
}).start();

自定义布局示例:
假设 res/layout/custom_toast.xml 是一个自定义布局文件,例如:

<!-- res/layout/custom_toast.xml -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="wrap_content"android:layout_height="wrap_content"android:background="@drawable/toast_background"android:padding="16dp"android:orientation="horizontal"><ImageViewandroid:id="@+id/icon"android:layout_width="24dp"android:layout_height="24dp"android:src="@drawable/ic_toast_icon"android:layout_marginEnd="8dp"/><TextViewandroid:id="@+id/text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@android:color/white"android:textSize="16sp"/>
</LinearLayout>

相关文章:

android 支持自定义布局、线程安全、避免内存泄漏的 Toast 工具类

支持自定义布局&#xff1a;可以灵活地显示自定义样式的 Toast。 线程安全&#xff1a;确保在主线程中显示 Toast&#xff0c;避免崩溃。 避免内存泄漏&#xff1a;使用 ApplicationContext 和取消机制&#xff0c;防止内存泄漏问题。 工具类&#xff1a;作为一个通用的工具…...

景联文科技:以精准数据标注赋能AI进化,构筑智能时代数据基石

在人工智能技术席卷全球的浪潮中&#xff0c;高质量数据已成为驱动AI模型进化的核心燃料。作为全球领先的AI数据服务解决方案提供商&#xff0c;景联文科技深耕数据标注领域多年&#xff0c;以技术为基、以专业为本&#xff0c;致力于为全球客户提供全场景、高精度、多模态的数…...

Mysql的卸载安装配置以及简单使用

MySQL其它问题已经更新在&#xff1a;MySQL完善配置---可视化-CSDN博客 一、卸载 ①控制面板卸载 ②C盘隐藏项目>ProgramData>mysql相关文件夹&#xff0c;还有Program file下的MySQL文件夹 ③开始菜单栏搜索>服务&#xff0c;找到MySQL相关服务删除&#xff0c;如果再…...

使用 ResponseBodyEmitter 实现异步响应式数据流处理

1. 概述 1.1 什么是 ResponseBodyEmitter ResponseBodyEmitter 是 Spring MVC 提供的一个接口,用于支持异步返回响应数据流。它允许在控制器方法中逐步发送数据给客户端,而无需一次性生成完整的响应。 1.2 使用场景 实时数据推送(如股票行情、聊天消息等)。大量数据分批…...

Uniapp项目运行到微信小程序、H5、APP等多个平台教程

摘要&#xff1a;Uniapp作为一款基于Vue.js的跨平台开发框架&#xff0c;支持“一次开发&#xff0c;多端部署”。本文将手把手教你如何将Uniapp项目运行到微信小程序、H5、APP等多个平台&#xff0c;并解析常见问题。 一、环境准备 在开始前&#xff0c;请确保已安装以下工具…...

Ubuntu 下 nginx-1.24.0 源码分析 - cycle->modules[i]->type

Nginx 中主要有以下几种模块类型 类型 含义 NGX_CORE_MODULE 核心模块&#xff08;如进程管理、错误日志、配置解析&#xff09;。 NGX_EVENT_MODULE 事件模块&#xff08;如 epoll、kqueue 等 IO 多路复用机制的实现&#xff09;。 NGX_HTTP_MODULE HTTP 模块&#xf…...

基于SpringBoot的“文物管理系统”的设计与实现(源码+数据库+文档+PPT)

基于SpringBoot的“文物管理系统”的设计与实现&#xff08;源码数据库文档PPT) 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 系统总体功能模块图 E-R实体图 系统首页界面 系统…...

dify + ollama + deepseek-r1+ stable-diffusion 构建绘画智能体

故事背景 stable-diffusion 集成进 dify 后&#xff0c;我们搭建一个小智能体&#xff0c;验证下文生图功能 业务流程 #mermaid-svg-6nSwwp69eMizP6bt {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6nSwwp69eMiz…...

Android原生gif动图加载AnimatedImageDrawable

Android原生gif动图加载AnimatedImageDrawable 从Android P&#xff08;9.0&#xff09;开始&#xff0c;Android系统支持gif动图的原生控件AnimatedImageDrawable&#xff0c;可以播放加载gif动图。 AnimatedImageDrawable官方文档链接&#xff1a; https://developer.andro…...

Windows 系统 Docker Desktop 入门教程:从零开始掌握容器化技术

文章目录 前言一、Docker 简介二、Docker Desktop 安装2.1 系统要求2.2 安装步骤 三、Docker 基本概念四、Docker 常用命令五、实战&#xff1a;运行你的第一个容器5.1 拉取并运行 Nginx 容器5.2 查看容器日志5.3 停止并删除容器 六、总结 前言 随着云计算和微服务架构的普及&…...

记录小白使用 Cursor 开发第一个微信小程序(二):创建项目、编译、预览、发布(250308)

文章目录 记录小白使用 Cursor 开发第一个微信小程序&#xff08;二&#xff09;&#xff1a;创建项目、编译、预览、发布&#xff08;250308&#xff09;一、创建项目1.1 生成提示词1.2 生成代码 二、编译预览2.1 导入项目2.2 编译预览 三、发布3.1 在微信开发者工具进行上传3…...

实战 - 使用 AutoAWQ 进行量化

文章目录 一、准备1、安装 autoawq2、模型准备 二、量化config.json 文件变化 三、加载量化后模型量化后的输出原始输出对比 四、查看模型的精度1、查看模型卡2、查看 config.json 中的 torch_dtype3、打印模型信息4、model.dtype 未必是模型精度 一、准备 1、安装 autoawq p…...

C++20 格式化库:强大的字符串格式化工具

文章目录 格式化语法常见用法1. 填充和对齐2. 数值格式化3. 进制格式化4. 自定义类型 示例代码注意事项 C20 的格式化库是一个强大的工具&#xff0c;用于处理字符串的格式化操作。它提供了类似于 Python 中 str.format() 的功能&#xff0c;但语法和用法更符合 C 的风格。以下…...

【一文学会 HTML5】

目录 HTML概述基本概念HTML 发展历程HTML 基本结构 网页基本标签标题标签&#xff08;<h1> - <h6>&#xff09;段落标签&#xff08;<p>&#xff09;换行标签&#xff08;<br>&#xff09;水平线标签&#xff08;<hr>&#xff09;注释&#xff0…...

如何在WPS中接入DeepSeek并使用OfficeAI助手(超细!成功版本)

目录 第一步&#xff1a;下载并安装OfficeAI助手 第二步&#xff1a;申请API Key 第三步:两种方式导入WPS 第一种:本地大模型Ollama 第二种APIKey接入 第四步&#xff1a;探索OfficeAI的创作功能 工作进展汇报 PPT大纲设计 第五步&#xff1a;我的使用体验(体验建议) …...

蓝耘智算 + 通义万相 2.1:为 AIGC 装上 “智能翅膀”,翱翔创作新天空

1. 引言&#xff1a;AIGC 的崛起与挑战 在过去几年中&#xff0c;人工智能生成内容&#xff08;AIGC&#xff09;技术突飞猛进。AIGC 涉及了文本生成、图像创作、音乐创作、视频制作等多个领域&#xff0c;并逐渐渗透到日常生活的方方面面。传统的内容创作方式已经被许多人类创…...

电脑如何在系统默认的壁纸中切换自己喜欢的

1、声明&#xff1a;该切换壁纸仅支持win10。 当你想去切换系统默认的壁纸&#xff0c;但是不知道该怎么切换&#xff0c;别慌&#xff0c;小亦教你几招帮你快速切换自定义壁纸。 我们平常使用的win10桌面壁纸大部分都是 简单、朴素的壁纸&#xff0c;但如果你想要切换自己喜…...

【大模型安全】安全解决方案

【大模型安全】安全解决方案 1.技术层面2.数据层面数据收集阶段训练阶段模型推理阶段 1.技术层面 在使用大语言模型时&#xff0c;通常有几种选择&#xff1a;一种是采用封装好的大语言模型SaaS云服务&#xff1b;另一种是在公有云上部署自有的大语言模型&#xff0c;并通过权…...

Windows编译环境搭建(MSYS2\MinGW\cmake)

我的音视频/流媒体开源项目(github) 一、基础环境搭建 1.1 MSYS2\MinGW 参考&#xff1a;1. 基于MSYS2的Mingw-w64 GCC搭建Windows下C开发环境_msys2使用mingw64编译 在Widndows系统上&#xff0c;使用gcc工具链&#xff08;g&#xff09;进行C程序开发&#xff1f;可以的&a…...

云曦春季开学考复现(2025)

Crypto 划水的dp和dq 下载附件后是简单的RSA算法题&#xff0c;之所以说简单是因为给了公钥e 趁热打铁&#xff0c;昨天刚学的RSA&#xff0c;既然有p有q&#xff0c;也有e&#xff0c;而np*q&#xff0c;可以算出欧拉函数值phi&#xff08;p-1&#xff09;*&#xff08;q-1&…...

MFC内存泄露

1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

HBuilderX安装(uni-app和小程序开发)

下载HBuilderX 访问官方网站&#xff1a;https://www.dcloud.io/hbuilderx.html 根据您的操作系统选择合适版本&#xff1a; Windows版&#xff08;推荐下载标准版&#xff09; Windows系统安装步骤 运行安装程序&#xff1a; 双击下载的.exe安装文件 如果出现安全提示&…...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信

文章目录 Linux C语言网络编程详细入门教程&#xff1a;如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket&#xff08;服务端和客户端都要&#xff09;2. 绑定本地地址和端口&#x…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题

【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要&#xff1a; 近期&#xff0c;在使用较新版本的OpenSSH客户端连接老旧SSH服务器时&#xff0c;会遇到 "no matching key exchange method found"​, "n…...

vulnyx Blogger writeup

信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面&#xff0c;gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress&#xff0c;说明目标所使用的cms是wordpress&#xff0c;访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

C# 表达式和运算符(求值顺序)

求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如&#xff0c;已知表达式3*52&#xff0c;依照子表达式的求值顺序&#xff0c;有两种可能的结果&#xff0c;如图9-3所示。 如果乘法先执行&#xff0c;结果是17。如果5…...