自定义属性并使用
1在values目录下建立attrs.xml文件,在里面定义自己的属性,如下:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="MyText">
<attr name="lineNum" format="integer"/>
<attr name="xScroll" format="boolean"/>
<attr name="mStr" format="string"/>
</declare-styleable>
</resources>
2在布局文件中使用自定义属性需要在根标签添加引用空间
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mtext="http://schemas.android.com/apk/res/com.duduhali.customview"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.duduhali.customview.MainActivity" >
<com.duduhali.customview.view.MyText
android:layout_width="match_parent"
android:layout_height="match_parent"
mtext:lineNum="3"
mtext:xScroll="true"
mtext:mStr="你好自定义View" />
</RelativeLayout>
上面xmlns:mtext="http://schemas.android.com/apk/res/com.duduhali.customview"为添加引用空间。
mtext:lineNum="3"
mtext:xScroll="true"
mtext:mStr="你好自定义View"
为使用自定义属性。要时自定的属性起作用,要在自己的View中加以引用,上面的MyText的构造函数如下,在里面对自定义属性加以使用
public MyText(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.MyText);
lineNum = ta.getInt(R.styleable.MyText_lineNum, 1);
xScroll = ta.getBoolean(R.styleable.MyText_xScroll, false);
text = ta.getString(R.styleable.MyText_mStr);
if( text == null){//设置未设置此属性时的默认值
text = "一只哈巴狗";
}
ta.recycle();//回收TypedArray,此后就不能再使用此TypedArray
}
其中的lineNum和xScroll为整形,text为字符串
自定义View的基类和子类如下:
BaseView.java
public abstract class BaseView extends View {
private boolean running = true;
private MyThread thread;
protected abstract void drawSub(Canvas canvas);//子类通过此方法此方法把元素画到界面上
protected abstract void logic();//在调用子类的drawSub()方法前调用,实现对绘画元素的处理
public BaseView(Context context) {//代码中生成view时调用
super(context);
// TODO Auto-generated constructor stub
}
public BaseView(Context context, AttributeSet attrs) {//布局文件中定义view调用
super(context, attrs);
// TODO Auto-generated constructor stub
}
public BaseView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
// TODO Auto-generated constructor stub
}
@Override
protected final void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
if(thread == null){
thread = new MyThread();
thread.start();
}else{
drawSub(canvas);
}
}
/*
* onDetachedFromWindow(),销毁view的时候调用,做收尾工作
* 相反,onAttachedToWindow()在第一次onDraw之前调用,只一次
*/
@Override
protected void onDetachedFromWindow() {
// TODO Auto-generated method stub
running = false;
super.onDetachedFromWindow();
}
class MyThread extends Thread{
@Override
public void run() {
// TODO Auto-generated method stub
while(running){
logic();
postInvalidate();
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
MyText.java
public class MyText extends BaseView {
private Paint paint = new Paint();
private int lineNum = 0;
private int mx = 0;
private boolean xScroll = false;
private String text;
public MyText(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
public MyText(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
TypedArray ta = context.obtainStyledAttributes(attrs,
R.styleable.MyText);
lineNum = ta.getInt(R.styleable.MyText_lineNum, 1);
xScroll = ta.getBoolean(R.styleable.MyText_xScroll, false);
text = ta.getString(R.styleable.MyText_mStr);
if( text == null){//设置未设置此属性时的默认值
text = "一只哈巴狗";
}
ta.recycle();//回收TypedArray,此后就不能再使用此TypedArray
}
@Override
protected void drawSub(Canvas canvas) {//此方法把元素画到界面上
// TODO Auto-generated method stub
for(int i = 0; i < lineNum; i++ ){
int textSize = 20 + i*10;
paint.setTextSize(textSize);
canvas.drawText(text, mx, textSize+textSize*i, paint);
}
}
@Override
protected void logic() {//在调用drawSub()前被父类调用,实现对绘画元素的处理
// TODO Auto-generated method stub
if( xScroll ){
mx += 2;
if( mx > getWidth() ){
mx = (int) - paint.measureText(text);
/*
* 获得字符串的现实宽度,必须是和context中资源相关联的,如:
* TextView tv = new TextView(getContext());
* Paint p = tv.getPaint();
* float width = p.measureText(text);
*/
}
}
}
}
本demo是仿照极客学院上的案例做的
工程源码地址: http://download.csdn.net/detail/duduhali/9124585