通过ClipDrawable 实现茶杯注满效果

本文介绍了一种使用ClipDrawable实现页面加载注满效果的方法,通过一个自定义的ImageView展示了一个空杯子逐渐注满的过程。

一、概述

相信大家都见过页面加载时的注满效果,就是一个空杯子到注满水的这个过程。想到这个可以通过ImageView的ClipDrawable来简单的实现。

二、效果图



三、实现步骤

(一)首先是主布局文件activity_main.xml

其中只有一个继承自FrameLayout的自定义控件,用来记载这个杯子的ImageView。代码:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.junjie.clipdrawable.FillTeaupView
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</RelativeLayout>

(二)MainActivity.java

这个类很简单,只用来记载这个布局就行。
public class MainActivity extends Activity {
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
	}
}

(三)FillTeaupView.java

最主要就是FillTeaupView这个自定义控件,其实这个控件就是一个ImageView,通过得到ImageView的ClipDrawable,然后根据ImageView的背景与前景,来做动态的变化。代码:
public class FillTeaupView extends FrameLayout {

	private static final int MAX_PROGRESS = 10000;
	// ClipDrawable代表从其它位图上截取一个“图片片段”
	private ClipDrawable mClipDrawable;
	private int mProgress = 0;
	private boolean running;
	private Handler handler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			// 如果消息是本程序发送的
			if (msg.what == 88) {
				// 设置截取的区域大小,当level为0时,截取的图片片段为空;当level为10000时,截取整张图片
				// 可以使用ClipDrawable的这种性质控制截取图片的区域大小,让程序不断调用setLevel方法并改变level的值,达到让图片慢慢展开的效果。
				mClipDrawable.setLevel(mProgress);
			}
		}
	};
	
	public FillTeaupView(Context context) {
		this(context, null, 0);
	}

	public FillTeaupView(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public FillTeaupView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		init(context);
	}

	private void init(Context context) {
		View view = LayoutInflater.from(context).inflate(R.layout.custom_loading, null);
		addView(view);
		ImageView imageView = (ImageView) findViewById(R.id.iv_progress);
		// 得到imageView的ClipDrawable
		mClipDrawable = (ClipDrawable) imageView.getDrawable();
		
		// 开启一个子线程
		Thread s = new Thread(r);
		s.start();
	}

	public void stop() {
		mProgress = 0;
		running = false;
	}

	Runnable r = new Runnable() {
		@Override
		public void run() {
			running = true;
			// 使用循环来动态改变状态
			while (running) { 
				handler.sendEmptyMessage(88);
				// 注满后保持这个状态,结束循环
				if (mProgress >= MAX_PROGRESS) {
					mProgress = MAX_PROGRESS;
					running = false;
					//stop();
				}
				mProgress += 100;
				try {
					Thread.sleep(40); // 为了模拟耗时操作
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	};
}

(四)custom_loading.xml

自定义控件的布局就是一个ImageView,背景background图片为:



想必大家也猜到了前景src图片的样式:



两者完全重叠可以实现注满,前景图慢慢出现就可以实现注入的动作了。布局代码:

<?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="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:background="@drawable/loading_bg"
    android:paddingLeft="3dp"
    android:paddingTop="3dp"
    android:scaleType="centerInside"
    android:src="@drawable/clip_imageview" />

<!-- background为背景图
	 src为前景图
	  我们需要不断改变的是前景图,这样背景图动态就能显示出来了 -->

(五)clip_imageview.xml

clip属性也是很重要的,主要设置前景图的截取方式。代码:
<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
    android:clipOrientation="vertical"
    android:drawable="@drawable/loading_progress"
    android:gravity="bottom" >

    <!-- android:clipOrientation:指定截取的方向,可设置为水平截取或垂直截取
    	 android:drawable:指定截取的源Drawable对象
		 android:gravity:指定截取时的对齐方式 -->
</clip>

至此,实现注满效果的例子就实现了。最后附上Demo下载地址:http://download.youkuaiyun.com/detail/xiaoli100861/9187207

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值