ViewOverlay-加蒙层真的一种实现方式

这篇具有很好参考价值的文章主要介绍了ViewOverlay-加蒙层真的一种实现方式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、ViewOverlay能实现什么?

    在Android中,ViewOverlay是一个特殊的视图层,可以在一个视图的上方添加和管理附加的视图层,而不会干扰原始视图的布局和交互。它提供了一种方便的方式来在运行时添加、移除或修改视图层,而无需修改原始布局。

二、基础用法

2.1 一个简单案例

比如我们想给一张图片加一张蒙层效果,蒙层颜色是#cc000000,那可以这样很简单的实现:

val imageView = ...
val colorDrawable = ColorDrawable(Color.parseColor("#cc000000"))
button.setOnClickListener {
    // 完全盖住ImageView
    // !!对于Drawable对象来说,必须调用setBounds()方法指定其宽高,否则不展示
    colorDrawable.setBounds(0, 0, imageView.measuredWidth, imageView.measuredHeight)
    imageView.overlay.add(colorDrawable)
}

原始图片效果:
ViewOverlay-加蒙层真的一种实现方式
添加蒙层效果:
ViewOverlay-加蒙层真的一种实现方式
移除蒙层效果:

imageView.overlay.remove(colorDrawable)
2.2 overlay.add(drawable)/groupOverlay.add(view)之后,不显示问题解决
2.2.1 add(Drawable)方法

    如果直接将Drawable对象添加到imageView.overlay.add()没有setBounds则会因为Drawable没有宽高而无法展示,宽高可能为0,需要主动调用setBounds指定drawable的宽高。

2.2.1 add(View)方法

    而对于add(View)来说(需要通过ViewGroup类型的容器对象getOverlay()),就需要给需要添加的view通过setLayoutParams的方式指定宽高才能展示。

注意View和ViewGroup的getOverlay方法实现的差异,是和ViewGroup有addView()而View没有是一样的道理。

  • ViewGroup->getOverlay()返回ViewGroupOverlay类型对象,能添加view的浮层,也能添加drawable
   @Override
    public ViewGroupOverlay getOverlay() {
        if (mOverlay == null) {
            mOverlay = new ViewGroupOverlay(mContext, this);
        }
        return (ViewGroupOverlay) mOverlay;
    }
  • View->getOverlay()返回ViewOverlay类型对象,无法addView(),只能添加drawable对象
    public ViewOverlay getOverlay() {
        if (mOverlay == null) {
            mOverlay = new ViewOverlay(mContext, this);
        }
        return mOverlay;
    }

    特别的如果添加TextView,因为不同字体、大小都会导致宽高不同,所以预先无法知道,这时候就需要StaticLayout.getDesiredWidth()方法获取文本需要的宽高,然后设置给TextView。
ViewOverlay-加蒙层真的一种实现方式
测试代码:
布局文件:activity_overlay:

<?xml version="1.0" encoding="utf-8"?>
<layout 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">

    <data class="ActivityOverlayBinding">

        <variable
            name="viewModel"
            type="com.yanggui.animatordemo.drawable.MyViewModel" />
    </data>

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context=".drawable.OverlayActivity">

        <Button
            android:id="@+id/button_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:text="overlay测试-添加" />

        <Button
            android:id="@+id/button_remove"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="60dp"
            android:text="overlay测试-移除" />


        <include
            android:id="@+id/layout_sub"
            layout="@layout/layout_sub_module"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

    </FrameLayout>
</layout>

布局文件:layout_sub_module

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data class="LayoutSubModuleBinding">

        <variable
            name="viewModel"
            type="com.yanggui.animatordemo.drawable.MyViewModel" />
    </data>

    <LinearLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="bottom"
        android:orientation="vertical">

        <androidx.appcompat.widget.AppCompatImageView
            android:id="@+id/image_view"
            android:layout_width="wrap_content"
            android:layout_height="600dp"
            android:scaleType="centerCrop"
            android:src="@{viewModel.imageDrawable}" />
    </LinearLayout>
</layout>
  • 从id为container的LinearLayout中添加文字TextView:
// 主布局
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_overlay)
// include进来的布局,只为测试在databinding中使用include加载子布
// 局的调用使用方式
mSubBinding = mBinding.layoutSub
mBinding.buttonAdd.setOnClickListener {
    val tv = TextView(this)
    tv.text = "是神仙姐姐呀~"
    tv.isSingleLine = true
    tv.maxLines = 1
    // !!需要走一遍测量-》布局的过程确定View的宽高和位置,否则是无法展示的
    tv.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED)
    // 调用layout方法确定tv控件的摆放位置
    tv.layout(0, 800, 1600, 1800)
    Log.d(TAG, "buttonAdd click, tv.w = ${tv.measuredWidth}, tv.h = ${tv.measuredHeight}")
    // container是一个普通的LinearLayout布局容器
    mSubBinding.container.overlay.add(tv)
}

效果截图:
ViewOverlay-加蒙层真的一种实现方式### 三、问题
    通过overlay方式添加view层级,通过AS的LayoutInspector工具抓布局居然看不到增加的View层级!!
ViewOverlay-加蒙层真的一种实现方式文章来源地址https://www.toymoban.com/news/detail-475274.html

到了这里,关于ViewOverlay-加蒙层真的一种实现方式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux下获取另外一个程序的标准输出和标准错误输出的一种实现方式

    问题:一个程序如何获取另外一个程序的标准输出和标准错误输出? 标准输入,标准输出,标准错误输出是一个程序的基本组成,在Linux下一个程序调用另外一个程序,如何获取其标准输出和错误输出呢? 分析:一个程序获取另外一个程序的信息,本质上是IPC(基于进程的通

    2024年02月13日
    浏览(31)
  • 我真的不想再用mybatis和其衍生框架了选择自研亦是一种解脱

    文档地址 https://xuejm.gitee.io/easy-query-doc/ GITHUB地址 https://github.com/xuejmnet/easy-query GITEE地址 https://gitee.com/xuejm/easy-query 众所邹知orm的出现让本来以sql实现的复杂繁琐功能大大简化,对于大部分程序员而言一个框架的出现是为了生产力的提升.。dbc定义了交互数据库的规范,任何数据库

    2024年02月16日
    浏览(34)
  • 云计算、大数据技术的智慧工地,实现对建筑工地实时监测、管理和控制的一种新型建筑管理方式

    智慧工地是利用物联网、云计算、大数据等技术,实现对建筑工地实时监测、管理和控制的一种新型建筑管理方式。 智慧工地架构: 1、终端层: 充分利用物联网技术、移动应用、智能硬件设备提高现场管控能力。通过RFID、传感器、摄像头、手机等终端设备,实现对项目建

    2024年02月04日
    浏览(31)
  • QML和C++交互中,实现C++中connect到qml的信号,再从qml发射信号传递数据给C++的一种方式

    假设我们有一个需求,要求在用户点击列表中的项目时,不仅在控制台上输出项目的名称,还要在C++端进行一些处理。我们希望在C++端能够接收到用户点击的项目名称,并进行相应的处理。 在这种情况下,我们可能会遇到一个常见的问题:如何在QML中捕获用户点击事件,并将

    2024年02月05日
    浏览(46)
  • Flask的一种启动方式和三种托管方式

    Flask 支持使用原生的 app.run() 方法来启动应用程序。这种方法是最简单、最基本的启动方式,适用于开发环境和小型应用程序。 以上代码定义了一个简单的 Flask 应用程序,其中一个路由 / 映射到了一个名为 hello_world() 的视图函数。在最后一行,我们通过 app.run() 方法启动了应

    2024年02月06日
    浏览(25)
  • 记录--你真的能区分JavaScript的各种导入导出方式吗?

    我们在无论是在查阅别人的代码,还是在实际项目开发的过程中,肯定都会使用导入导出的功能,有时候我们会搞混这几种方式到底有什么区别,今天我们就来细致的区分一下: 我们都知道最常见的几种导出方式无非是 export , exports , export default , module.exports 这几种,常

    2024年02月08日
    浏览(28)
  • 对称加密原理 - 一种古老的加密方式

    哈希是打开加密货币的第一把钥匙,我们已经深度剖析了如何证明工作量、梅克尔树如何检测防篡改以及区块链牵一发而动全身的链式结构,为学习加密货币奠定良好基础。我们今天讨论对称加密技术的基本原理。 请大家关注 gitcoins抖音频道 ,我们将会分享有趣的、高质量

    2024年02月01日
    浏览(29)
  • 探索一种C++中构造对象的方式

    本文展示一种构造对象的方式,用户无需显式调用构造函数。 对于有参数的构造函数的类,该实现在构造改对象时传递默认值来构造。当然用户也可以指定(绑定)某个参数的值。 实现思路参考boost-ext/di的实现。 来看下例子: 例子比较简单,构造一个ObjectCreator对象,并调用他

    2024年02月07日
    浏览(27)
  • chatgpt智能提效职场办公-ppt怎么蒙层

    作者:虚坏叔叔 博客:https://xuhss.com 早餐店不会开到晚上,想吃的人早就来了!😄 在 PowerPoint 中添加蒙版图层,可以在幻灯片中创建一个半透明的矩形或形状,并在其上方添加或放置其他对象。 下面是一些步骤: 在幻灯片中,添加一个形状或图像,并将其放在你想要添加

    2023年04月26日
    浏览(37)
  • elasticsearch 快照丢失部分的恢复 ----- 一种解决方式

    前文   es提供了数据备份和恢复的方式,可以很方便的供数据备份,同时应用于多套环境,且可以自定义备份目标(比如具体到索引),可以自定义备份策略(比如每天早上定时备份),可以说是非常方便,关于如何备份,网上的文档很多,有机会我也出一篇。另外,关于

    2024年02月15日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包