如果您需要在应用内显示静态图片,可以使用 Drawable 类及其子类绘制形状和图片。Drawable 是可绘制对象的常规抽象。不同的子类可用于特定的图片场景,您可以对其进行扩展以定义您自己的行为方式独特的可绘制对象。

除了使用类构造函数之外,还可以通过另外两种方法定义和实例化 Drawable

  • 扩充保存在项目中的图片资源(位图文件)。

  • 扩充用于定义可绘制属性的 XML 资源。

注意:您可以改用矢量可绘制对象,它通过一组点、线条和曲线以及相关颜色信息定义图片。这样一来,就可以在不降低质量的情况下将矢量可绘制对象缩放为不同的尺寸。如需了解详情,请参阅矢量可绘制对象概览。

通过资源图片创建可绘制对象

您可以通过引用项目资源中的图片文件向您的应用添加图形。支持的文件类型包括 PNG(首选)、JPG(可接受)和 GIF(不推荐)。这种方法非常适合添加应用图标、徽标和其他图形(例如游戏中使用的图形)。

要使用图片资源,请将相应文件添加到项目的 res/drawable/ 目录下。在项目中,您可以从代码或 XML 布局中引用图片资源。无论是哪种方式,都是通过资源 ID(不包含文件类型扩展名的文件名)引用的。例如,my_image.png 引用为 my_image

注意res/drawable/ 目录下的图片资源可由 aapt 工具在构建过程中自动完成无损图片压缩优化。例如,可以通过调色板将不需要超过 256 种颜色的真彩色 PNG 转换为 8 位 PNG。这样做会生成质量相同但内存占用量更小的图片。因此,此目录下的图片二进制文件可能会在构建时发生更改。如果您打算将某张图片作为比特流进行读取以将其转换为位图,请改为将图片放在 res/raw/ 文件夹下,这样的话,aapt 工具便无法对其进行修改。

以下代码段演示了如何使用通过可绘制资源创建的图片构建一个 ImageView 并将其添加到布局中:

JAVA

    ConstraintLayout constraintLayout;    protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      // Create a ConstraintLayout in which to add the ImageView      constraintLayout = new ConstraintLayout(this);      // Instantiate an ImageView and define its properties      ImageView i = new ImageView(this);      i.setImageResource(R.drawable.my_image);      i.setContentDescription(getResources().getString(R.string.my_image_desc));      // set the ImageView bounds to match the Drawable's dimensions      i.setAdjustViewBounds(true);      i.setLayoutParams(new ViewGroup.LayoutParams(              ViewGroup.LayoutParams.WRAP_CONTENT,              ViewGroup.LayoutParams.WRAP_CONTENT));      // Add the ImageView to the layout and set the layout as the content view.      constraintLayout.addView(i);      setContentView(constraintLayout);    }    

KOTLIN

    private lateinit var constraintLayout: ConstraintLayout    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        // Instantiate an ImageView and define its properties        val i = ImageView(this).apply {            setImageResource(R.drawable.my_image)            contentDescription = resources.getString(R.string.my_image_desc)            // set the ImageView bounds to match the Drawable's dimensions            adjustViewBounds = true            layoutParams = ViewGroup.LayoutParams(                    ViewGroup.LayoutParams.WRAP_CONTENT,                    ViewGroup.LayoutParams.WRAP_CONTENT)        }        // Create a ConstraintLayout in which to add the ImageView        constraintLayout = ConstraintLayout(this).apply {            // Add the ImageView to the layout.            addView(i)        }        // Set the layout as the content view.        setContentView(constraintLayout)    }    

在其他情况下,您可能需要将图片资源作为 Drawable 对象进行处理,如下例所示:

JAVA

    Resources res = context.getResources();    Drawable myImage = ResourcesCompat.getDrawable(res, R.drawable.my_image, null);    

KOTLIN

    val myImage: Drawable = ResourcesCompat.getDrawable(context.resources, R.drawable.my_image, null)    

注意:项目中的每个唯一资源只能具有一种状态,无论您为其实例化多少个不同的对象。例如,如果您用同一图片资源实例化了两个 Drawable 对象,并更改其中一个对象的属性(例如不透明度),则另一个对象也会受到影响。在处理图片资源的多个实例时,您应执行补间动画,而不是直接转换 Drawable 对象。

以下 XML 代码段展示了如何在 XML 布局中向 ImageView 添加可绘制资源:

                android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:src="@drawable/my_image"            android:contentDescription="@string/my_image_desc" />    

如需详细了解如何使用项目资源,请参阅资源。

注意:将图片资源用作可绘制对象的来源时,请确保图片的尺寸适合不同的像素密度。如果图片的尺寸不合适,系统会将其缩放为合适的尺寸,而这可能会导致可绘制对象失真。如需了解详情,请参阅支持不同的像素密度。

通过 XML 资源创建可绘制对象

如果您想创建一个 Drawable 对象,该对象最初并不依赖于由您的代码定义的变量或用户互动,则最好在 XML 中定义 Drawable。即使您预期 Drawable 在用户与您的应用互动时属性会更改,您也应考虑在 XML 中定义该对象,因为您可以在对其进行实例化之后修改其属性。

在 XML 中定义 Drawable 之后,将文件保存在项目的 res/drawable/ 目录下。以下示例展示了定义 TransitionDrawable 资源(继承自 Drawable)的 XML:

        <transition xmlns:android="http://schemas.android.com/apk/res/android">        <item android:drawable="@drawable/image_expand">        <item android:drawable="@drawable/image_collapse">    transition>    

然后,通过调用 Resources.getDrawable() 并传入 XML 文件的资源 ID 来检索并实例化相应对象。支持 inflate() 方法的任何 Drawable 子类都可以在 XML 中进行定义并由您的应用实例化。支持 XML 扩充的各个可绘制类利用特定的 XML 属性来帮助定义对象属性。以下代码会实例化 TransitionDrawable 并将其设置为 ImageView 对象的内容:

JAVA

    Resources res = context.getResources();    TransitionDrawable transition =        (TransitionDrawable) ResourcesCompat.getDrawable(res, R.drawable.expand_collapse, null);    ImageView image = (ImageView) findViewById(R.id.toggle_image);    image.setImageDrawable(transition);    // Description of the initial state that the drawable represents.    image.setContentDescription(getResources().getString(R.string.collapsed));    // Then you can call the TransitionDrawable object's methods.    transition.startTransition(1000);    // After the transition is complete, change the image's content description    // to reflect the new state.    

KOTLIN

    val transition= ResourcesCompat.getDrawable(            context.resources,            R.drawable.expand_collapse,            null    ) as TransitionDrawable    val image: ImageView = findViewById(R.id.toggle_image)    image.setImageDrawable(transition)    // Description of the initial state that the drawable represents.    image.contentDescription = resources.getString(R.string.collapsed)    // Then you can call the TransitionDrawable object's methods.    transition.startTransition(1000)    // After the transition is complete, change the image's content description    // to reflect the new state.    

如需详细了解支持的 XML 属性,请参阅上面列出的类。

形状可绘制对象

如果您想动态绘制二维图形,ShapeDrawable 对象是一种不错的选择。您可以程序化地在 ShapeDrawable 对象上绘制基元形状,并采用您的应用所需的样式。

ShapeDrawable 是 Drawable 的子类。因此,您可以在需要使用 Drawable 时使用 ShapeDrawable。例如,您可以使用 ShapeDrawable 对象设置视图的背景,具体方法是将其传递给视图的 setBackgroundDrawable() 方法。您还可以绘制形状作为其自定义视图,然后将其添加到应用的布局中。

ShapeDrawable 有自己的 draw() 方法,因此您可以创建一个在 onDraw() 事件期间绘制 ShapeDrawable 对象的 View 的子类,如以下代码示例所示:

JAVA

    public class CustomDrawableView extends View {      private ShapeDrawable drawable;      public CustomDrawableView(Context context) {        super(context);        int x = 10;        int y = 10;        int width = 300;        int height = 50;        setContentDescription(context.getResources().getString(                R.string.my_view_desc));        drawable = new ShapeDrawable(new OvalShape());        // If the color isn't set, the shape uses black as the default.        drawable.getPaint().setColor(0xff74AC23);        // If the bounds aren't set, the shape can't be drawn.        drawable.setBounds(x, y, x + width, y + height);      }      protected void onDraw(Canvas canvas) {        drawable.draw(canvas);      }    }    

KOTLIN

    class CustomDrawableView(context: Context) : View(context) {        private val drawable: ShapeDrawable = run {            val x = 10            val y = 10            val width = 300            val height = 50            contentDescription = context.resources.getString(R.string.my_view_desc)            ShapeDrawable(OvalShape()).apply {                // If the color isn't set, the shape uses black as the default.                paint.color = 0xff74AC23.toInt()                // If the bounds aren't set, the shape can't be drawn.                setBounds(x, y, x + width, y + height)            }        }        override fun onDraw(canvas: Canvas) {            drawable.draw(canvas)        }    }    

您可以像使用任何其他自定义视图一样使用上述代码示例中的 CustomDrawableView 类。例如,您可以程序化地将其添加到应用中的某个 Activity,如下例所示:

JAVA

    CustomDrawableView customDrawableView;    protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      customDrawableView = new CustomDrawableView(this);      setContentView(customDrawableView);    }    

KOTLIN

    private lateinit var customDrawableView: CustomDrawableView    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        customDrawableView = CustomDrawableView(this)        setContentView(customDrawableView)    }    

如果您想改为在 XML 布局中使用自定义视图,则 CustomDrawableView 类必须替换 View(Context, AttributeSet) 构造函数(在该类从 XML 中扩充时调用)。以下示例展示了如何在 XML 布局中声明 CustomDrawableView

    <com.example.shapedrawable.CustomDrawableView            android:layout_width="fill_parent"            android:layout_height="wrap_content"            />    

ShapeDrawable 类与 android.graphics.drawable 软件包中的很多其他可绘制类型一样,可让您使用公开方法定义对象的各种属性。您可能需要调整的一些示例属性包括 alpha 透明度、色彩滤镜、抖动、不透明度和颜色。

您还可以使用 XML 资源定义基元可绘制形状。如需了解详情,请参阅可绘制资源类型中的形状可绘制对象。

NinePatch 可绘制对象

NinePatchDrawable 图形是一种可拉伸的位图,可用作视图的背景。Android 会自动调整图形的大小以适应视图的内容。NinePatch 图片的其中一项用途是用作标准 Android 按钮(按钮必须拉伸以适应各种长度的字符串)的背景。NinePatch 图形是标准 PNG 图片,包含一个额外的 1 像素边框。必须使用 9.png 扩展名将其保存在项目的 res/drawable/ 目录下。

使用边框可定义图片的可拉伸区域和静态区域。您可以通过在边框的左侧和顶部绘制一条(或多条)1 像素宽的黑线来指定可拉伸部分(其他边框像素应完全透明或为白色)。您可以根据需要添加任意数量的可拉伸部分。可拉伸部分的相对尺寸保持不变,因此最大部分始终为最大。

您还可以定义图片的可选可绘制部分(有效的方法是添加内边距线),方法是在右侧和底部各画一条线。如果 View 对象将 NinePatch 图形设置为其背景,然后指定视图的文本,则它会拉伸其自身以便所有文本仅位于右侧和底部的线所指定的区域(如有)。如果没有添加内边距线,则 Android 会使用左侧和顶部的线定义这一可绘制区域。

为了明确区分各条线,左侧和顶部的线定义允许复制图片的哪些像素来拉伸图片。底部和右侧的线定义图片中允许放置视图内容的相对区域。

图 1 显示了定义按钮的 NinePatch 图形示例:

图 1:定义按钮的 NinePatch 图形示例

此 NinePatch 图形通过左侧和顶部的线定义可拉伸区域,通过底部和右侧的线定义可绘制区域。在上方的图片中,灰色虚线表示图片中为了拉伸图片而复制的区域。在下方的图片中,粉色矩形表示允许放置视图内容的区域。如果内容不适合此区域,则图片会拉伸以使其合适。

您可以使用 Draw 9-patch 工具提供的 WYSIWYG 图形编辑器创建 NinePatch 图片,极其方便。如果您定义的可拉伸区域可能会因像素复制而失真,该工具甚至会发出警告。

以下示例布局 XML 演示了如何为多个按钮添加 NinePatch 图形。NinePatch 图片会保存到 res/drawable/my_button_background.9.png

    <Button android:id="@+id/tiny"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentTop="true"            android:layout_centerInParent="true"            android:text="Tiny"            android:textSize="8sp"            android:background="@drawable/my_button_background"/>    <Button android:id="@+id/big"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentBottom="true"            android:layout_centerInParent="true"            android:text="Biiiiiiig text!"            android:textSize="30sp"            android:background="@drawable/my_button_background"/>    

请注意,layout_width 和 layout_height 属性均设置为 wrap_content 以使按钮恰好适合文本内容。

图 2 显示了通过上述 XML 和 NinePatch 图片渲染的两个按钮。请注意按钮的宽度和高度如何随文本而发生变化,以及背景图片如何拉伸以适应文本。

图 2:通过 XML 资源和 NinePatch 图形渲染的按钮

自定义可绘制对象

如果您想创建一些自定义可绘制对象,可以通过扩展 Drawable 类(或其任何子类)来实现。

要实现的最重要方法是 draw(Canvas),因为它提供了您在提供绘制指令时必须使用的 Canvas 对象。

以下代码展示了用于绘制圆形的 Drawable 的简单子类:

JAVA

    public class MyDrawable extends Drawable {        private final Paint redPaint;        public MyDrawable() {            // Set up color and text size            redPaint = new Paint();            redPaint.setARGB(255, 255, 0, 0);        }        @Override        public void draw(Canvas canvas) {            // Get the drawable's bounds            int width = getBounds().width();            int height = getBounds().height();            float radius = Math.min(width, height) / 2;            // Draw a red circle in the center            canvas.drawCircle(width/2, height/2, radius, redPaint);        }        @Override        public void setAlpha(int alpha) {            // This method is required        }        @Override        public void setColorFilter(ColorFilter colorFilter) {            // This method is required        }        @Override        public int getOpacity() {            // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE            return PixelFormat.OPAQUE;        }    }    

KOTLIN

    class MyDrawable : Drawable() {        private val redPaint: Paint = Paint().apply { setARGB(255, 255, 0, 0) }        override fun draw(canvas: Canvas) {            // Get the drawable's bounds            val width: Int = bounds.width()            val height: Int = bounds.height()            val radius: Float = Math.min(width, height).toFloat() / 2f            // Draw a red circle in the center            canvas.drawCircle((width / 2).toFloat(), (height / 2).toFloat(), radius, redPaint)        }        override fun setAlpha(alpha: Int) {            // This method is required        }        override fun setColorFilter(colorFilter: ColorFilter?) {            // This method is required        }        override fun getOpacity(): Int =            // Must be PixelFormat.UNKNOWN, TRANSLUCENT, TRANSPARENT, or OPAQUE            PixelFormat.OPAQUE    }    

然后,您可以将可绘制对象添加到任意位置;例如添加到 ImageView(如下所示):

JAVA

    MyDrawable mydrawing = new MyDrawable();    ImageView image = findViewById(R.id.imageView);    image.setImageDrawable(mydrawing);    image.setContentDescription(getResources().getString(R.string.my_image_desc));    

KOTLIN

    val myDrawing = MyDrawable()    val image: ImageView = findViewById(R.id.imageView)    image.setImageDrawable(myDrawing)    image.contentDescription = resources.getString(R.string.my_image_desc)    

在 Android 7.0(API 级别 24)及更高版本上,您还可以使用 XML 定义自定义可绘制对象的实例,方法如下:

  • 将完全限定类名用作 XML 元素名称。对于这种方法,自定义可绘制类必须是顶级公开类:

        <com.myapp.MyDrawable xmlns:android="http://schemas.android.com/apk/res/android"        android:color="#ffff0000" />    
  • 将 drawable 用作 XML 标记名称,并通过类属性指定完全限定的类名称。此方法可同时用于顶级公开类和公开静态内部类:

        "http://schemas.android.com/apk/res/android"        class="com.myapp.MyTopLevelClass$MyDrawable"        android:color="#ffff0000" />    

向可绘制对象添加色调

对于 Android 5.0(API 级别 21)及更高版本,您可以对定义为 Alpha 掩码的位图和九宫图进行色调调节。您可以使用颜色资源或解析为颜色资源的主题背景属性(例如 ?android:attr/colorPrimary)进行色调调节。通常情况下,您只需创建这些资源一次,然后自动为其着色以与您的主题背景相符。

您可以使用 setTint() 方法对 BitmapDrawableNinePatchDrawable 或 VectorDrawable 对象着色。您还可以使用 android:tint 和 android:tintMode 属性在布局中设置着色颜色和模式。

从图片中萃取突出颜色

Android 支持库包含 Palette 类,可让您从图片中萃取突出颜色。您可以将可绘制对象作为 Bitmap 进行加载,并将其传递到 Palette 以访问其颜色。如需了解详情,请参阅使用 Palette API 选择颜色。

android任意函数绘制_图片和图形 | 可绘制对象概览相关推荐

  1. 如何用lisp画蔓叶线_利用 TI 图形计算器绘制美丽的极坐标曲线

    利用 TI 图形计算器绘制美丽的极坐标曲线 规定有单位长度的射线 Ox,O 为极点,Ox 为极轴,这样就建立了极坐标系. 又把平 面上一点 P 到极点 O 的距离称为极径 ρ,OP 与 Ox 轴的夹角 ...

  2. 【Android】开源项目汇总-备用 各种图形的绘制,各种效果

    from://http://www.eoeandroid.com/home.php?mod=space&uid=765778&do=blog&id=47674 Android开 ...

  3. Android 任意View转为bitmap图片

    在开发的过程中有时会碰到这样的需求,把一个activity或者一个view变成图片分享出去.从网上收集了一些资料之后经过整理现在分享出来,教大家实现activity,scrollview,listvi ...

  4. 二维绕任意点旋转_二维图形复合线性变换程序设计:三角形绕任意点旋转2wfhbh...

    第七讲:二维图形复合线性变换程序设计: 例题:三角形绕任意点旋转. 组合变换为: ( 1 )平移变换 ( 2 )旋转变换 ( 3 )平移变换 #include #include #define PAI ...

  5. java 绘图 渐变_在CAShapeLayer图形下方绘制渐变

    我正在使用应用于CAShapeLayer的CGPath绘制图形 . 图形本身被绘制得很好,但我想在之后添加一个渐变 . 我的问题是路径是从最后一个点到第一个点的直线关闭(见下文) - 这会使渐变填充看 ...

  6. 如何用python画函数图像_使用python的pyplot绘制函数实例

    简介 本文主要介绍如何通过pyplot来绘制函数图.主要绘制函数如下: - 一元一次函数 - 一元二次函数 - 指数函数 - 自然对数函数 - 正弦函数 一元一次函数 代码 import matplo ...

  7. python 画任意函数曲线_使用Python画数学函数曲线

    import numpy as np import pandas as pd import matplotlib.pyplot as plt plt.figure(1) # 创建图表1 plt.fig ...

  8. MATLAB图形绘制--李萨茹图形的绘制以及生成运动轨迹的动画

    t = [0:0.02:10]; x = cos(t); y = cos(3*t+pi/2);for i = 1:length(t)scatter(x(i),y(i));hold on; % scat ...

  9. android音频开发6,Android 音视频开发(一) : 通过三种方式绘制图片

    想要逐步入门音视频开发,就需要一步步的去学习整理,并积累.本文是音视频开发积累的第一篇. 对应的要学习的内容是:在 Android 平台绘制一张图片,使用至少 3 种不同的 API,ImageView ...

  10. html5 简单图片效果,【HTML5】Canvas绘制简单图片教程,

    [HTML5]Canvas绘制简单图片教程, 获取Image对象,new出来 定义Image对象的src属性,参数:图片路径 定义Image对象的onload方法,调用context对象的drawIm ...

最新文章

  1. python中and与or的执行顺序-python 代码运行顺序问题?
  2. 二、CSS知识总结(上篇)
  3. php运算符的关键字,PHP 运算符
  4. 高速信号传输约翰逊 pdf_高速数字电路仿真设计与测试技术发展趋势综述 (一)...
  5. json数据格式了解
  6. Linux ping命令、Linux kill命令、Linux logname命令、 Linux logout命令
  7. dwr运行时出现Servlet.init() for servlet dwr-invoker threw exception的解决方法
  8. wifi连指定ssid和password
  9. centos-rpm
  10. [大数据]黑马hadoop学习笔记一
  11. 电力网络故障的计算机算法,电力系统故障分析的计算机算法.pdf
  12. 前后端分离和不分离图解
  13. 大话2正在连接登录服务器,大话西游手游服务器连接失败进不去解决办法
  14. c语言char怎么用?
  15. 安然公司特殊目的实体(SPEs)解读
  16. 隐藏微信公众号右上角的分享按钮
  17. “黑吃黑”webshell箱子
  18. Django企业开发实战--by胡阳,学习记录1127
  19. nagios配置示例
  20. 记录谷歌gn编译时碰到的一个错误“I could not find a “.gn“ file ...”

热门文章

  1. 第三部分 Makefile 的工程组织
  2. linux __setup
  3. NYOJ题目37-回文字符串
  4. 题目244-16进制的简单运算
  5. vs2017如何编程python_vs2017怎么编写python代码
  6. 计算机怎么登录用户名和密码忘了怎么办,如果我忘记了计算机的用户名和密码,该怎么办...
  7. 生成手写文字图片_如何把手机图片转成PDF文件?这个技巧你一定能学会!
  8. gprs发送消息给服务器,gprs发送到云服务器
  9. python可以替代java吗_Python 并非最好的编程语言,它无法取代 C/C++ 和 Java
  10. mate40升级鸿蒙系统教程,mate40鸿蒙系统怎么升级 教程如下