简介
ClipDrawable 对一个Drawable进行剪切操作,可控制这个Drawable的剪切区域,以及相对容器的对齐方式,它根据level值决定剪切区域的大小。官方文档说明,level的范围大小为0-10000,0表示完全不显示,10000表示完全显示,通过ClipDrawable提供的setLevel(int level)方法来设置剪切区域。
XML配置
ClipDrawable可通过XML进行配置
<!-- clip 定义这是个ClipDrawable,必须作为根元素 android:drawable 表示该ClipDrawable引用的drawable资源(必须) android:clipOrientation 裁剪的方向 android:gravity 指定从哪个位置裁剪(多个值之间用“|”分隔) top:从下向上剪切 bottom:从上向下剪切 。。。。 --> <?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:gravity="flag" android:clipOrientation=["horizontal" | "vertical"] android:drawable="reference" > </clip>
简单应用
用ClipDrawable的xml配置,简单编写一个自定义的Progress。效果图
源码
控件的布局文件yx_clipprogress_layout.xml资源文件yx_clipprogress_clip_xml.xml<?xml version="1.0" encoding="utf-8"?> <ImageView xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/iv_progress" android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center" android:background="@drawable/yx_clipprogress_bg" android:scaleType="centerInside" android:src="@drawable/yx_clipprogress_clip_xml" > </ImageView>
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:clipOrientation="vertical" android:gravity="bottom" android:drawable="@drawable/yx_clipprogress_loading" > </clip>
属性配置文件 attrs.xml<declare-styleable name="YXClipProgress"> <attr name="autoRuning" format="boolean"/> <attr name="progress" format="integer"/> </declare-styleable>
自定义控件类package com.example.ztest2; import java.lang.ref.WeakReference; import android.content.Context; import android.content.res.TypedArray; import android.graphics.drawable.ClipDrawable; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.FrameLayout; import android.widget.ImageView; public class YXClipProgress extends FrameLayout{ /** * ClipDrawable-level的最大值,范围在0-10000之间,0 不显示,10000充分显示 * 可以类比progress 即progress = MAX_PROGRESS/100; */ private static final int MAX_PROGRESS = 10000; /* 是否自动增加进度 */ private boolean auto_runing; private static final int MESSAGE_WHAT = 0x123456; private ClipDrawable mClipDrawable; private int mProgress; private PHandler handler = null; /** * 设置进度值 * @param progress 进度值0-100 */ public void setYXProgress(int progress){ auto_runing = false; handler.sendEmptyMessage(MESSAGE_WHAT); this.mProgress = (progress * 100); } /** * stop */ public void stop(){ mProgress = 0; auto_runing = false; } public YXClipProgress(Context context) { this(context,null); // TODO Auto-generated constructor stub } public YXClipProgress(Context context, AttributeSet attrs) { this(context, attrs,0); // TODO Auto-generated constructor stub } public YXClipProgress(Context context, AttributeSet set, int defStyle) { super(context, set, defStyle); // TODO Auto-generated constructor stub customInitAttribute(context,set,0); initThread(context); } private void initThread(Context context) { // TODO Auto-generated method stub new Thread(new Runnable() { @Override public void run() { while(auto_runing){ handler.sendEmptyMessage(MESSAGE_WHAT); if(mProgress>MAX_PROGRESS){ mProgress = 0; } mProgress += 100; try { Thread.sleep(50); } catch (Exception e) { e.printStackTrace(); } } } }).start(); } private void customInitAttribute(Context context, AttributeSet set, int defStyle) { /*开启Handler*/ handler = new PHandler(this); /* 配置属性值 */ TypedArray a = context.obtainStyledAttributes(set,R.styleable.YXClipProgress); auto_runing = a.getBoolean(R.styleable.YXClipProgress_autoRuning, false); mProgress = a.getInt(R.styleable.YXClipProgress_progress, 0) * 100; a.recycle(); /* inflate */ View view = LayoutInflater.from(context).inflate(R.layout.yx_clipprogress_layout, null); addView(view); ImageView imageView = (ImageView) findViewById(R.id.iv_progress); mClipDrawable = (ClipDrawable) imageView.getDrawable(); mClipDrawable.setLevel(mProgress); } private static class PHandler extends Handler{ WeakReference<YXClipProgress> mp; PHandler(YXClipProgress a){ mp = new WeakReference<YXClipProgress>(a); } @Override public void handleMessage(Message msg) { YXClipProgress t = mp.get(); if(msg.what == MESSAGE_WHAT){ t.mClipDrawable.setLevel(t.mProgress); } } } }
此控件类关键在于处理消息部分中的setLevel。
附件图片
yx_clipprogress_bg.pngyx_clipprogress_loading.png