Android图形图像相关小知识点整理
Posted xiaoqiang_0719
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android图形图像相关小知识点整理相关的知识,希望对你有一定的参考价值。
文章目录
TransitionDrawable
定义两个Drawable之间渐变过渡,A->B(startTransition) ,B->A(reverseTransition)
方式 1:
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/back_local_hdd_cover"/>
<item android:drawable="@drawable/back_local_bt_cover"/>
</transition>
方式 2:
val arrayDrawable= arrayOf(
ResourcesCompat.getDrawable(resources, R.drawable.back_local_hdd_cover, null),
ResourcesCompat.getDrawable(resources, R.drawable.back_local_bt_cover, null)
)
val transitionDrawable = TransitionDrawable(arrayDrawable)
private fun newTransactionDrawable() {
setContentView(R.layout.activity_drawable)
val transition = ResourcesCompat.getDrawable(
resources,
R.drawable.expand_collapse,
null
) as TransitionDrawable
iv_drawable.apply {
setImageDrawable(transition)
contentDescription = resources.getString(R.string.app_name)
}.setOnClickListener {
isChecked = if (!isChecked) {
transition.startTransition(1000)
true
} else {
transition.reverseTransition(1000)
false
}
}
}
ShapeDrawable
动态绘制二维图形
class CustomDrawableView(context: Context) : View(context) {
private val drawable: ShapeDrawable = run {
val x = 100
val y = 100
val width = 300
val height = 300
val shape: ShapeDrawable = 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)
}
shape
}
override fun onDraw(canvas: Canvas) {
drawable.draw(canvas)
}
}
xml中定义shape图片,只需要记住一些关键属性即可,可以查阅属性文档 AndroidDeveloper的Shape属性文档
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="10dp" />
<stroke
android:width="10dp"
android:color="@color/color_pink"
android:dashWidth="6dp"
android:dashGap="6dp" />
<gradient
android:angle="90"
android:centerColor="@color/reply_red_200"
android:centerX="0.7"
android:centerY="0.7"
android:endColor="@color/white"
android:startColor="@color/color_pink" />
<padding
android:left="100dp"
android:right="100dp" />
</shape>
Tint给图片着色
对图片进行着色,一般使用在Icon中使用(背景透明的图标)只会给有色值的图标部分着色,可以在代码中使用 setTint()
方法对 BitmapDrawable
、NinePatchDrawable
或 VectorDrawable
对象着色
经过tint着色之后:
<ImageView
android:id="@+id/repeat_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:contentDescription="@string/app_name"
android:src="@drawable/ic_repeat_round"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:tint="@color/color_pink"
tools:ignore="UnusedAttribute" />
tint有以下几种模式,一般使用默认模式(src_in)即可
<attr name="tintMode">
<!-- The tint is drawn on top of the drawable.
[Sa + (1 - Sa)*Da, Rc = Sc + (1 - Sa)*Dc] -->
<enum name="src_over" value="3" />
<!-- The tint is masked by the alpha channel of the drawable. The drawable’s
color channels are thrown out. [Sa * Da, Sc * Da] -->
<enum name="src_in" value="5" />
<!-- The tint is drawn above the drawable, but with the drawable’s alpha
channel masking the result. [Da, Sc * Da + (1 - Sa) * Dc] -->
<enum name="src_atop" value="9" />
<!-- Multiplies the color and alpha channels of the drawable with those of
the tint. [Sa * Da, Sc * Dc] -->
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
<!-- Combines the tint and drawable color and alpha channels, clamping the
result to valid color values. Saturate(S + D) -->
<enum name="add" value="16" />
</attr>
private fun newTintDrawable() {
//1、xml使用
setContentView(R.layout.activity_tint)
//2、代码中对ImageView使用
repeat_shuffle.imageTintList =
ColorStateList.valueOf(ContextCompat.getColor(this, R.color.color_pink))
repeat_shuffle.imageTintMode = PorterDuff.Mode.SRC_IN
repeat_shuffle.setImageResource(R.drawable.ic_repeat_shuffle_round)
//3、BitmapDrawable使用
val rawBitmap = BitmapFactory.decodeResource(
resources,
R.drawable.ic_repeat_shuffle_round
)
val drawable: Drawable = BitmapDrawable(rawBitmap)
drawable.setTint(ResourcesCompat.getColor(resources, R.color.color_pink, null))
repeat_shuffle.setImageDrawable(drawable)
//4、TransitionDrawable使用
val arrayDrawable = arrayOf(
ResourcesCompat.getDrawable(resources, R.drawable.ic_repeat_shuffle_round, null),
ResourcesCompat.getDrawable(resources, R.drawable.ic_repeat_round, null)
)
val transitionDrawable = TransitionDrawable(arrayDrawable)
transitionDrawable.setTintMode(PorterDuff.Mode.SRC_IN)
transitionDrawable.setTint(ResourcesCompat.getColor(resources, R.color.color_pink, null))
repeat_shuffle.setImageDrawable(transitionDrawable)
}
Palette提取图片颜色
我们需要通过一个Bitmap对象来生成一个对应的Palette对象。调用generate()以同步的方式生成Palette,或者generate(object :Palette.PaletteAsyncListener )以异步的方式生成Palette
// 同步generate()方式获取
val palette = Palette.from(rawBitmap).generate()
val darkVibrantColor = palette.getDarkVibrantColor(Color.BLACK)
iv_palette.setBackgroundColor(darkVibrantColor)
// 异步generate()方式获取
Palette.from(rawBitmap).generate { palette ->
if (palette != null) {
iv_palette2.setBackgroundColor(palette.getDarkVibrantColor(Color.BLACK))
}
}
得到Palette对象后,就可以拿到提取到的颜色值
● Palette.getVibrantSwatch() (有活力的)
● Palette.getDarkVibrantSwatch() (有活力的 暗色)
● Palette.getLightVibrantSwatch() (有活力的 亮色)
● Palette.getMutedSwatch() (柔和的)
● Palette.getDarkMutedSwatch() (柔和的 暗色)
● Palette.getLightMutedSwatch() (柔和的 亮色)
● Palette.getDominantSwatch() (占优势的颜色)
以上方法都有对应的getColor()方法,例如: **getDominantColor(@ColorInt int defaultColor) **
一般使用getDominantColor便可拿到优势色值
如需访问Palette中的所有颜色,可以使用 getSwatches()
方法返回从图片生成的所有色样的列表,包括标准的六种颜色配置文件
VectorDrawable
VectorDrawable 定义静态可绘制对象,由 path
和 group
对象构成
<!-- res/drawable/battery_charging.xml -->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
<!-- intrinsic size of the drawable -->
android:height="24dp"
android:width="24dp"
<!-- size of the virtual canvas -->
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<group
android:name="rotationGroup"
android:pivotX="10.0"
android:pivotY="10.0"
android:rotation="15.0" >
<path
android:name="vect"
android:fillColor="#FF000000"
android:pathData="M15.67,4H14V2h-4v2H8.33C7.6,4 7,4.6 7,5.33V9h4.93L13,7v2h4V5.33C17,4.6 16.4,4 15.67,4z"
android:fillAlpha=".3"/>
<path
android:name="draw"
android:fillColor="#FF000000"
android:pathData="M13,12.5h2L11,20v-5.5H9L11.93,9H7v11.67C7,21.4 7.6,22 8.33,22h7.33c0.74,0 1.34,-0.6 1.34,-1.33V9h-4v3.5z"/>
</group>
</vector>
AnimatedVectorDrawable
可为矢量图形的属性添加动画,可以将添加动画效果之后的矢量图形定义为三个单独的资源文件,也可以将其定义为可定义整个可绘制对象的单个 XML 文件
多个 XML 文件
-
VectorDrawable
XML 文件 -
AnimatedVectorDrawable
XML 文件,用于定义目标VectorDrawable
、要添加动画效果的目标路径和组、属性 -
定义为
ObjectAnimator
或AnimatorSet
对象的动画文件AnimatedVectorDrawable 的 XML 文件 <animated-vector xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/vd" > <target android:name="rotationGroup" android:animation="@anim/rotation" /> <target android:name="vectorPath" android:animation="@anim/path_morph" /> </animated-vector>
单个 XML 文件
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android" xmlns:aapt="http://schemas.android.com/aapt"> <aapt:attr name="android:drawable"> <vector android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:name="root" android:strokeWidth="2" android:strokeLineCap="square" android:strokeColor="?android:colorControlNormal" android:pathData="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7" /> </vector> </aapt:attr> <target android:name="root"> <aapt:attr name="android:animation"> <objectAnimator android:propertyName="pathData" android:valueFrom="M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7" android:valueTo="M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4" android:duration="300" android:interpolator="@android:interpolator/fast_out_slow_in" android:valueType="pathType" /> </aapt:attr> </target> </animated-vector>
矢量图标的优点
1、矢量图的主要优势在于图片可缩放。可以在不降低显示质量的情况下缩放图片,也就是说,可以针对不同的屏幕密度调整同一文件的大小,而不会降低图片质量。
2、不仅能缩减 APK 文件大小,还能减少开发者维护工作。
3、矢量图是以xml语言来描述的,所以它修改自如。
矢量图标的缺点
对cpu的消耗,图片越大绘制占用的cpu资源越多,官方建议不超过200dp*200dp
官方建议
-
矢量可绘制对象可伸缩,不会失去定义,是单色应用内图标的理想之选。
-
尽管矢量可绘制对象确实支持一种或多种颜色,但在很多情况下,最好将图标颜色设置为黑色通过对可绘制对象进行着色,可以将位图定义为透明遮罩,并在运行时用一种颜色对其进行着色。(Tint)
-
颜色提取用于自动从位图图片中提取突出颜色。(palette)
-
LayerDrawable
使用标签< layer-list> + item,实现叠加效果,可以由多个Drawable的叠加生成一个Drawable,可以减少不必要的代码层级,图二的叠加效果需要在父层级设置android:clipChildren=“false”
上图阴影效果如下:
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:left="6dp"
android:top="6dp">
<shape android:shape="rectangle">
<solid android:color="#1A000000" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"
android:topLeftRadius="6dip"
android:topRightRadius="6dip" />
</shape>
</item>
<item
android:bottom="10dp"
android:right="10dp">
<shape android:shape="rectangle">
<solid android:color="#f46464" />
<corners
android:bottomLeftRadius="6dip"
android:bottomRightRadius="6dip"
android:topLeftRadius="6dip"
android:topRightRadius="6dip" />
</shape>
</item>
</layer-list>
Demo示例
参考文献
Google官方地址:https://developer.android.google.cn/guide/topics/graphics/drawables
以上是关于Android图形图像相关小知识点整理的主要内容,如果未能解决你的问题,请参考以下文章
Flutterflutter doctor 报错Android license status unknown. Run `flutter doctor --android-licenses‘(代码片段