Android中ClipDrawable的使用和自定义ProgressBar

简介

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
<?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>
资源文件yx_clipprogress_clip_xml.xml
<?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.png
yx_clipprogress_loading.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值