linwoain的个人blog

知我者谓我心忧,不知我者谓我何求

0%

自定义控件,实现加载图片时透明变换

自定义控件,一般都是通过继承已有的view类,如TextView,Button。。。或者直接继承其父类View。这次因为要加载图片。所以继承自ImageView。并且实现了一个通过属性来控制的加载时间。首先是自定义的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
*知我者为我心忧,不知我者谓我何求!
*linwoain@outlook.com
*作者 linwoain
*日期 2014/11/7 9:17
*/
package com.linwoain.TestAndroid.fragment;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ImageView;
import com.linwoain.TestAndroid.R;
import java.util.Timer;
import java.util.TimerTask;
/**
* 自定义控件,实现
* @author linwoain
* @version 2014/11/7 9:17
*/
public class AlphaImageView extends ImageView {
private static final int SPEED = 300;//每隔多少毫秒透明度改变一次
private int alphaDelta = 0;//图像透明度每次改变的大小
//记录图片当前的透明度
private int curAlpha = 0;
Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x123) {
curAlpha += alphaDelta;
if (curAlpha > 255) {
curAlpha = 255;
AlphaImageView.this.setAlpha(curAlpha);
}
}
}
};
public AlphaImageView(Context context) {
this(context, null);
}
public AlphaImageView(Context context, AttributeSet attrs) {
super(context, attrs);

TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.AlphaImageView);
int duration = typedArray.getInt(R.styleable.AlphaImageView_duration, 0);//默认不透明
alphaDelta = 255 * SPEED / duration;
typedArray.recycle();
}
@Override
protected void onDraw(Canvas canvas) {
this.setAlpha(curAlpha);
super.onDraw(canvas);
final Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
Message message = new Message();
message.what = 0x123;
if (curAlpha >= 255) {
timer.cancel();
} else {
handler.sendMessage(message);
}
}
}, 0, SPEED);
}
}

这当中使用了属性AlphaImageView_duration,需要在values目录下新建attrs文件中声明,两种方式1、不声明类型:

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<resources>
<attr name="duration"></attr>
<declare-styleable name="AlphaImageView">
<attr name="duration"></attr>
</declare-styleable>
</resources>

2、声明类型:

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="AlphaImageView">
<attr name="duration" format="integer"></attr>
</declare-styleable>
</resources>

第一种方式,有可能导致编译正确,但运行错误,第二种编译器会拒绝输入错误类型 。其中的AlphaImageView可以是非自定义控件的类名。然后在布局文件中添加一个AlphaImageView实例

1
2
3
4
5
<com.linwoain.TestAndroid.fragment.AlphaImageView
app:duration="6000"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/gif"/>

注意,在布局文件中使用自定义控件的属性时,需要引入命名控件

1
2
3
4
5
6
7
8

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

如上方所示,1的命名控件为安卓系统提供的控件的命名控件,2是自定义的命名控件,由http://schemas.android.com/apk/res(http://schemas.android.com/apk/res/com.linwoain.TestAndroid)+应用的包名 共同构成!
此时就完成了一个自定义控件!!