Android中的drawable

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

1.drawable简介

1.1.什么是drawable

drawable是一种可以在Canvas上进行绘制的抽象的概念,颜色图片都可以是一个drawable,Drawable可以通过XML定义,或者通过代码创建,Android中的drawable是一个抽象类,每个具体的Drawable都是其子类

优点:使用简单,比自定义view成本低,占用空间小,可以减少apk大小

1.2.drawable的份分类

1.2.1.BitmapDrawable

表示一张图片,可以直接引用原始图片或者通过XML进行描述

属性 作用 备注
android:src 图片资源ID
android:antialias 图片抗锯齿-图片平滑,清晰度降低
android:dither 开启抖动效果-用于高质量图片在低质量屏幕上保存较好的显示效果(不会失真) 应该开启
android:filter 开启过滤-在图片尺寸拉伸和压缩时保持较好的显示效果 应该开启
android:gravity 图片小于容器尺寸时,对图片进行定位-选项之间用‘ ’来组合使用
android:mipMap 纹理映射-图像处理技术 默认false
android:tileMode 平铺模式-repeat单纯重复、mirror镜面反射、clamp图片四周像素扩散 默认disable关闭
1.2.2.NinePatchDrawable(.9图片)

自动根据宽高进行缩放不会失真

实际使用,可以直接引用图片或者通过XML描述

1.2.3.ShapeDrawable

通过颜色来构造的图形,可以是纯色的图形,也可以是有渐变效果的图形,shape标签创建的Drawable实体是GradientDrawable

使用:

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

    <corners
        android:radius="10dp"
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp"/>
    <gradient
        android:angle="45"
        android:centerX="30"
        android:centerY="30"
        android:centerColor="@color/colorAccent"
        android:endColor="@color/colorPrimary"
        android:startColor="@color/colorPrimaryDark"
        android:gradientRadius="20"
        android:type="linear"
        android:useLevel="true" />
    <padding
        android:left="10dp"
        android:top="10dp"
        android:right="10dp"
        android:bottom="10dp" />
    <size
        android:width="200dp"
        android:height="200dp" />
    <solid
        android:color="@color/colorPrimary"/>
    <stroke
        android:width="10dp"
        android:color="@color/colorAccent"
        android:dashWidth="5dp"
        android:dashGap="3dp"/>

</shape>
属性/标签 作用 备注
android:shape 图形的形状:rectangle矩形、oval椭圆、line横线、ring圆环 corners标签对应于矩形;line和ring通过stroke指定线的宽度和颜色; ring圆环有五个特殊的shape属性
corners标签 四个角的角度
gradient标签 渐变效果-android:angle表示渐变角度,必须为45的倍数 android:type指明渐变类型:linear线性,radial径向、sweep扫描
solid标签 纯色填充 与gradient标签排斥
stroke标签 描边 有描边线和虚线
size标签 表示shape的固有大小,并非最终显示的大小 没有时getIntrinsicWidth返回-1;能指明Drawable的固有宽高,但如果作为View背景还是会被拉伸
1.2.4.LayerDrawable

XMl标签为layer-list,层次化的Drawable合集,可以包含多个item,每个item表示一个Drawable item中可以通过android:drawable直接引用资源,android:top等表示Drawable相当于View上下左右的偏移量

使用:

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

    <item>
        <shape android:shape="rectangle">
            <solid
                android:color="#0ac39e"/>
        </shape>
    </item>

    <item
        android:bottom="6dp">
        <shape android:shape="rectangle">
            <solid
                android:color="#FFFFFF"/>
        </shape>
    </item>

    <item
        android:bottom="1dp"
        android:left="1dp"
        android:right="1dp">
        <shape android:shape="rectangle">
            <solid
                android:color="#FFFFFF"/>
        </shape>
    </item>

</layer-list>
1.2.5.StateListDrawable

对应于selector标签,用于View根据状态选择不同的Drawable

使用:

<?xml version="1.0" encoding="utf-8"?>
<selector
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:constantSize="false" //StateListDrawable的固有大小是否根据状态而改变,默认false=根据状态而改变
    android:dither="true"        //是否开启抖动-让高质量图片在低质量屏幕上依旧效果好,默认true开启
    android:variablePadding="false" //padding是否根据状态的改变而改变,不建议开启(false)
    >
    <item android:state_pressed="true"  //Button被按下后却没有松开的状态
        android:drawable="@color/colorAccent"/>
    <item android:state_focused="true"  //View获取了焦点
        android:drawable="@color/colorPrimary"/>
    <item android:state_selected="true" //用户选择了View
        android:drawable="@color/colorPrimary"/>
    <item android:state_checked="true" //用户选中了View,一般用于CheckBox这类在选中和没有选中状态之间切换的View
        android:drawable="@drawable/ic_launcher_background"/>
    <item android:state_enabled="true" //View处于可用状态
        android:drawable="@drawable/ic_launcher_foreground"/>
    <item android:drawable="#FFFFFF"/> //默认Drawable: 按顺序向下匹配,需要放在最下方,因为可以匹配任何状态
</selector>
1.2.6.LevelListDrawable

对应于level-list标签,拥有多个item,每个item都有maxLevelminLevelLevel的范围为0~10000,给定level后,会按从上至下的顺序匹配,直到找到范围合适的Drawable,并返回,item的level一定要降序或者升序,调用View的getBackground获得Drawable对象,并调用setLevel设置等级level,ImageView的setImageLevel()能快速指定src引用的Drawable的Level,LevelListDrawable是根据level改变,选择不同的Drawable,能用于实现进度条、音量调节等等

使用:

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:minLevel="0" android:maxLevel="10" android:drawable="@drawable/d1" />
    <item android:minLevel="11" android:maxLevel="20" android:drawable="@drawable/d2" />
    <item android:minLevel="21" android:maxLevel="30" android:drawable="@drawable/d3" />
    <item android:minLevel="31" android:maxLevel="40" android:drawable="@drawable/d4" />
</level-list>
1.2.7.TransitionDrawable

对应于transition标签,实现两个Drawable之前的淡入淡出效果,获得背景的TransitionDrawable后,通过startTransitionreverseTransition方法实现效果和逆过程

使用:

  Glide.with(this)
                .load(prcUrl)
                .format(DecodeFormat.PREFER_ARGB_8888)
                .into(object : CustomTarget<Drawable>() {
                    override fun onResourceReady(
                        resource: Drawable,
                        transition: Transition<in Drawable>?
                    ) {
                        val mPrePosterDrawable = mResultPosterDrawable
                        if(resource is BitmapDrawable){
                            val bitmap = resource.bitmap
                            if(bitmap != null) {
                                val tempBitmap = Bitmap.createBitmap(bitmap)
                                mResultPosterDrawable = BitmapDrawable(resources, tempBitmap)
                                VodLogUtils.d(TAG, "mResultPosterDrawable=$mResultPosterDrawable" )
                            }
                        }

                        if(mResultPosterDrawable == null) {
                            VodLogUtils.d(TAG, "mResultPosterDrawable is null" )
                            return
                        }

                        try {
                            val transitionDrawable = if(mPrePosterDrawable == null
                                || (mPrePosterDrawable is BitmapDrawable && mPrePosterDrawable.bitmap == null)
                                || (mPrePosterDrawable is BitmapDrawable && mPrePosterDrawable.bitmap.isRecycled)){
                                VodLogUtils.d(TAG, "mPrePosterDrawable is null" )
                                TransitionDrawable(arrayOf(ResourcesCompat.getDrawable(resources,R.drawable.vod_common_dialog_player_mask, null), mResultPosterDrawable))
                            } else {
                                TransitionDrawable(arrayOf(mPrePosterDrawable, mResultPosterDrawable))
                            }
                            transitionDrawable.isCrossFadeEnabled = false
                            transitionDrawable.startTransition(500)

                            mMaskView.background = transitionDrawable
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }

                    }

                    override fun onLoadCleared(placeholder: Drawable?) {}
                })

实现两张图片渐隐渐显

1.2.8.InsetDrawable的

对应inset标签,将其他Drawable内嵌到自身,并在四周留出间距,View需要背景比自己实际区域要小的时候,可以使用insetlayer-list也可以实现该需求

使用:

<inset xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:insetTop="10dp"
    android:insetBottom="10dp"
    android:insetLeft="10dp"
    android:insetRight="10dp">
</inset>
1.2.9.ScaleDrawable

对应于scale标签
根据自己的等级level(0~10000)将指定的Drawable缩放到一定比例
android:scaleHeight="70%"用于指定宽高的缩放比例=为原来的30%
ScaleDrawable的level为0,不可见。为10000时,不缩放。
一般将level设置为1,就会按照属性指定的比例缩放。其他值也会改变缩放效果。
android:scaleGravity属性和gravity属性完全一致
使用:

<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_launcher"
    android:scaleGravity="center"
    android:scaleHeight="70%"
    android:scaleWidth="70%">
</scale>
1.3.0.ClipDrawable

对应于clip标签

根据自己当前的等级level(0~10000)来裁剪另一个Drawable

裁剪方向由clipOrientationgravity属性共同控制

level为0,Drawable不可见;10000表示不裁剪;为8000,表示裁减了2000;为1,表示裁剪了9999

1.3.1.AnimationDrawable

对应于animation-list标签
用于实现逐帧动画效果
android:oneShot决定是循环播放还是播放一次,false:循环播放
item中设置一帧一帧的Drawable以及持续时间
AnimationDrawable的setOneShot(boolean flag) 和android:oneShot配置一样
addFrame (Drawable frame, int duration) 动态的添加一个图片进入该动画中
stop()和start()用于停止和开始/继续播放,停止时会停留在当前一帧上
使用:

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="false">
    <item android:drawable="@drawable/shake_anim_01" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_02" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_03" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_04" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_05" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_06" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_07" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_08" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_09" android:duration="100"/>
    <item android:drawable="@drawable/shake_anim_10" android:duration="100"/>
</animation-list>
val imageview = findViewById<ImageView>(R.id.imaview)
(imageview.drawable as AnimationDrawable).start() //开始播放
1.3.1.ShapeDrawable的OvalShape、RectShape、ArcShape和PaintDrawable

用于获得有shape形状drawable(椭圆、长方形、扇形以及更为通用PaintDrawable-具有圆角和边界)

        /**===================================================
         *  一个继承自ShapeDrawable更为通用的Drawable:具有圆角
         *====================================================*/
        PaintDrawable drawable3 = new PaintDrawable(Color.GREEN);
        drawable3.setCornerRadius(30);
        findViewById(R.id.textView3).setBackgroundDrawable(drawable3);

        /**============================================
         *   通过Shape构造出相应的ShapeDrawable
         *=============================================*/
        //椭圆形形状 : shape赋予ShapeDrawable
        OvalShape ovalShape = new OvalShape();
        ShapeDrawable drawable1 = new ShapeDrawable(ovalShape);
        drawable1.getPaint().setColor(Color.BLUE);
        drawable1.getPaint().setStyle(Paint.Style.FILL);
        findViewById(R.id.textView1).setBackgroundDrawable(drawable1);

        //矩形形状  : shape赋予ShapeDrawable
        RectShape rectShape = new RectShape();
        ShapeDrawable drawable2 = new ShapeDrawable(rectShape);
        drawable2.getPaint().setColor(Color.RED);
        drawable2.getPaint().setStyle(Paint.Style.FILL);
        findViewById(R.id.textView2).setBackgroundDrawable(drawable2);

        //扇形、扇面形状 : shape赋予ShapeDrawable
        //顺时针,开始角度30, 扫描的弧度跨度180
        ArcShape arcShape = new ArcShape(30, 180);
        ShapeDrawable drawable4 = new ShapeDrawable(arcShape);
        drawable4.getPaint().setColor(Color.YELLOW);
        drawable4.getPaint().setStyle(Paint.Style.FILL);
        findViewById(R.id.textView4).setBackgroundDrawable(drawable4);
1.3.2.自定义Drawable

一般作为ImageView的图像来显示
另一个是作为View的背景
自定义Drawable主要就是实现draw方法
setAlpha、setColorFilter、getOpacity也需要重写,但是模板固定
当自定义Drawable有固定大小时(比如绘制一张图片),需要重写getIntrinsicWidth()/getIntrinsicHeight()方法(默认返回-1),会影响到View的wrap_content布局
内部固定大小不等于Drawable的实际区域大小,getBounds能获得实际区域大小
模板代码:文章来源地址https://www.toymoban.com/news/detail-848575.html

class CustomDrawable(color: Int) : Drawable(){
    var mPaint: Paint
    init {
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mPaint.color = color
    }
    override fun draw(canvas: Canvas) {
        val rect = bounds
        canvas.drawCircle(rect.exactCenterX(),
                rect.exactCenterY(),
                Math.min(rect.exactCenterX(), rect.exactCenterY()),
                mPaint)
    }

    override fun setAlpha(alpha: Int) {
        mPaint.alpha = alpha
        invalidateSelf()
    }
    override fun setColorFilter(colorFilter: ColorFilter?) {
        mPaint.colorFilter = colorFilter
        invalidateSelf()
    }
    override fun getOpacity(): Int {
        //not sure, so be safe
        return PixelFormat.TRANSLUCENT
    }
}

到了这里,关于Android中的drawable的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Android实现保存res下(drawable/mipmap)的图片到手机相册

    项目小需求需要保存二维码名片到手机相册的需求,该图片在res/mipmap或者res/drawable文件夹下,实现方法如下。 代码如下(示例): 代码如下(示例): 以上就是今天要讲的内容,本文仅仅简单介绍了在res/mipmap或者res/drawable文件夹下图片保存到手机相册的方法。

    2024年02月12日
    浏览(58)
  • Android 布局菜鸟 android中的布局类型和特点?

           一、LinearLayout(线性布局) 1、 特点:         主要以水平或垂直方式来排列界面中的控件。并将控件排列到一条直线上。在线性布局中,如果水平排列,垂直方向上只能放一个控件,如果垂直排列,水平方向上也只能放一个控件。 2、适⽤场景:         And

    2024年01月17日
    浏览(32)
  • Android中的SDK以及利用Android Studio生成aar

    广义上的SDK: 指的是为特定的软件包、软件框架、硬件平台、操作系统等建立应用程序时所使用的开发工具的集合。 比如你在编辑器里敲代码的时候它会自动补全代码,自动错误检查,你点一下Run,它会调用编译器来自动编译,编译完它会调用iPhone的模拟器来运行,这就是

    2024年02月12日
    浏览(47)
  • 【Android】解决Android Studio中的虚拟设备无法上网问题

    前言 : 使用AndroidStudio自带的虚拟设备在调试软件时, 发现无法联网,然后用虚拟设备自带的浏览器进行网页访问也是失败的, 因此可以说明是整个虚拟设备是无法正常联网通讯的! 问题原因 :可能你的虚拟设备的DNS设置和你的电脑的DNS不在一个网段上,需要修改虚拟设备的

    2024年02月06日
    浏览(49)
  • 【Android】细数Linux和Android系统中的伪文件系统

    做了好些年Android开发,你了解过Linux伪文件系统吗? 在 Linux 中,伪文件系统(Pseudo Filesystem)是一种特殊的文件系统,它不涉及具体的物理存储设备,而是提供了一种接口,允许用户和应用程序以文件和目录的形式访问内核和其他系统信息。这些文件和目录在运行时被内核动

    2024年01月24日
    浏览(35)
  • Android系统的问题分析笔记(9) - Android 中的 Uri 如何使用呢 ?

    Android 中常用的 uri 如何使用呢 ?(此篇分析基础为Android 7.1.1系统源码),参看Android官方说明:https://developer.android.com/reference/android/net/Uri,代码可在此查看:https://github.com/LineageOS/android_frameworks_base/blob/lineage-20.0/core/java/android/net/Uri.java   通用资源标志符 URI (Universal Resour

    2024年02月09日
    浏览(49)
  • Android中的ABI

    ABI是Application Binary Interface的缩写。 ABI常表示两个程序模块之间的接口,且其中一个模块常为机器码级别的library或操作系统。 ABI定义了函数库的调用、应用的二进制文件(尤其是.so)如何运行在相应的系统平台上等细节。 Android目前支持以下七种ABI: armeabi、armeabi-v7a、arm64

    2024年02月14日
    浏览(36)
  • Android 中的 线程池

    1、corePoolSize 用于指定线程池的核心线程数大小; 2、maximumPoolSize 用于指定最大线程池大小。 3、keepAliveTime,unit 一起用于指定线程池中空闲线程的最大存活时间。 4、workQueue 任务队列,相当于生产者 - 消费者模式中的传输管道,用于存放待处理的任务。 5、threadFactory 用于指

    2024年02月09日
    浏览(32)
  • Android中的内存管理

    1.内存管理机制概述 1.分配机制: 安卓系统会为每个进程合理的分配内存,从而保证每个进程能正常运行。而不至于内存不够使用或者每个进程占用太多的内存。 2.回收机制 操作系统在内存不足的时候,它会有一个合理的回收和再分配的机制。 从而保证新的进程能够正常运

    2024年02月07日
    浏览(34)
  • Android中的蓝牙技术

    随着智能化生活的发展,手机成为人们生活的必需品,而蓝牙技术也随之应运而生。蓝牙技术作为现代移动设备与设备之间传输数据的一种主流方式,已经广泛应用于手表、耳机、车载系统等多种设备。在Android设备中,蓝牙技术也被大量使用,本篇文章将介绍Android中的蓝牙

    2024年02月07日
    浏览(34)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包