论坛首页 移动开发技术论坛

TextView 实现原理 实践

浏览 9411 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2010-01-16  

自定义View

 

[功能]

1. 自定义View 实现 TextView 的功能

2. 典型的 TextView 如下:

<TextView
			android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:text="HelloTextView" />

 

写道
android:text="HelloTextView"

 

就会显示指定的String

 

 

 

[代码]

1.  定义Text2View 所用关键字"text" 用于指定显示用的string

* 在 res/value 目录下创建 attrs.xml 文件 如下定义:

<?xml version="1.0" encoding="utf-8"?>
<resources>
     <declare-styleable name="Text2View">
        <attr name="text" format="string" />
    </declare-styleable>
</resources>

 

 

 

2. 定义 public class Text2View extends View

public class Text2View extends View {
    Paint text2Paint;
    String text2Text;
    int ascent;
    


    //Constructor - for java
    public Text2View(Context context) {
        super(context);
        initialize();
    }

    //Constructor - for xml
    public Text2View(Context context, AttributeSet attrs) {
        super(context, attrs);
        
        initialize();

        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.Text2View);
        
        int n = ta.getIndexCount();
        
        for(int i =0;i < n;i++){
        	int attr = ta.getIndex(i); 
        	
        	switch(attr){
        	case R.styleable.Text2View_text:
        		updateText(ta.getString(R.styleable.Text2View_text));
        		break;
        		
        	//TO ADD CUSTOM ATTRIBUTE
        		
        	default:
        		break;
        	}
        	
        }
        
        ta.recycle();
    }
    
    private final void updateText(String s){
    	text2Text = s;
    	
    	requestLayout();
        invalidate();
    }
    
    //load default setting on Text2View
    private final void initialize() {
        text2Paint = new Paint();
        text2Paint.setAntiAlias(true);
        text2Paint.setTextSize(16);
        text2Paint.setColor(0xFF000000);
        //setPadding(3, 3, 3, 3);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(measureWidth(widthMeasureSpec),
                measureHeight(heightMeasureSpec));
    }

    private int measureWidth(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text
            result = (int) text2Paint.measureText(text2Text) + getPaddingLeft()
                    + getPaddingRight();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }

        return result;
    }

    /**
     * Determines the height of this view
     * @param measureSpec A measureSpec packed into an int
     * @return The height of the view, honoring constraints from measureSpec
     */
    private int measureHeight(int measureSpec) {
        int result = 0;
        int specMode = MeasureSpec.getMode(measureSpec);
        int specSize = MeasureSpec.getSize(measureSpec);

        ascent = (int) text2Paint.ascent();
        if (specMode == MeasureSpec.EXACTLY) {
            // We were told how big to be
            result = specSize;
        } else {
            // Measure the text (beware: ascent is a negative number)
            result = (int) (-ascent + text2Paint.descent()) + getPaddingTop()
                    + getPaddingBottom();
            if (specMode == MeasureSpec.AT_MOST) {
                // Respect AT_MOST value if that was what is called for by measureSpec
                result = Math.min(result, specSize);
            }
        }
        return result;
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawText(text2Text, getPaddingLeft(), getPaddingTop() - ascent, text2Paint);
        
    }
}

 

 

3. Text2View 构造函数需要解释一下:

//Constructor - for java
    public Text2View(Context context) {
        super(context);
        initialize();
    }

    //Constructor - for xml
    public Text2View(Context context, AttributeSet attrs) {
        super(context, attrs);
        
        initialize();

        TypedArray ta = context.obtainStyledAttributes(attrs,
                R.styleable.Text2View);
        
        int n = ta.getIndexCount();
        
        for(int i =0;i < n;i++){
        	int attr = ta.getIndex(i); 
        	
        	switch(attr){
        	case R.styleable.Text2View_text:
        		updateText(ta.getString(R.styleable.Text2View_text));
        		break;
        		
        	//TO ADD CUSTOM ATTRIBUTE
        		
        	default:
        		break;
        	}
        	
        }
        
        ta.recycle();
    }

 

 

4. 在 xml 文件中如何使用Text2View

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res/com.android.View"
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
<TextView
			android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            android:text="HelloTextView" />
<com.android.View.Text2View
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" 
            app:text="HelloText2View" />
</LinearLayout>

 

 

 

5. 效果图 和默认的TextView 比较一下

   发表时间:2010-01-20  
这个  意义何在?
0 请登录后投票
   发表时间:2010-01-20  
yzhong_sa 写道
这个  意义何在?


定制化View啊 再作为模板
0 请登录后投票
   发表时间:2010-01-21  
  很好,很强大。
最近急需这类知识。
0 请登录后投票
   发表时间:2010-01-22  
Lz实现个textView写那么长篇...不就是onMeasure和onDraw俩方法.
0 请登录后投票
   发表时间:2010-01-22  
另外真想订制textView的外观,可以继承textView.重写onDraw
0 请登录后投票
   发表时间:2010-01-23  
melode11 写道
Lz实现个textView写那么长篇...不就是onMeasure和onDraw俩方法.

那你知道系统的TextView 实现的原理么? 这就是我写这个的本意!
0 请登录后投票
   发表时间:2010-03-12  
写得很好,但是,能不能在关键的地方加点注释啊,看不大懂
0 请登录后投票
   发表时间:2010-03-28  
对于做自己的ui确实有一些提示
0 请登录后投票
   发表时间:2010-03-29  
这方面的前辈们,俺是接触开发的新手,刚进公司,求这方面的发展,谁能给点资料,越基础越好。谢谢。
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics