美文网首页面试
第六章(3) Android中的Drawable

第六章(3) Android中的Drawable

作者: 努力生活的西鱼 | 来源:发表于2018-07-16 14:25 被阅读68次

    8. ScaleDrawable

    ScaleDrawable对应于<scale>标签,它可以根据自己的等级将指定的Drawable缩放到一定比例。

    Amy_LuLu__的图
    <?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:clipOrientationandroid: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的图

    getIntrinsicWidthgetIntrinsicHeight这两个方法需要注意一下,当自定义的Drawable有固定大小时最好重写这两个方法,因为它会影响到Viewwrap_content布局。
    Drawable的实际大小可以通过它的getBounds方法来得到。

    相关文章

      网友评论

        本文标题:第六章(3) Android中的Drawable

        本文链接:https://www.haomeiwen.com/subject/arhbpftx.html