自定义View系列(二)

     2017年转眼逝去,开始了崭新的18年,年假也结束了,又开始了忙碌的工作。作为2018年的第一篇小记还是围绕自定义View开始的,这是自定义View的第二篇小记,也是2018年的第一篇小记,着重介绍自定义View的一些常用的方法。废话不多说,老规矩,先上代码:

1,主函数:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
}

这个就没什么可说的了,里面什么都没有······

2,xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"

    tools:context="com.example.administrator.myview1.MainActivity">

   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#ff0000"
       app:type="0"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#00ff00"
       app:type="1"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#0000ff"
       app:type="2"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#ff8890"
       app:type="3"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#29c682"
       app:type="4"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#4606b4"
       app:type="5"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:width="2dp"
       app:color="#ec06c9"
       app:type="6"/>
   <com.example.administrator.myview1.MyTextView
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       app:type="7"/>


</RelativeLayout>

3,自定义属性:

<resources>
    <declare-styleable name="MyTextView">
        <attr name="type" format="integer"/>
        <attr name="width" format="dimension"/>
        <attr name="color" format="color"/>
    </declare-styleable>
</resources>

4,自定View:

public class MyTextView extends View {

    private Paint mPaint;
    private float mWidth;
    private int mType;
    private int color;
    
    public MyTextView(Context context) { this(context,null);}
    
    public MyTextView(Context context, @Nullable AttributeSet attrs) { this(context, attrs,0);}

    public MyTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.MyTextView);
        mWidth = typedArray.getDimension(R.styleable.MyTextView_width,0);
        mType = typedArray.getInt(R.styleable.MyTextView_type,2);
        color = typedArray.getColor(R.styleable.MyTextView_color,Color.RED);
        typedArray.recycle();
        initView();
    }
    
    /** 初始化,创建画笔*/  private void initView(){
        mPaint = new Paint();
        mPaint.setAntiAlias(true);//消除锯齿
        mPaint.setStyle(Paint.Style.STROKE);//画笔的类型为空心
        mPaint.setStrokeWidth(mWidth);//边框的宽度
        mPaint.setColor(color);//画笔的颜色
    }
    
    /** 重写onDraw方法,开始绘制 */  @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if(mType == 0){//画矩形
            //前四个参数分别为:左上右下的坐标
            canvas.drawRect(100,50,300,200,mPaint);
        }else if(mType == 1){//圆角矩形
            RectF rect = new RectF(600,50,800,250);
           canvas.drawRoundRect(rect,20,20,mPaint);
        }else if(mType == 2){//            canvas.drawCircle(200,400,100,mPaint);
        }else if(mType == 3){//椭圆
            RectF rect = new RectF(550,300,900,500);
           canvas.drawOval(rect,mPaint);
        }else if(mType == 4){//扇形
            RectF rect = new RectF(100,600,300,800);
           canvas.drawArc(rect,60,120,true,mPaint);
        }else if(mType == 5){//弧形
            RectF rect = new RectF(600,600,800,800);
            canvas.drawArc(rect,-90,90,false,mPaint);
        }else if(mType == 6){//文本
            mPaint.setTextSize(80);
           canvas.drawText("这是一个自定义的View",100,1000,mPaint);
        }else if(mType == 7){
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
            canvas.drawBitmap(bitmap,100,1100,mPaint);
        }
    }
}

    很简单的一段代码,第三个构造方法中用到了自定义属性,放在res/values下的attrs中,上面已经贴出了声明的属性的内容和属性类型。类型type,边框width和颜色color。属性的类型主要有:string,color,demension,integer,enum,reference,float,boolean,fraction,flag;这些,可以自己查阅资料进行了解。这里不再赘述。

    一个初始化方法:initView()里面,对画笔Paint进行初始化,设置了一些简单的属性,都有注释,不再细说。主要的是最后的一个方法onDraw(Canvas canvas)。里面有一个参数Canvas,顾名思义就是画布。我们所自定义的一切东西最后都是在画布上绘制出来的。所以,onDraw()方法是一定要重写的。

在onDraw()方法中,调用了canvas的几个常用的方法,画矩形,圆角矩形,元,椭圆,扇形,弧形,文本和图片。基本上常用的也就这么多了。下面我们逐一介绍各个方法和参数代表的含义:

canvas.drawRect(100,50,300,200,mPaint):绘制矩形,前四个参数是坐标,前两个是矩形坐上叫的坐标,后两个是矩形右下角的坐标值,这样矩形的大小已经决定了,mPaint是画笔。

canvas.drawRoundRect(rect,20,20,mPaint):绘制圆角矩形。其中rect是通过RectF rect = new RectF(600,50,800,250)绘制出的矩形,不再多说。第二个和第三个参数分别是下图的rx和ry:

                               

                                            图片来源:http://blog.csdn.net/carson_ho/article/details/60598775

x轴的坐标和y轴的坐标,ry和ry相当于椭圆的圆弧,也就是椭圆的连个半径。

特别注意:当 rx大于宽度的一半, ry大于高度一半 时,画出来的为椭圆

canvas.drawCircle(200,400,100,mPaint):绘制圆形。这个算是最常见的,前两个参数代表绘制的圆形的圆形,第三个参数是圆的半径。

canvas.drawOval(rect,mPaint):绘制椭圆。rect是一个矩形对象,也是椭圆所在的矩形,椭圆的宽高也有所在的矩形决定了。

canvas.drawArc(rect,60,120,true,mPaint):绘制扇形。rect为矩形对象。第二三个参数是扇形的其实角度和扫过角度,第三个大于第二个为顺时针,反之为逆时针。第四个参数是布尔值,是否使用圆心,为true时,是扇形,为false时,为弧形。

注意:扇形和圆弧的角度对应于圆上的角度为,圆心的正上方开始为-90度,以顺时针增加,圆心的水平右边为0度

canvas.drawText(string,100,1000,mPaint):绘制文本。string为要绘制的文本,第二个和第三个擦书为文本开始的x轴和y轴的坐标(注意是开始文本的右下角,后期会详细讲解)。

canvas.drawBitmap(bitmap,100,1100,mPaint):绘制位图,这个其实用的并不算多,第一个参数是位图对象,二三参数是x和y轴的坐标。

这里附上效果图:


这一期就到这吧,下一期开始进行自定控件控件!