Android0917(自定义的View、绘制简单图形、Bitmap)(二)

绘制简单图形

下面是Canvas类常用的方法:

drawRect(RectF rect, Paint paint) //绘制区域,参数一为RectF一个区域

drawPath(Path path, Paint paint) //绘制一个路径,参数一为Path路径对象

drawBitmap(Bitmap bitmap, Rect src, Rect dst, Paint paint) //贴图,参数一就是我们常规的Bitmap对象,参数二是源区域(这里是bitmap),参数三是目标区域(应该在canvas的位置和大小),参数四是Paint画刷对象,因为用到了缩放和拉伸的可能,当原始Rect不等于目标Rect时性能将会有大幅损失。

drawLine(float startX, float startY, float stopX, float stopY, Paintpaint) //画线,参数一起始点的x轴位置,参数二起始点的y轴位置,参数三终点的x轴水平位置,参数四y轴垂直位置,最后一个参数为Paint 画刷对象。

drawPoint(float x, float y, Paint paint) //画点,参数一水平x轴,参数二垂直y轴,第三个参数为Paint对象。

drawText(String text, float x, floaty, Paint paint) //渲染文本,Canvas类除了上面的还可以描绘文字,参数一是String类型的文本,参数二x轴,参数三y轴,参数四是Paint对象。

drawOval(RectF oval, Paint paint)//画椭圆,参数一是扫描区域,参数二为paint对象;
drawCircle(float cx, float cy, float radius,Paint paint)// 绘制圆,参数一是中心点的x轴,参数二是中心点的y轴,参数三是半径,参数四是paint对象;

drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//画弧,

参数一是RectF对象,一个矩形区域椭圆形的界限用于定义在形状、大小、电弧,参数二是起始角(度)在电弧的开始,

参数三扫描角(度)开始顺时针测量的,参数四是如果这是真的话,包括椭圆中心的电弧,并关闭它,如果它是假这将是一个弧线,参数五是Paint对象;

还要理解一个paint类:
Paint 代表了Canvas上的画笔、画刷、颜料等等;

Paint类常用方法:

setARGB(int a, int r, int g, int b) // 设置 Paint对象颜色,参数一为alpha透明值

setAlpha(int a) // 设置alpha不透明度,范围为0~255

setAntiAlias(boolean aa) // 是否抗锯齿

setColor(int color) // 设置颜色,这里Android内部定义的有Color类包含了一些常见颜色定义

setTextScaleX(float scaleX) // 设置文本缩放倍数,1.0f为原始

setTextSize(float textSize) // 设置字体大小

setUnderlineText(booleanunderlineText) // 设置下划线

MyPath.java

public class MyPath extends View{
    private int width;
    private int height;
    private Paint mPaint;
    private Paint mPaintText;
    private Path mPath;
    private Path mPathCircle;
    private Path mPathLine;
    private Paint mPaintLine;
    private Path mPathWave;
    private Paint mPaintWave;
    private static final int WAVE_LINE=0x23;
    private int count=0;
    private Bitmap mBitmap;
    private Handler handler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch(msg.what){
                case WAVE_LINE:
                    count+=10;
                    if (count>160) {
                        count = 0;
                    }
                    invalidate();// 刷新
                    handler.sendEmptyMessageDelayed(WAVE_LINE,100);
                    break;
            }
        }
    };
    public MyPath(Context context) {
        super(context);
    }

    public MyPath(Context context, AttributeSet attrs) {
        super(context, attrs);
        //设置绘制文字的画笔
        mPaintText=new Paint();
        mPaintText.setColor(Color.BLUE);
        mPaintText.setTextSize(50);//设置画笔大小
        mPaintText.setStyle(Paint.Style.STROKE);//消除锯齿
        //设置绘制画笔的属性
        mPaint=new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(10);//设置画笔宽度
        mPaint.setStyle(Paint.Style.STROKE);
        //设置绘画线段的画笔
        mPaintLine=new Paint();
        mPaintLine.setColor(Color.RED);
        mPaintLine.setStyle(Paint.Style.STROKE);
        mPaintLine.setStrokeWidth(10);
        //设置绘画波浪线的画笔属性
        mPaintWave=new Paint();
        mPaintWave.setColor(Color.YELLOW);
        mPaintWave.setStrokeWidth(10);
        mPaintWave.setStyle(Paint.Style.STROKE);
        //设置路径
        mPathWave=new Path();//设置波浪线的路径
        mPath=new Path();//设置路径
        mPathCircle=new Path();//设置圆形的路径
        mPathLine=new Path();//设置线段的路径

        handler.sendEmptyMessageDelayed(WAVE_LINE, 100);
        //设置初始化位图Bitmap,
        mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.zun);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//设置画布的大小,长和宽
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.moveTo(100, 100);//设置路径的第一个点座标
        mPath.lineTo(150,150);//设置下一个点的座标
        mPath.lineTo(100,150);//设置下一个点的座标
        mPath.close();//封闭路径
        canvas.drawBitmap(mBitmap,width/2,height/2,mPaint);
        //设置圆形路径,Path.Direction设置转动方向,CW是顺时针,CCW是逆时针
        mPathCircle.addCircle(width/2,height/2,width/4,Path.Direction.CW);
        // canvas.drawPath绘制特定的路径,第一个参数传具体的路径Path实例对象,第二参数传画笔
        canvas.drawPath(mPath,mPaint);//设置路径
        canvas.drawPath(mPathCircle,mPaint);
        //canvas.drawTextOnPath设置文字沿路径排列,第一个参数是文字内容,第二个参数是沿的路径Path实例对象
        //第三个参数和第四个参数是横纵偏移量,最后一个是画笔
        canvas.drawTextOnPath("我是沿着路径走的一行字",mPathCircle,10,50,mPaintText);
        //Path.quadTo用来绘制贝赛尔曲线,前两个参数是控制点的横纵座标,后两个参数是后一个点的横纵座标
        mPathLine.moveTo(width/8*3,height/8*3);
        mPathLine.quadTo(width/2,height/2+width/4,width/8*5,height/8*3);
        canvas.drawPath(mPathLine,mPaintLine);

        mPathWave.reset();
        mPathWave.moveTo(count,height/2+width/16);
        //Path.rQuadTo()方法绘制曲线时,会把上一点的座标当做是原点座标,依次往后
        for (int i=0;i<10;i++){
            mPathWave.rQuadTo(40,30,80,0);
            mPathWave.rQuadTo(40,-30,80,0);
        }
        canvas.drawPath(mPathWave,mPaintWave);
    }
}

activity_path.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent"
  android:background="@mipmap/imagebac">
<com.example.administrator.canvas.widget.MyPath
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyPathActivity.java

public class MyPathActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_path);
    }
}

这里写图片描述

Bitmap、Matrix

位于android.graphics.Matrix包下的Matrix是拥有3 x3的座标变换矩阵的矩阵类。用于对位图进行一些变化

1、Translate—平移变换

 matrix.postTranslate(0,mBitmapHeigtht*2);//沿y轴向下平移Bitmap高的2倍

2、Scale—缩放变换

matrix.postScale(2,2);//放大2倍

3、Rotate—旋转变换

 matrix.postRotate(180);//旋转180度

4、Skew—错切变换

 matrix.postSkew(1,0);//x轴上的值不变,拉伸y轴上的值

5、Values—-对称

 float matrix_values[]={1f,0f,0f,0f,-1f,0f,0f,0f,1f};//关于x轴对称,倒影效果
matrix.setValues(matrix_values);
float matrix_values2[]={-1f,0f,0f,0f,1f,0f,0f,0f,1f};//关于y轴对称,镜面效果
matrix.setValues(matrix_values2);

Bitmap实现在android.graphics包中。Bitmap类的构造函数是私有的,外面并不能实例化.BitmapFactory类提供了创建Bitmap的接口,而JNI接口来实例化Bitmap的.如下:

 mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.betterfly);//decodeResource能够从给定的资源中解析出新的位图,第一个参数是包含图像数据的资源对象,第二个参数是图像数据的资源标识

得到位图Bitmap的宽和高

mBitmapWidth=mBitmap.getWidth();//得到位图的宽
mBitmapHeigtht =mBitmap.getHeight();//得到位图的高

将位图绘制到画布上,canvas.drawBitmap()方法,第一个参数是位图实例对象Bitmap,第二个和第三个参数是位图得左上角位于画布中的位置,最后一个是画笔

canvas.drawBitmap(mBitmap,0,0,mPaint);

MyBitmap.java

public class MyBitmap extends View {
    private int width;
    private int height;
    private Paint mPaint;
    private Bitmap mBitmap;
    private Matrix matrix;
    private int mBitmapWidth;
    private int mBitmapHeigtht;
    public MyBitmap(Context context) {
        super(context);
    }

    public MyBitmap(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint=new Paint();
        mPaint.setColor(Color.GREEN);
        mPaint.setStrokeWidth(10);
        mPaint.setStyle(Paint.Style.STROKE);
        mBitmap= BitmapFactory.decodeResource(getResources(), R.mipmap.betterfly);
        matrix=new Matrix();
        mBitmapWidth=mBitmap.getWidth();
        mBitmapHeigtht =mBitmap.getHeight();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//设置画布的大小,长和宽
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawBitmap(mBitmap,0,0,mPaint);

        matrix.reset();
        matrix.postScale(2,2);//放大2倍
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();;
        canvas.drawBitmap(mBitmap,matrix,mPaint);
        matrix.postTranslate(0,mBitmapHeigtht*2);//平移
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        matrix.postRotate(180);//旋转
        matrix.postTranslate(mBitmapWidth*2,mBitmapHeigtht*3);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        float matrix_values[]={1f,0f,0f,0f,-1f,0f,0f,0f,1f};//关于x轴对称,倒影效果
        matrix.setValues(matrix_values);
        matrix.postTranslate(0,mBitmapHeigtht*2);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();;
        float matrix_values2[]={-1f,0f,0f,0f,1f,0f,0f,0f,1f};//关于y轴对称,镜面效果
        matrix.setValues(matrix_values2);
        matrix.postTranslate(mBitmapWidth*2,0);
        canvas.drawBitmap(mBitmap,matrix,mPaint);

        matrix.reset();
        matrix.postSkew(1,0);//拉伸
        matrix.postTranslate(0,mBitmapHeigtht*3);
        canvas.drawBitmap(mBitmap,matrix,mPaint);
    }
}

activity_bitmap.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.example.administrator.canvas.widget.MyBitmap
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyBitmapActivity.java

public class MyBitmapActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmap);
    }
}

这里写图片描述

位图相交

这里写图片描述

MyBitmapView.java

public class MyBitmapView extends View {
    private int width;
    private int height;
    private Paint mPaintCircle;
    private Paint mPaintRect;
    private Bitmap mBitmap;
    private Canvas canvasBit;
    public MyBitmapView(Context context) {
        super(context);
    }

    public MyBitmapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintCircle=new Paint();
        mPaintCircle.setColor(Color.YELLOW);

        mPaintRect=new Paint();
        mPaintRect.setColor(Color.GREEN);
    //PorterDuffXfermode(PorterDuff.Mode.XOR)创建一个xfermode使用指定的波特达夫模式。参数为运用波特达夫模式
        PorterDuffXfermode modeXOR=new PorterDuffXfermode(PorterDuff.Mode.XOR);
        //setXfermode()方法设置或清除xfermode对象。参数为xfermode的实例对象
     mPaintRect.setXfermode(modeXOR);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//设置画布的大小,长和宽
//Bitmap.createBitmap()返回与指定的宽度和高度可变的位图。 
//Bitmap.Config描述了一个位图结构如何存储像素       mBitmap=Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        //Canvas(mBitmap)方法用指定的位图构造一个画布来绘制。
        canvasBit=new Canvas(mBitmap);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        canvasBit.drawCircle(width/4,height/4,width/4,mPaintCircle);
        canvasBit.drawRect(0,0,width/4,width/4,mPaintRect);
        canvas.drawBitmap(mBitmap,0,0,null);
    }
}

activity_bitmapview.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.example.administrator.canvas.widget.MyBitmapView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" />
</LinearLayout>

MyBitmapView.java

public class MyBitmapViewActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmapview);
    }
}

这里写图片描述

MySilder.java

public class MySilder extends View {
    private int width;
    private int height;
    private Paint mPaint;
    private Paint mPaintMove;
    private String []array={"A","B","C","D","E","F","G",
            "H","I","J","K","L","M","N","O","P","Q","R",
            "S","T","U","V","W","X","Y","Z"};
    private int count=1;
    private int index;

    private OnItemOnClick listener;

    public void setListener(OnItemOnClick listener) {
        this.listener = listener;
    }

    public interface OnItemOnClick{
        public void onItemOnClickListener(int index,String indexString);
    }
    public MySilder(Context context) {
        super(context);
    }

    public MySilder(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint=new Paint();
        mPaint.setTextAlign(Paint.Align.CENTER);
        mPaintMove=new Paint();
        mPaintMove.setTextAlign(Paint.Align.CENTER);
        mPaintMove.setColor(Color.RED);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width=getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height=getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width,height);//设置画布的大小,长和宽
    //设置字体的大小
        mPaint.setTextSize(height/26);
        mPaintMove.setTextSize(height/26);
    }

    private  float x,y;

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_MOVE:
            case MotionEvent.ACTION_DOWN:
                x=event.getX();
                y=event.getY();
                if (x>width-mPaint.measureText("M")*2) {
                    index = (int) (y / (height / 26));
                    invalidate();
                    if (listener!=null){
                        listener.onItemOnClickListener(index ,array[index]);
                    }
                    return true;
                }
                    break;
            case MotionEvent.ACTION_UP:
                count=-1;
                invalidate();
                return true;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i=0;i<26;i++){
            canvas.drawText(array[i],width-mPaint.measureText("M"),height/26*(i+1),mPaint);
            if (count==1){
                canvas.drawText(array[index],width-mPaint.measureText("M"),height/26*(index+1),mPaint);
            }else{
                canvas.drawText(array[index],width-mPaint.measureText("M"),height/26*(index+1),mPaintMove);
            }
        }
    }
}

MySilderActivity.java

public class MySilderActivity extends Activity {
    private TextView mTextView;
    private MySilder mySilder;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_silder);
        mTextView= (TextView) findViewById(R.id.textview);
        mySilder= (MySilder) findViewById(R.id.silder);
        mySilder.setListener(new MySilder.OnItemOnClick() {
            @Override
            public void onItemOnClickListener(int index,String indexString) {
                mTextView.setText(indexString);
            }
        });
    }
}

activity_silder.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:textSize="100dp"
        android:text="A"
        android:textAlignment="center"/>
<com.example.administrator.canvas.widget.MySilder
    android:id="@+id/silder"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"/>
</RelativeLayout>

这里写图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章