8. ScaleDrawable
ScaleDrawable
对应于<scale>
标签,它可以根据自己的等级将指定的Drawable
缩放到一定比例。
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/drawable_resource"
android:scaleGravity=["top" | "bottom" | "left" | "right" |
"center_vertical" | "fill_vertical" | "center_horizontal" |
"fill_horizontal" | "center" | "fill" | "clip_vertical" |
"clip_horizontal"]
android:scaleHeight="percentage"
android:scaleWidth="percentage" />
-
android:scaleGravity:
缩放的方向, 比如:top
, 缩放的时候就会向顶部靠拢,bottom
, 缩放时会向底部靠拢; -
android:scaleHeight:
表示Drawable
能够在高度上缩放的百分比, 比如: 50%, -
android:scaleWidth:
表示Drawable
能够在宽度上缩放的百分比, 同上;
ScaleDrawable
的缩放,并不是自动的建立在原有Drawable
尺寸的基础上的。而是,需要给原有的Drawable
指定一个Level
,然后ScaleDrawable
是在这个Level
的基础上进行缩放的!!
更加坑爹的事情是,在设置百分比的时候,设置的值是缩小的比例。也就是说,设置0.1,意为缩小10%!!而不是原始大小的10%!!
ScaleDrawable
不能单独的使用, 他需要配合Level
等级使用, level
的取值是0~10000
, (0为不可见)
<?xml version="1.0" encoding="utf-8"?>
<scale
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@android:color/holo_green_dark"
android:scaleGravity="left"
android:scaleWidth="30%"
android:scaleHeight="30%">
</scale>
作为背景使用
<TextView
android:id="@+id/tv"
android:layout_width="300dp"
android:layout_height="300dp"
android:text="Hello World!"
android:gravity="center"
android:clickable="true"
android:background="@drawable/scale_drawable"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
在Java中使用
tv = findViewById(R.id.tv);
final ScaleDrawable scaleDrawable = (ScaleDrawable) tv.getBackground();
scaleDrawable.setLevel(0); // 不显示
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scaleDrawable.setLevel(5000);
}
});
先来理清下View
的宽高, Drawable
的宽高, 可缩放的百分比,Level
等级三者间的关系: 一个个来说:
-
View
的宽高: 在整个过程中是不会发生变化的; - 可缩放的百分比: 先搞清楚这个百分比, 它是控件能够缩小的最小尺寸, 比如:
10%
, 表示Drawable
最小能缩小到控件的10%
宽或者高, 这时候还需要加上一个level
等级 -
Level
等级:取值是0~10000
; 上面Drawable
能放大或缩小的区间是10%~100%
, 这个区间就是用0~10000
是描述. 它们和缩放后的宽高存在一个等式:
缩放后的宽高 = Drawable显示的宽高(大多时候是View的宽高) - Drawable显示的宽高(大多时候是View的宽高) * 可缩放的百分比 * (设置的Level/10000);
9. ClipDrawable
ClipDrawable
对应于<clip>
标签,它可以根据自己当前的等级(level)
来裁剪另一个Drawable
,裁剪方向可以通过android:clipOrientation
和android:gravity
这两个属性来共同控制。其中
clipOrientation
表示裁剪方向,有水平和竖直两个方向,gravity
比较复杂,需要和clipOrientation
一起才能发挥作用。gravity属性
在XML中设置
<?xml version="1.0" encoding="utf-8"?>
<clip
xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/circle"
android:clipOrientation="vertical"
android:gravity="bottom">
</clip>
在布局中使用
<ImageView
android:id="@+id/imageView"
android:layout_width="384dp"
android:layout_height="511dp"
android:src="@drawable/drawable_clip"/>
在Java中使用
imageView = findViewById(R.id.imageView);
clipDrawable = (ClipDrawable) imageView.getDrawable();
clipDrawable.setLevel(5000);
Drawable
的等级(level)
是有范围的,即0~10000
,最小等级是0
,最大等级是10000
,对于ClipDrawable
来说,等级0
表示完全裁剪,即整个Drawable
都不可见了,而等级10000
表示不裁剪。在上面的代码中,将等级设置为8000
,表示裁剪了2000
,即在底部裁减掉20%
的区域,被裁减的区域就相当于不存在了。
等级越大,表示裁剪的区域越小,因此等级10000
表示不裁剪,这个时候整个图片都可以完全显示出来;而等级0
则表示裁剪全部区域,这个时候整个图片将不可见。另外裁剪效果还受裁剪方向和gravity
属性的影响。
10. 自定义Drawable
Drawable
的使用范围很单一,一个是作为ImageView
中的图像来显示,另外一个就是作为View
的背景,大多数情况下Drawable
都是以View
的背景这种形式出现的。
通常我们没有必要去自定义 Drawable
,这是因为自定义的Drawable
无法在XML
中使用,这就降低了Drawable
的使用范围。
public class CustomDrawable extends Drawable{
private Paint mPaint;
public CustomDrawable(int color) {
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(color);
}
@Override
public void draw(@NonNull Canvas canvas) {
final Rect rect = getBounds();
float cx = rect.exactCenterX();
float cy = rect.exactCenterY();
canvas.drawCircle(cx,cy,Math.min(cx,cy),mPaint);
}
@Override
public void setAlpha(int alpha) {
mPaint.setAlpha(alpha);
invalidateSelf();
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
mPaint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
在Java中
imageView2 = findViewById(R.id.imageView2);
CustomDrawable drawable = new CustomDrawable(R.color.colorPrimary);
imageView2.setImageDrawable(drawable);
借用开心wonderful的图
getIntrinsicWidth
和getIntrinsicHeight
这两个方法需要注意一下,当自定义的Drawable
有固定大小时最好重写这两个方法,因为它会影响到View
的wrap_content
布局。
Drawable
的实际大小可以通过它的getBounds
方法来得到。
网友评论