Path、 贝塞尔曲线、 Bitmap、 Xfermode、 OnTouchEvent

Path

借助path类画一些几何图形
画一个三角形、画一个圆,沿着圆写文字,画贝塞尔曲线

protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        path.moveTo(300, 300);
        path.lineTo(200, 400);
        path.lineTo(400, 400);
        path.close();
        path.addCircle(width/2,height/2,300, Path.Direction.CCW);
        canvas.drawPath(path, mPaint);
        canvas.drawTextOnPath("文字文字文字文字文字文字文字",path,50,0,mPaint);
        path.moveTo(200,200);
        path.quadTo(300,300, 400, 200);
        canvas.drawPath(path, mPaint);
        canvas.drawPoint(200, 200, mPaintPoint);
}

贝塞尔曲线

所谓贝塞尔曲线,是连接两个点的圆滑曲线,它由三个点确定,一个起始点,一个终点,第三个是控制点。
如何画一个贝塞尔曲线:

path.moveTo(200,200);//起始点
path.quadTo(300,300, 400, 200);//控制点  结束点
canvas.drawPath(path, mPaint);

下面的程序可以达到水面波动的效果

package com.example.administrator.mywidgetdemo.MyView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.View;

import java.util.Calendar;

/**
 * Created by Administrator on 2015/9/17.
 */
public class MyPathView extends View {
    private int width;
    private int height;
    private Paint mPaint;
    private Paint mPaintPoint;
    private Path path;
    public static final int NEED_INVALIDATE = 0X23;
    private int count = 0;
    private Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what){
                case NEED_INVALIDATE:
                    count+=5;
                    if (count>80){
                        count=0;
                    }
                    invalidate();//告诉UI主线程重新绘制
                    handler.sendEmptyMessageDelayed(NEED_INVALIDATE,100);
                    break;
            }
        }
    };

    public MyPathView(Context context) {
        super(context);
    }

    public MyPathView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaint = new Paint();
        mPaint.setTextSize(50);
        mPaint.setAntiAlias(true);
        mPaint.setStyle(Paint.Style.STROKE);
        path = new Path();

        mPaintPoint = new Paint();
        mPaintPoint.setColor(Color.GREEN);
        mPaintPoint.setStyle(Paint.Style.STROKE);
        mPaintPoint.setStrokeWidth(3);
        handler.sendEmptyMessage(NEED_INVALIDATE);
    }

    @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);
        path.reset();
        path.moveTo(count, 100);
        for (int i = 0;i<10;i++){
            path.rQuadTo(20,5,40,0);//rQuadTo是以moveTo到的点为原点,接着确定两个点
            path.rQuadTo(20,-5,40,0);
        }
        canvas.drawPath(path,mPaint);
        canvas.drawCircle(400,100,80,mPaintPoint);
    }
}

Bitmap

Bitmap,位图
借助矩阵Matrix可以对位图进行操作:平移、旋转、缩放、倾斜、对称

package com.example.administrator.mywidgetdemo.MyView;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import com.example.administrator.mywidgetdemo.R;

/**
 * Created by Administrator on 2015/9/17.
 */
public class MyBitmapView extends View {
    private int width;
    private int height;
    private Bitmap mBitmap;
    private Paint mPaint;
    private Matrix matrix;

    private int mBitmapWidth;
    private int mBitmapHeight;

    public MyBitmapView(Context context) {
        super(context);
    }

    public MyBitmapView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.aa);
        Log.d("","图片相关信息 宽:"+mBitmap.getWidth()+"高:"+mBitmap.getHeight());
        mBitmapWidth = mBitmap.getWidth();
        mBitmapHeight = mBitmap.getHeight();

        mPaint = new Paint();
        matrix = new Matrix();

    }

    @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);//放大缩小
        canvas.drawBitmap(mBitmap, matrix, mPaint);

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

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

        matrix.reset();
        matrix.postSkew(0,1);//侧切(倾斜)
        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, mBitmapHeight * 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(width*2,0);
        canvas.drawBitmap(mBitmap,matrix,mPaint);
    }
}

Xfermode

示例图:
这里写图片描述

package com.example.administrator.mywidgetdemo.MyView;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by Administrator on 2015/9/17.
 */
public class MyBitmapView2 extends View {
    private int width;
    private int height;
    private Bitmap mBitmap;
    private Paint mPaintCricle;
    private Paint mPaintRect;

    public MyBitmapView2(Context context) {
        super(context);
    }

    public MyBitmapView2(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintCricle = new Paint();
        mPaintRect = new Paint();
        mPaintCricle.setColor(Color.YELLOW);
        mPaintRect.setColor(Color.BLUE);
        PorterDuffXfermode mode = new PorterDuffXfermode(PorterDuff.Mode.XOR);//通过改变参数可以达到不同的效果
        mPaintRect.setXfermode(mode);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width, height);
        mBitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888);
        canvasBit = new Canvas(mBitmap);
    }
    private Canvas canvasBit;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.RED);

        canvasBit.drawCircle(width/2,height/2,width/2,mPaintCricle);
        canvasBit.drawRect(0,height/2-width/2,width/2,height/2,mPaintRect);
        canvas.drawBitmap(mBitmap,0,0,null);
    }
}

onTouchEvent

示例是模拟电话薄中的联系人右侧的字母栏,可以点击,可以滑动。

package com.example.administrator.mywidgetdemo.MyView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * Created by Administrator on 2015/9/17.
 */
public class MySlider extends View {
    private int width;
    private int height;
    private Paint mPaintText;
    private Paint mPaintClick;
    private int index = -1;
    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 OnItemSelect onItemSelectListener;

    public void setOnItemSelectListener(OnItemSelect onItemSelectListener) {
        this.onItemSelectListener = onItemSelectListener;
    }

    public interface OnItemSelect{
        public void onItemSelect(int index,String stringIndex);
    }

    public MySlider(Context context) {
        super(context);
    }

    public MySlider(Context context, AttributeSet attrs) {
        super(context, attrs);
        mPaintText = new Paint();
        mPaintText.setTextAlign(Paint.Align.CENTER);
        mPaintClick = new Paint();
        mPaintClick.setTextAlign(Paint.Align.CENTER);
        mPaintClick.setColor(Color.BLUE);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(),widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(),heightMeasureSpec);
        setMeasuredDimension(width, height);
        mPaintText.setTextSize(height / 26f);

        mPaintClick.setTextSize(height/26f);
    }
    private float x;
    private float 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-mPaintText.measureText("M")*2){
                    index = (int) (y/(height/26));
                    Log.d("onTouch","点击到了:"+array[index]);
                    onItemSelectListener.onItemSelect(index,array[index]);
                    invalidate();
                    return true;
                }
                break;

            case MotionEvent.ACTION_UP:
                index = -1;
                invalidate();
                break;
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        for (int i=0;i<array.length;i++){
            if (index==i){
                canvas.drawText(""+array[i],width-mPaintText.measureText("M"),height/26*(i+1),mPaintClick);
            }else {
                canvas.drawText(""+array[i],width-mPaintText.measureText("M"),height/26*(i+1),mPaintText);
            }
        }
    }
}
public class MainActivity extends Activity {
    private MySlider mySlider;
    private TextView textView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_bitmapview);
        mySlider = (MySlider) findViewById(R.id.myslider);
        textView = (TextView) findViewById(R.id.textview);
        mySlider.setOnItemSelectListener(new MySlider.OnItemSelect(){

            @Override
            public void onItemSelect(int index, String stringIndex) {
                textView.setText(stringIndex);
            }
        });
    }
}

观察者设计模式

 private OnItemSelect onItemSelectListener;

    public void setOnItemSelectListener(OnItemSelect onItemSelectListener) {
        this.onItemSelectListener = onItemSelectListener;
    }

    public interface OnItemSelect{
        public void onItemSelect(int index,String stringIndex);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值