AutoBackgroundBackButton 在ScrollView上方自动根据返回键按钮下方内容动态改变颜色。自动变色返回键

在日常有时候有一些为了优化体验的需求。AutoBackgroundBackButton 一个可以根据按钮下方背景颜色动态的改版返回键自定义ImageView。这里只展示了黑白切换方式,你如果还有其他需求可以参考颜色校验来自己实现切换对应颜色按钮。【例如白色背景展示黑色样式,图片上方显示白色样式】

返回键效果录屏

返回键录屏

下面展示文件 AutoBackgroundBackButton.kt


import android.content.Context
import android.content.res.ColorStateList
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.BitmapDrawable
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.view.View
import androidx.appcompat.widget.AppCompatImageView
import androidx.core.widget.NestedScrollView
import kotlin.math.absclass AutoBackgroundBackButton @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : AppCompatImageView(context, attrs, defStyleAttr) {private var mScrollView: NestedScrollView? = nullprivate val handler = Handler(Looper.getMainLooper())private val delayMillis = 100L // 延迟截图生成的时间,单位为毫秒private var isScrolling = falsefun setScrollView(scrollView: NestedScrollView) {scrollView.viewTreeObserver.addOnGlobalLayoutListener {mScrollView = scrollViewscrollView.setOnScrollChangeListener(NestedScrollView.OnScrollChangeListener { v, scrollX, scrollY, oldScrollX, oldScrollY ->isScrolling = true // 设置滚动状态为 truehandler.removeCallbacksAndMessages(null) // 移除之前的延迟任务handler.postDelayed({if (isScrolling) {isScrolling = false // 滚动结束,将滚动状态设置为 falseupdateImageResource()}}, delayMillis)})updateImageResource()}}private fun updateImageResource() {val bottomAreaColor = getBottomAreaColor()//方式1:可以直接设置setImageResource来改变//setImageResource(if (isColorDark(bottomAreaColor)) R.drawable.ic_back_white else R.drawable.ic_back_black)//方式2:使用imageTintList属性来直接改版图片颜色val states = arrayOf(intArrayOf())val colors = intArrayOf(if (isColorDark(bottomAreaColor)) Color.WHITE else Color.BLACK)imageTintList = ColorStateList(states, colors)}private fun getBottomAreaColor(): Int {if (mScrollView == null || mScrollView?.width == 0 || mScrollView?.height == 0) {return Color.WHITE} else {val y0 = getLocationOnScreen().secondval y1 = mScrollView!!.getLocationOnScreen().secondval startY = abs(y0 - y1)val bitmap = getScreenshotOfScreenRegion(mScrollView!!,width,startY,startY + height)if (bitmap != null && !bitmap.isRecycled) {if (bitmap.height == 0) {return Color.WHITE} else {val color = getAverageColorFromBitmap(bitmap, 0, 0, bitmap.width, bitmap.height)//测试预览,可以打开注解查看[打开记得注释bitmap.recycle()]
//                    setBackgroundDrawable(BitmapDrawable(resources, bitmap))bitmap.recycle()return color}} else {return Color.WHITE}}}fun View.getLocationOnScreen(): Pair<Int, Int> {val location = IntArray(2)getLocationOnScreen(location)return Pair(location[0], location[1])}private fun getScreenshotOfScreenRegion(scrollView: NestedScrollView,bitmapWidth: Int,startY: Int,endY: Int): Bitmap? {// 获取屏幕的截图val screenBitmap = getScrollViewScreenshot(scrollView, bitmapWidth) ?: return null// 计算在屏幕上的起始位置和结束位置val startYOnScreen = startYval endYOnScreen = endY// 计算在 ScrollView 上的位置val startYOnScrollView = startYOnScreen + scrollView.scrollY// 截取屏幕上的指定区域var regionHeight = endYOnScreen - startYOnScreentry {return Bitmap.createBitmap(screenBitmap,0,startYOnScrollView,bitmapWidth,regionHeight)} catch (ex: Exception) {return null}}private fun getScrollViewScreenshot(scrollView: NestedScrollView, bitmapWidth: Int): Bitmap? {val height = scrollView.getChildAt(0)?.height ?: return null // 获取 ScrollView 内容的高度if (height == 0) return null // 如果 ScrollView 的高度为0,直接返回nullval bitmap = Bitmap.createBitmap(bitmapWidth, height, Bitmap.Config.ARGB_8888)val canvas = Canvas(bitmap)scrollView.draw(canvas)return bitmap}private fun isColorDark(color: Int): Boolean {val darkness =1 - (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255return darkness >= 0.1}private fun getAverageColorFromBitmap(bitmap: Bitmap, startX: Int, startY: Int, width: Int, height: Int): Int {val pixels = IntArray(width * height)bitmap.getPixels(pixels, 0, width, startX, startY, width, height)var red: Long = 0var green: Long = 0var blue: Long = 0var count = 0for (pixel in pixels) {red += Color.red(pixel)green += Color.green(pixel)blue += Color.blue(pixel)count++}if (count == 0) {return Color.WHITE // 默认颜色}red /= countgreen /= countblue /= countreturn Color.rgb(red.toInt(), green.toInt(), blue.toInt())}override fun onDetachedFromWindow() {super.onDetachedFromWindow()handler.removeCallbacksAndMessages(null) // 移除之前的延迟任务}
}

xml中使用

    <com.xxx.weight.AutoBackgroundBackButtonandroid:id="@+id/backButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:padding="10dp"android:src="@drawable/ic_back_black"android:tint="@color/white" />

代码中关联ScrollView

backButton.setScrollView(scrollView)

这样就可以实现返回键和ScrollView的滑动关联,在滑动的时候能自动的根据下方内容而变化颜色。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/5340.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python urllib 爬虫入门(1)

本文主要为Python urllib类库函数和属性介绍及一些简单示例。 目录 urllib爬取网页 简单示例 写入文件 其他读取方法 readline函数 readlines函数 response属性 当前环境信息 返回状态码 返回url地址 对url进行编码与解码 写入文件 总结 urllib爬取网页 通过pyth…

PotatoPie 4.0 实验教程(35) —— FPGA实现摄像头图像二值化膨胀效果

手机扫码 链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 什么是图像二值化膨胀&#xff0c;有什么作用&#xff1f; 图像二值化膨胀是图像处理中的一种基本操作&#xff0c;它用于扩展和增强二值图像中的白色区域。具体而言&#xff0c;二值化膨胀操作…

【论文笔记】Training language models to follow instructions with human feedback A部分

Training language models to follow instructions with human feedback A 部分 回顾一下第一代 GPT-1 &#xff1a; 设计思路是 “海量无标记文本进行无监督预训练少量有标签文本有监督微调” 范式&#xff1b;模型架构是基于 Transformer 的叠加解码器&#xff08;掩码自注意…

LeetCode55:跳跃游戏

题目描述 给你一个非负整数数组 nums &#xff0c;你最初位于数组的 第一个下标 。数组中的每个元素代表你在该位置可以跳跃的最大长度。 判断你是否能够到达最后一个下标&#xff0c;如果可以&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 解题思想 每次…

update_min_vruntime()流程图

linux kernel scheduler cfs的update_min_vruntime() 看起来还挺绕的。含义其实也简单&#xff0c;总一句话&#xff0c;将 cfs_rq->min_vruntime 设置为&#xff1a; max( cfs_rq->vruntime, min(leftmost_se->vruntime, cfs_rq->curr->vruntime) )。 画个流…

滑动窗口详解

目录 一、滑动窗口的特定步骤&#xff1a; 二、题目解析 1、⻓度最⼩的⼦数组---点击跳转题目 3、最⼤连续 1 的个数 III----点击跳转题目 4、将 x 减到 0 的最⼩操作数----点击跳转题目 5、⽔果成篮----点击跳转题目 滑动窗口是双指针算法中细分的一种&#xff0c;它由暴…

PDF高效编辑器,支持修改PDF文档并转换格式从PDF文件转换成图片文件,轻松管理你的文档世界!

PDF文件已成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;传统的PDF阅读器往往只能满足简单的查看需求&#xff0c;对于需要频繁编辑、修改或转换格式的用户来说&#xff0c;就显得力不从心。现在&#xff0c;我们为您带来一款全新的PDF高效编辑器&#xff0c;让…

挑战一周完成Vue3项目Day3: 品牌管理+平台属性管理+SPU管理+SKU管理

一、真实接口替换mock接口 &#xff08;1&#xff09;替换各个环境下的服务器地址&#xff08; .env.development、.env.production、.env.test &#xff09; VITE_SERVE"http://sph-api.atguigu.cn" &#xff08;2&#xff09; 配饰代理跨域&#xff1a;vite.con…

根据标签最大层面ROI提取原始图像区域

今天要实现的任务是提取肿瘤的感兴趣区域。 有两个文件&#xff0c;一个是nii的原始图像文件&#xff0c;一个是nii的标签文件。 我们要实现的是&#xff1a;在标签文件上选出最大层面&#xff0c;然后把最大层面的ROI映射到原始图像区域&#xff0c;在原始图像上提裁剪出ROI…

PLC通过Modbus转Profinet网关连接变频器与电机通讯

Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;是一种能够实现Modbus协议和Profinet协议之间转换的设备。Modbus转Profinet网关可提供单个或多个RS485接口&#xff0c;PLC作为控制中枢&#xff0c;变频器作为控制电机转速&#xff0c;通过Modbus转Profinet网关&#…

瑞米派实时系统与EtherCAT移植-米尔Remi Pi

1.概述 Remi Pi采用瑞萨RZ/G2L作为核心处理器&#xff0c;该处理器搭载双核Cortex-A551.2GHzCortex-M33200MHz处理器&#xff0c;其内部集成高性能3D加速引擎Mail-G31 GPU(500MHz)和视频处理单元&#xff08;支持H.264硬件编解码&#xff09;,16位的DDR4-1600 / DDR3L-1333内存…

Webshell绕过技巧分析之-base64编码和压缩编码

在网络安全运营&#xff0c;护网HVV&#xff0c;重保等活动的过程中&#xff0c;webshell是一个无法绕过的话题。通常出现的webshell都不是以明文的形式出现&#xff0c;而是针对webshell关键的内容进行&#xff0c;混淆&#xff0c;编码来绕过网络安全产品&#xff0c;例如IDS…

计算机提示msvcp110.dll是什么意思?msvcp110.dll丢失恢复办法

在Windows操作系统中&#xff0c;动态链接库&#xff08;DLL&#xff09;扮演着至关重要的角色&#xff0c;它们是实现程序间代码共享和模块化设计的关键组件。msvcp110.dll&#xff0c;作为Microsoft Visual C 2012运行时库的一个组成部分&#xff0c;是理解现代软件开发和维护…

【酱浦菌-爬虫技术细节】解决学术堂爬虫翻页(下一页)问题

首先我们通过css选择器获取页码信息&#xff0c;这里的css选择器&#xff0c;选择的是含有a标签的所有li标签&#xff0c;代码如下&#xff1a; li html_web.css(div.pd_c_xslb_left_fenye ul li>a) for li in li:li_url li.css(a::attr(href)).get()li_num li.css(a::t…

STM32入门_江协科技_3~4_OB记录的自学笔记_软件安装新建工程

3. 软件安装 3.1. 安装Keil5 MDK 作者的资料下载的连接如下&#xff1a;https://jiangxiekeji.com/download.html#32 3.2. 安装器件支持包 因为新的芯片层出不穷&#xff0c;所以需要安装Keil5提供的器件升级版对软件进行升级&#xff0c;从而支持新的芯片&#xff1b;如果不…

unity-C#调用百度千帆AppBuilder的OpenApi

目录 功能描述准备工作百度智能云账号创建应用编辑应用创建Api秘钥Api调用流程unity代码Unitywebrequest非流式流式注意事项 Restsharp 功能描述 使用百度千帆AppBuilder平台,通过api调用的方式实现AI大模型对话功能(文字) 准备工作 百度智能云账号 请自行在百度智能云进行…

力扣---二叉树的右视图

给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1,3,4]示例 2: 输入: [1,null,3] 输出: [1,3]示例 3: 输入: [] 输出: []实现方法&…

nginx+Tomcat动静分离

本⽂的动静分离主要是通过nginxtomcat来实现&#xff0c;其中nginx处理图⽚、html等静态的⽂ 件&#xff0c;tomcat处理jsp、do等动态⽂件. 实验环境 192.168.200.133 nginx反向代理 192.168.200.129 static 192.168.200.130 dynamic 步骤 修改三台主机名 [rootadmin ~]#…

关于Centos 7/8 网络设置 与工具连接

网络三步曲的配置 1、首先更改虚拟机的网络配置 查看子网地址以及网关 如果有要求需要更改IP地址&#xff0c;规定第三位是指定数值&#xff0c;那么需要全部更改 例如&#xff0c;IP地址为192.168.200.30 其中200为重点&#xff0c;更改时为以下步骤 1、点击DHCP设置&#x…

【数据结构】顺序表专题

前言 本篇文章我们来进行有关顺序表的专题训练&#xff0c;让我们一起来看一下有关顺序表的算法题 &#x1f493; 个人主页&#xff1a;小张同学zkf ⏩ 文章专栏&#xff1a;数据结构 &#x1f4dd;若有问题 评论区见 &#x1f389;欢迎大家点赞&#x1f44d;收藏⭐文章 1.移除…