Android Drawable实践
前语
最近看源码、做事情有点累了,抽时刻看了看书,发现很多东西只是看过,却没有去实践,看了基本也就忘了,有些内容真好没那么复杂,就花了点零散时刻试试。
这篇文章是Android中Drawable的实践内容,从《Android开发艺术探究》的第六章下手的,这儿简略记录下。
BitmapDrawable
BitmapDrawable实际便是用来放图片的,下面是例子:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_launcher"
android:antialias="true"
android:dither="true"
android:filter="true"
android:gravity="fill_vertical|left"
android:mipMap="false"
android:tileMode="disabled"
/>
<!--
antialias 抗锯齿
dither 抖动效果,避免因像素适配问题导致的失真
filter 过滤作用,避免拉伸或压缩时影响显现作用
gravity 当图片尺度小于容器尺度时,对图片的定位作用
mipMap 纹理映射,避免远处图片失真
tileMode 平铺形式,和gravity抵触,有平铺repeat、镜像mirror、两头扩展
-->
用法也简略,给view的background设置上就行:
<TextView
android:id="@+id/bitmapDrawable"
android:text="BitmapDrawable"
android:background="@drawable/ic_drawable_bitmap"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
显现作用:
NinePatchDrawable
NinePatchDrawable和BitmapDrawable相似,需求留意的是Android Studio中只要png才干转成“.9”格局图片,NinePatchDrawable里边也不能访问mipmap的图片,需求复制到drawable里边去:
<nine-patch xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/ic_nine_patch"
android:dither="true"
/>
<!--
antialias 抗锯齿
dither 颤动作用,避免因像素适配问题导致的失真
filter 过滤作用,避免拉伸或压缩时影响显现作用
gravity 当图片尺度小于容器尺度时,对图片的定位作用
mipMap 纹理映射,避免远处图片失真
tileMode 平铺形式,和gravity抵触,有平铺repeat、镜像mirror、两头扩展
-->
用法相似:
<TextView
android:id="@+id/ninePatchDrawable"
android:text="NinePatchDrawable"
android:background="@drawable/ic_drawable_nine_patch"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
配置:
显现作用:
拉伸的很奇怪,不过没问题hh
ShapeDrawable
ShapeDrawable用的比较多吧,各种背景基本是这个,不多说:
<shape android:shape="rectangle"
xmlns:android="http://schemas.android.com/apk/res/android" >
<!-- 线 -->
<stroke
android:width="3dp"
android:color="@color/blue"
android:dashGap="1dp"
android:dashWidth="2dp"/>
<!-- 实心 -->
<solid
android:color="@color/gray"/>
<!-- 圆角 -->
<corners
android:topLeftRadius="5dp"
android:topRightRadius="10dp"
android:bottomRightRadius="15dp"
android:bottomLeftRadius="20dp"/>
<!-- 突变(和solid抵触) -->
<gradient
android:type="sweep"
android:centerY="50%"
android:centerX="25%"
android:startColor="@color/red"
android:centerColor="@color/yellow"
android:endColor="@color/purple"
/>
<padding
android:top="0dp"
android:left="30dp"
android:right="30dp"
android:bottom="20dp"/>
<size
android:width="300dp"
android:height="100dp"
/>
</shape>
运用:
<TextView
android:id="@+id/shapeDrawable"
android:text="ShapeDrawable"
android:background="@drawable/ic_drawable_shape"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
实际作用:
shape的几种类型(rectangle、oval、ring)和gradient的几种类型留意下,突变中心用百分比,其他问题不大。
LayerDrawable
LayerDrawable便是放多层item,仿照阴影还挺好用的:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 仿照输入框 -->
<!-- 全灰 -->
<item>
<shape android:shape="rectangle">
<solid android:color="@color/gray"/>
</shape>
</item>
<!-- 下面留一条灰线,其他全白 -->
<item android:bottom="30dp" >
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
</shape>
</item>
<!-- 左右留一点,嵌入底部灰线,中心全白 -->
<item android:bottom="15dp" android:left="15dp" android:right="15dp">
<shape android:shape="rectangle">
<solid android:color="@color/white"/>
</shape>
</item>
</layer-list>
运用:
<TextView
android:id="@+id/layerDrawable"
android:text="LayerDrawable"
android:background="@drawable/ic_drawable_layer"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
作用:
StateListDrawable
StateListDrawable便是selector标签,用的也挺多吧:
<selector xmlns:android="http://schemas.android.com/apk/res/android"
android:constantSize="false"
android:dither="true"
android:variablePadding="false">
<!-- constantSize,状况改变,size坚持不变(最大item尺度) -->
<!-- constantSize,状况改变,padding跟从改变,否则用最大padding -->
<!-- 各种状况,pressed、checked、focused、selected、enabled -->
<item android:state_pressed="true">
<shape>
<solid android:color="@color/gray"/>
</shape>
</item>
<item android:state_focused="true">
<shape>
<stroke android:width="3dp" android:color="@color/blue"/>
</shape>
</item>
<!-- 一般状况放最终 -->
<item>
<shape>
<stroke android:width="3dp" android:color="@color/gray"/>
</shape>
</item>
</selector>
运用,这儿要留意下TextView不处理点击事情:
<TextView
android:id="@+id/stateListDrawable"
android:text="StateListDrawable(press)"
android:background="@drawable/ic_drawable_state_list"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
android:clickable="true"
android:focusable="true"
tools:ignore="HardcodedText"
/>
实际作用:
LevelListDrawable
LevelListDrawable能够设置level,设置level后里边会改变:
<level-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:minLevel="0" android:maxLevel="0">
<shape>
<solid android:color="@color/gray"/>
</shape>
</item>
<item android:minLevel="1" android:maxLevel="2">
<shape>
<solid android:color="@color/yellow"/>
</shape>
</item>
<item android:minLevel="2" android:maxLevel="2">
<shape>
<solid android:color="@color/purple"/>
</shape>
</item>
<item android:minLevel="3" android:maxLevel="3">
<shape>
<solid android:color="@color/red"/>
</shape>
</item>
</level-list>
运用:
<TextView
android:id="@+id/levelListDrawable"
android:text="LevelListDrawable: current level = 0"
android:background="@drawable/ic_drawable_level_list"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 切换level
binding.levelListDrawable.setOnClickListener {
var level = binding.levelListDrawable.background.level
level = ++level % 5
binding.levelListDrawable.background.level = level
binding.levelListDrawable.text = "LevelListDrawable: current level = $level"
}
作用:
TransitionDrawable
TransitionDrawable有个突变作用:
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:top="50dp"
android:bottom="50dp"
android:left="100dp"
android:right="100dp"
>
<shape>
<stroke android:width="3dp" android:color="@color/gray"/>
</shape>
</item>
<item>
<shape>
<solid android:color="@color/gray"/>
</shape>
</item>
</transition>
运用:
<TextView
android:id="@+id/transitionDrawable"
android:text="TransitionDrawable(click)"
android:background="@drawable/ic_drawable_transition"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 发动transition
binding.transitionDrawable.setOnClickListener {
(binding.transitionDrawable.background as TransitionDrawable).startTransition(1500)
}
实际作用:
InsertDrawable
InsertDrawable便是能包含其他drawable,供给一个padding作用:
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:insetTop="20dp"
android:insetBottom="40dp"
android:insetLeft="10dp"
android:insetRight="30dp">
<shape>
<stroke android:width="3dp" android:color="@color/gray"/>
</shape>
</inset>
运用:
<TextView
android:id="@+id/insertDrawable"
android:text="InsertDrawable"
android:background="@drawable/ic_drawable_insert"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
实际作用:
ScaleDrawable
ScaleDrawable便是会依据level缩放的drawable:
<scale xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:scaleGravity="center"
android:scaleWidth="75%"
android:scaleHeight="75%"
>
<shape>
<solid android:color="@color/gray"/>
</shape>
</scale>
运用:
<TextView
android:id="@+id/scaleDrawable"
android:text="ScaleDrawable: current level = 0"
android:background="@drawable/ic_drawable_scale"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 设置缩放
binding.scaleDrawable.setOnClickListener {
var level = binding.scaleDrawable.background.level
level = (level + 1000) % 10000
binding.scaleDrawable.background.level = level
binding.scaleDrawable.text = "ScaleDrawable: current level = $level"
}
实际作用:
ClipDrawable
ClipDrawable会依据level裁切:
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="vertical"
android:gravity="center"
android:drawable="@drawable/ic_launcher"
>
</clip>
运用:
<TextView
android:id="@+id/clipDrawable"
android:text="ClipDrawable: current level = 0"
android:background="@drawable/ic_drawable_clip"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 设置裁切
binding.clipDrawable.setOnClickListener {
var level = binding.clipDrawable.background.level
level = (level + 1000) % 10000
binding.clipDrawable.background.level = level
binding.clipDrawable.text = "ClipDrawable: current level = $level"
}
实际作用:
CustomDrawable
这儿我自己写了一个Drawable,将就看下吧:
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.ColorFilter
import android.graphics.Paint
import android.graphics.PixelFormat
import android.graphics.drawable.Drawable
class CustomStarDrawable: Drawable() {
private val mPaint: Paint = Paint()
init {
mPaint.strokeWidth = 5f
mPaint.flags = Paint.ANTI_ALIAS_FLAG
mPaint.style = Paint.Style.FILL
mPaint.color = Color.GRAY
}
override fun draw(canvas: Canvas) {
// 绘制圆圈
val num = level / 2000
val radius = (bounds.bottom - bounds.top) / 4f
val distance = (bounds.right - bounds.left) / 5f
when(num) {
1 -> mPaint.color = Color.RED
2 -> mPaint.color = Color.YELLOW
3 -> mPaint.color = Color.BLUE
4 -> mPaint.color = Color.GREEN
else -> mPaint.color = Color.GRAY
}
// canvas.drawRect(bounds, mPaint)
for (i in 0 until num) {
canvas.drawCircle(distance * i + radius, 2 * radius, radius, mPaint)
}
}
override fun setAlpha(alpha: Int) {
mPaint.alpha = alpha
invalidateSelf()
}
override fun setColorFilter(colorFilter: ColorFilter?) {
mPaint.colorFilter = colorFilter
invalidateSelf()
}
@Deprecated("Deprecated in Java",
ReplaceWith("PixelFormat.TRANSLUCENT", "android.graphics.PixelFormat")
)
override fun getOpacity(): Int {
return PixelFormat.TRANSLUCENT
}
// 默许巨细
override fun getIntrinsicWidth(): Int {
return 500
}
override fun getIntrinsicHeight(): Int {
return 100
}
}
运用:
<TextView
android:id="@+id/customDrawable"
android:text="CustomDrawable: current level = 0"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 设置自定义drawable
binding.customDrawable.background = CustomStarDrawable()
binding.customDrawable.setOnClickListener {
var level = binding.customDrawable.background.level
level = (level + 2000) % 10000
binding.customDrawable.background.level = level
binding.customDrawable.text = "CustomDrawable: current level = $level"
}
实际作用:
RippleDrawable
RippleDrawable水波纹作用,很多点击会用到(留意V21):
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/blue"
android:radius="100dp"
/>
<!-- color,有必要,涟漪的色彩 -->
<!-- radius,涟漪最大的半径 -->
运用:
<TextView
android:id="@+id/rippleDrawable"
android:text="RippleDrawable(click)"
android:background="@drawable/ic_drawable_ripple"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
android:clickable="true"
android:focusable="true"
tools:ignore="HardcodedText"
/>
作用:
RotateDrawable
RotateDrawable旋转的,没什么好说的,也和level有关:
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/ic_launcher"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="180"
android:visible="true"
/>
运用:
<TextView
android:id="@+id/rotateDrawable"
android:text="RotateDrawable: current level = 0"
android:background="@drawable/ic_drawable_rotate"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
tools:ignore="HardcodedText"
/>
代码:
// 设置旋转drawable
binding.rotateDrawable.setOnClickListener {
var level = binding.rotateDrawable.background.level
level = (level + 2000) % 10000
binding.rotateDrawable.background.level = level
binding.rotateDrawable.text = "RotateDrawable: current level = $level"
}
实际作用:
AnimateStateListDrawable
AnimateStateListDrawable便是selector加动画,相似的还有好多个,能够加帧动画或者vector动画,下面我就简略试了下(留意v21):
<?xml version="1.0" encoding="utf-8"?>
<animated-selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 开启状况 -->
<item
android:id="@+id/state_on"
android:state_pressed="true">
<shape>
<solid android:color="@color/blue"/>
</shape>
</item>
<!-- 封闭状况 -->
<item
android:id="@+id/state_off"
android:state_pressed="false">
<shape>
<stroke android:width="3dp" android:color="@color/gray"/>
</shape>
</item>
<!-- 封闭切换到开启的帧动画 -->
<transition
android:fromId="@id/state_off"
android:toId="@id/state_on">
<animation-list>
<item android:duration="200">
<shape><solid android:color="#000000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#220000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#440000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#660000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#880000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#AA0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#CC0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#EE0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#FF0000FF"/> </shape>
</item>
</animation-list>
</transition>
<!-- 开启切换到封闭的动画 -->
<transition
android:fromId="@id/state_on"
android:toId="@id/state_off">
<animation-list>
<item android:duration="200">
<shape><solid android:color="#FF0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#EE0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#CC0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#AA0000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#880000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#660000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#440000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#220000FF"/> </shape>
</item>
<item android:duration="200">
<shape><solid android:color="#000000FF"/> </shape>
</item>
</animation-list>
</transition>
</animated-selector>
运用:
<TextView
android:id="@+id/animateStateListDrawable"
android:text="AnimateStateListDrawable(press)"
android:background="@drawable/ic_drawable_animate_state_list"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_margin="5dp"
android:clickable="true"
android:focusable="true"
tools:ignore="HardcodedText"
/>
实际作用:
其他
好像还有其他几个,adaptive-icon、animated-rotate、animated-vector、animation-list,animated的都相似,后边有时刻搞下动画,试试vector动画,adaptive-icon好像是和app图标相关的,用到再看。
小结
这儿花了点时刻,试了下各种drawable的运用作用,有的有状况,有的和level相关,有的合作动画,还挺有意思,也自定义了一个依据level增加圆圈的drawable,又学习了!
8点11,下班!