ClipDrawable使用

本文介绍了Android中ClipDrawable的应用,这是一种可以根据level值剪切原始Drawable对象的工具。文章通过实例展示了如何使用XML定义ClipDrawable,并通过代码实现渐变效果。

官方文档:

A Drawable that clips another Drawable based on this Drawable's current level value. You can control how much the child Drawable gets clipped in width and height based on the level, as well as a gravity to control where it is placed in its overall container. Most often used to implement things like progress bars, by increasing the drawable's level with setLevel().

Note: The drawable is clipped completely and not visible when the level is 0 and fully revealed when the level is 10,000.

It can be defined in an XML file with the <clip> element. For more information, see the guide to Drawable Resources.


简单地讲:ClipDrawable对象是一个Drawable对象,用来剪切原有的Drawabe对象(根据level值剪切),形成“片段”。level范围(0-10000),0为不可见,10000为全显示。

如果在XML文件中定义ClipDrawable对象的话,需要使用<clip>元素。截取的方向由clipOrientation属性控制。


贴出例子:

ClipDrawable资源文件:clip_drawable.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- clipOrientation属性设置图片截取的方向 -->
<clip xmlns:android="http://schemas.android.com/apk/res/android" 
    android:drawable="@drawable/jellybean"
    android:clipOrientation="horizontal"
    android:gravity="center">
</clip>

布局文件中:main.xml  (ImageView控件中设置ClipDrawable资源文件)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/image"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:scaleType="fitCenter"
        android:src="@drawable/clip_drawable" />

</LinearLayout>

主Activity代码:ClipDrawableTest.java

package com.cb.clipdrawable;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import org.crazyit.image.R;

import android.app.Activity;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ImageView;

public class ClipDrawableTest extends Activity {
	ImageView mImageView;
	Drawable mDrawable;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		mImageView = (ImageView) findViewById(R.id.image);
		mDrawable = mImageView.getDrawable();

		//使用一个timer对象控制发送消息
		final Timer timer = new Timer();
		timer.schedule(new TimerTask() {

			@Override
			public void run() {
				Message msg = new Message();
				mHandler.sendMessage(msg);
				//level 取值范围0-10000.
				if (mDrawable.getLevel() >= 10000) {
					timer.cancel();
				}
			}
		}, 0, 200);
		/*
		try {
			//设置壁纸
			setWallpaper(BitmapFactory.decodeResource(getResources(), R.drawable.jellybean));
		} catch (IOException e) {
			e.printStackTrace();
		}
		*/
	}

	private Handler mHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			//设置图片:每次根据level值的变化而变化,再显示出来
			mDrawable.setLevel(mDrawable.getLevel() + 200);
		}

	};
}

渐变前图片:



渐变后图片:


是的,**你可以直接使用 `ClipDrawable`**,但前提是: ### ✅ 使用 `ClipDrawable` 的前提条件: 1. **图像资源必须是 `ClipDrawable` 类型**; 2. **资源必须在 XML 中定义为 `<clip>` 标签**; 3. **不能直接从普通图片(如 PNG)创建 `ClipDrawable`**; 4. **必须通过资源加载或代码动态创建**。 --- ## ✅ 正确使用 `ClipDrawable` 的方式 ### 🧱 1. 在 `res/drawable` 中定义 `clip.xml` ```xml <!-- res/drawable/clip_bulb.xml --> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/bulbonbody" android:orientation="vertical" android:gravity="bottom" /> ``` - `android:drawable`:引用你的灯泡图片; - `android:orientation="vertical"`:表示垂直方向裁剪; - `android:gravity="bottom"`:表示从底部开始裁剪。 --- ### 📦 2. 在布局中使用该 `ClipDrawable` ```xml <ImageView android:id="@+id/blubMaxInit" android:layout_width="wrap_content" android:layout_height="150dp" android:adjustViewBounds="true" android:src="@drawable/clip_bulb" /> ``` --- ### 🧠 3. 在代码中获取并修改 `ClipDrawable` 的 `level` ```kotlin val drawable = lightBulb.drawable as ClipDrawable drawable.level = 5000 // 50% 亮度(level 范围是 0 ~ 10000) ``` - `level = 0` 表示完全裁剪(不可见); - `level = 10000` 表示完全显示; - 你可以通过手势、SeekBar、动画等方式动态改变 `level`。 --- ## ❌ 不能这样使用: ### ❌ 错误写法 1:直接从普通图片转换 ```kotlin val drawable = imageView.drawable as ClipDrawable // ❌ 如果不是 clip 类型会崩溃 ``` - 如果你直接加载的是 PNG 图片,它不是 `ClipDrawable` 类型; - 强转会抛出异常:`java.lang.ClassCastException`。 --- ### ❌ 错误写法 2:代码中直接 new ClipDrawable ```kotlin val drawable = ClipDrawable(...) // ❌ 构造函数被隐藏,不能直接 new ``` - Android 不允许直接实例化 `ClipDrawable`; - 必须通过 XML 定义或者使用 `DrawableContainer` 构造。 --- ## ✅ 动态创建 `ClipDrawable`(高级用法) 如果你不想用 XML,也可以在代码中动态创建: ```kotlin val originalDrawable = ContextCompat.getDrawable(context, R.drawable.bulbonbody) val clipDrawable = ClipDrawable(originalDrawable, Gravity.BOTTOM, ClipDrawable.VERTICAL) imageView.setImageDrawable(clipDrawable) clipDrawable.level = 7000 // 70% ``` > 注意:`ClipDrawable` 是 `DrawableWrapper`,可以包装任意 `Drawable`。 --- ## ✅ 总结 | 问题 | 是否可以 | |------|----------| | 可以直接使用 `ClipDrawable` 吗? | ✅ 可以,但必须是通过 XML 或动态包装创建的 | | 可以将普通图片强转为 `ClipDrawable`? | ❌ 不可以,会崩溃 | | 可以用代码创建 `ClipDrawable`? | ✅ 可以,但不能直接 new,要包装已有 Drawable | | `level` 的取值范围是多少? | ✅ 0 ~ 10000,0 是完全隐藏,10000 是完全显示 | --- ##
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值