8. ScaleDrawable
ScaleDrawable
對(duì)應(yīng)于<scale>
標(biāo)簽,它可以根據(jù)自己的等級(jí)將指定的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
, 縮放的時(shí)候就會(huì)向頂部靠攏,bottom
, 縮放時(shí)會(huì)向底部靠攏; -
android:scaleHeight:
表示Drawable
能夠在高度上縮放的百分比, 比如: 50%, -
android:scaleWidth:
表示Drawable
能夠在寬度上縮放的百分比, 同上;
ScaleDrawable
的縮放,并不是自動(dòng)的建立在原有Drawable
尺寸的基礎(chǔ)上的笼吟。而是咐鹤,需要給原有的Drawable
指定一個(gè)Level
,然后ScaleDrawable
是在這個(gè)Level
的基礎(chǔ)上進(jìn)行縮放的G群恕谓传!
更加坑爹的事情是,在設(shè)置百分比的時(shí)候芹关,設(shè)置的值是縮小的比例续挟。也就是說(shuō),設(shè)置0.1侥衬,意為縮小10%J觥!而不是原始大小的10%V嶙堋直颅!
ScaleDrawable
不能單獨(dú)的使用, 他需要配合Level
等級(jí)使用, level
的取值是0~10000
, (0為不可見(jiàn))
<?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);
}
});
先來(lái)理清下View
的寬高, Drawable
的寬高, 可縮放的百分比,Level
等級(jí)三者間的關(guān)系: 一個(gè)個(gè)來(lái)說(shuō):
-
View
的寬高: 在整個(gè)過(guò)程中是不會(huì)發(fā)生變化的; - 可縮放的百分比: 先搞清楚這個(gè)百分比, 它是控件能夠縮小的最小尺寸, 比如:
10%
, 表示Drawable
最小能縮小到控件的10%
寬或者高, 這時(shí)候還需要加上一個(gè)level
等級(jí) -
Level
等級(jí):取值是0~10000
; 上面Drawable
能放大或縮小的區(qū)間是10%~100%
, 這個(gè)區(qū)間就是用0~10000
是描述. 它們和縮放后的寬高存在一個(gè)等式:
縮放后的寬高 = Drawable顯示的寬高(大多時(shí)候是View的寬高) - Drawable顯示的寬高(大多時(shí)候是View的寬高) * 可縮放的百分比 * (設(shè)置的Level/10000);
9. ClipDrawable
ClipDrawable
對(duì)應(yīng)于<clip>
標(biāo)簽,它可以根據(jù)自己當(dāng)前的等級(jí)(level)
來(lái)裁剪另一個(gè)Drawable
怀樟,裁剪方向可以通過(guò)android:clipOrientation
和android:gravity
這兩個(gè)屬性來(lái)共同控制功偿。其中
clipOrientation
表示裁剪方向,有水平和豎直兩個(gè)方向往堡,gravity
比較復(fù)雜械荷,需要和clipOrientation
一起才能發(fā)揮作用。在XML中設(shè)置
<?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
的等級(jí)(level)
是有范圍的虑灰,即0~10000
吨瞎,最小等級(jí)是0
,最大等級(jí)是10000
穆咐,對(duì)于ClipDrawable
來(lái)說(shuō)颤诀,等級(jí)0
表示完全裁剪字旭,即整個(gè)Drawable
都不可見(jiàn)了,而等級(jí)10000
表示不裁剪崖叫。在上面的代碼中遗淳,將等級(jí)設(shè)置為8000
,表示裁剪了2000
心傀,即在底部裁減掉20%
的區(qū)域洲脂,被裁減的區(qū)域就相當(dāng)于不存在了。
等級(jí)越大剧包,表示裁剪的區(qū)域越小恐锦,因此等級(jí)10000
表示不裁剪,這個(gè)時(shí)候整個(gè)圖片都可以完全顯示出來(lái)疆液;而等級(jí)0
則表示裁剪全部區(qū)域一铅,這個(gè)時(shí)候整個(gè)圖片將不可見(jiàn)。另外裁剪效果還受裁剪方向和gravity
屬性的影響堕油。
10. 自定義Drawable
Drawable
的使用范圍很單一潘飘,一個(gè)是作為ImageView
中的圖像來(lái)顯示,另外一個(gè)就是作為View
的背景掉缺,大多數(shù)情況下Drawable
都是以View
的背景這種形式出現(xiàn)的卜录。
通常我們沒(méi)有必要去自定義 Drawable
,這是因?yàn)樽远x的Drawable
無(wú)法在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);
getIntrinsicWidth
和getIntrinsicHeight
這兩個(gè)方法需要注意一下,當(dāng)自定義的Drawable
有固定大小時(shí)最好重寫(xiě)這兩個(gè)方法搜囱,因?yàn)樗鼤?huì)影響到View
的wrap_content
布局丑瞧。
Drawable
的實(shí)際大小可以通過(guò)它的getBounds
方法來(lái)得到。