如何自定义View  
好处:特殊的效果,满足个性的需求
流程:
1) 创建一个类,继承View或它的子类
2) 添加构造方法
  一个参数:在代码中创建对象
  两个参数:在布局文件中使用  
3) 重写onDraw()方法           一个矩形区域,画布Canvas  画笔Paint
  设置画笔属性
       // 创建画笔
       Paint paint = new Paint();
       paint.setColor(Color.RED);
       paint.setAntiAlias(true);
       paint.setTextSize(30);
4) 使用canvas绘制
  例如:canvas.rotate(90);
        canvas.drawText("VerticalTextView", 20, 0, paint);


如何使用自定义控件
在布局文件中拖拽自定义控件



自定义控件属性的步骤:
1) 在values目录中创建attrs.xml
  (从ApiDemos中拷贝)
2) 定义属性
  例如:  
   <declare-styleable name="VerticalTextView">
       <attr name="content" format="string" />
3) 在自定义控件代码中读取布局中配置的属性,进行设置
  参考ApiDemos中的LabelView  


使用自定义属性:
1) 在布局文件中添加自定义控件的命名空间
  例如: xmlns:yuchen="http://schemas.android.com/apk/res/org.yuchen.templete"  
2) 配置属性,例如:yuchen:content="sdf"

动态:
1) 修改重新绘制的内容
2) 触发系统重新调用onDraw()方法
  调用invalidate()方法
  例如:
       // 动态自定义控件
       postDelayed(new Runnable()
       {
           @Override
           public void run()
           {
               text = new Date().toLocaleString();
               invalidate();
               postDelayed(this, 1000);
           }
       }, 1000);


运行效果如下:(动态生成)

221602447.jpg


代码如下:

public class Mytextview extends View
{
    String content = "abc";
    private int color;
    private float dimension;
    private Paint paint;
    public Mytextview(Context context)
    {//一个参数的构造方法,适用在,代码中new自定义的view类
        super(context);
    }
    public Mytextview(Context context, AttributeSet attrs)
    {
    //两个参数的构造方法,适用在,使用布局xml里拖拉自定义的控件方法
    //
        super(context, attrs);
            
    //      读取控件里使用的属性attrs
        TypedArray a = context.obtainStyledAttributes(attrs,
    R.styleable.mytextview);
        CharSequence s = a.getString(R.styleable.mytextview_text);
    //静态读取自定义控件的文字内容
        color = a.getColor(R.styleable.mytextview_textColor,     Color.BLACK);
        dimension = a.getDimension(R.styleable.mytextview_textSize, 20);
//        if (s != null) {
//            content = s.toString();
//        }
        postDelayed(new Runnable()
        {
//          动态获得自定义控件的文字内容
            @Override
            public void run()
            {
                content = new Date().toLocaleString();
                invalidate();//调用ondraw()方法,重绘
                postDelayed(this, 1000);
            }
        }, 1000);
    }
    @Override
    protected void onDraw(Canvas canvas)
    { //canvas画布
        super.onDraw(canvas);
        Log.e("onDraw", "onDraw");
        paint = new Paint();
        paint.setColor(color);
        paint.setTextSize(dimension);
        paint.setAntiAlias(true);//消除锯齿
        canvas.rotate(90);//画布旋转90度
        canvas.drawText(content , 60, -60, paint);//画文本
    }
}
public class Mytextview extends View
{
    String content = "abc";
    private int color;
    private float dimension;
    private Paint paint;
    public Mytextview(Context context)
    {//一个参数的构造方法,适用在,代码中new自定义的view类
        super(context);
    }
    public Mytextview(Context context, AttributeSet attrs)
    {
    //两个参数的构造方法,适用在,使用布局xml里拖拉自定义的控件方法
//
        super(context, attrs);
//      读取控件里使用的属性attrs
        TypedArray a = context.obtainStyledAttributes(attrs,
        R.styleable.mytextview);
        CharSequence s = a.getString(R.styleable.mytextview_text);//静态读取自定义控件的文字内容
        color = a.getColor(R.styleable.mytextview_textColor, Color.BLACK);
        dimension = a.getDimension(R.styleable.mytextview_textSize, 20);
//        if (s != null) {
//            content = s.toString();
//        }
        postDelayed(new Runnable()
        {
//          动态获得自定义控件的文字内容
            @Override
            public void run()
            {
                content = new Date().toLocaleString();
                invalidate();//调用ondraw()方法,重绘
                postDelayed(this, 1000);
            }
        }, 1000);
    }
    @Override
    protected void onDraw(Canvas canvas)
    {
        super.onDraw(canvas);
        paint = new Paint();
        paint.setColor(color);
        paint.setTextSize(dimension);
        paint.setAntiAlias(true);//消除锯齿
        canvas.rotate(90);//画布旋转90度
        canvas.drawText(content , 60, -60, paint);//画文本
    }
}