Android 绘图进阶:仿360水纹进度球(可动正余弦曲线+xfermode)

Android 绘图进阶:仿360水纹进度球(可动正余弦曲线+xfermode)_第1张图片
  在 Android 绘图基础:Path(绘制三角形、贝塞尔曲线、正余弦) 这篇博客中我们已经实现了可动的正余弦曲线,在学习了PorterDuff的Xfermode设置画笔风格后我们只需要在可动正余弦曲线的基础上进行修改即可。

思路

  要在上次可动正余弦曲线的基础上实现仿360的水纹进度球,最不太好做的是将我们的正余弦曲线进行闭合。也就是下面这部分代码。

mpath.reset();
        //f要放置在前面
        //如果写成currentprogress/100*300f的话 前半部分都是int值计算后已经是0再*300就没用了
        //可以先将450-(currentprogress/100f*300)
        //修改为固定高度比如200进行查看水纹样式
        mpath.moveTo(500,450-(currentprogress/100f*300));
        mpath.lineTo(500,450);
        //450-currentprogress/maxprogress*300f
        mpath.lineTo(count,450);
        mpath.lineTo(count,450-(currentprogress/100f*300));
        for(int i=0;i<10;i++){
            //rQuadTo
            mpath.rQuadTo(20, size, 40, 0);
            mpath.rQuadTo(20, -size, 40, 0);    
        }       

        mcanvas_bitmap.drawPath(mpath, Paintpath);

  根据代码的坐标点,可以先将450-(currentprogress/100f*300)//修改为固定高度比如200进行查看水纹样式,,之后尝试划线进行路径的闭合。
备注:count是为了值水纹可动的,实际上就是将正余弦曲线向右进行拖拽。
2、设置画笔风格Xfermode为SRC_IN就可以了。

Paintpath.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));

调用

mcanvas_bitmap.drawPath(mpath, Paintpath);

3、最后在MainActivity中控制currentprogress就OK了。
在MyPathView 中给出currentprogress的set/get方法,通过Mainactivity中的Hamdler进行改变:就可以了

mypathview.setCurrentprogress(progress);

代码展示

MyPathView (实现水纹闭合+画笔样式SRC_IN)

public class MyPathView extends View{
    private static final int A9DBF6 = 0;
    private int width;
    private int height;

    private Paint Paintpath;
    private Path mpath;
    private Paint PaintText;
    private Paint Paintpoint;
    private int count;
    private int size;
    private Bitmap mbitmap;
    private Canvas mcanvas_bitmap;
    private Paint paintnew;
    private int maxprogress=100;
    private int currentprogress;
    private Handler mhanHandler=new Handler(){
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
            case 0x23:
                count++;
            if(count>=80){
                count=0;
            }
            size++;
            if(size>10){
                size=5;
            }
            mhanHandler.sendEmptyMessageDelayed(0x23, 200);
                invalidate();
                break;

            default:
                break;
            }

        };
    };


    public int getCurrentprogress() {

        return currentprogress;
    }
    public void setCurrentprogress(int currentprogress) {
        this.currentprogress = currentprogress;
        invalidate();
    }
    public MyPathView(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
    }
    public MyPathView(Context context, AttributeSet attrs) {
        super(context, attrs);
        Paintpath=new Paint();
        Paintpath.setColor(Color.BLUE);
        Paintpath.setAntiAlias(true);
    // Paintpath.setStrokeWidth(5);
        Paintpath.setStyle(Style.FILL);
        Paintpath.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));


        PaintText=new Paint();
        PaintText.setColor(Color.YELLOW);
        PaintText.setAntiAlias(true);       
        PaintText.setTextSize(30);
        PaintText.setTextAlign(Align.CENTER);

        mpath=new Path();
        Paintpoint=new Paint();
        Paintpoint.setColor(Color.RED);
    // Paintpoint.setStrokeWidth(20);
        Paintpoint.setStyle(Style.FILL);
        paintnew=new Paint();
        paintnew.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        mhanHandler.sendEmptyMessage(0x23);


    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.LTGRAY);
        mpath.reset();
        mcanvas_bitmap.drawCircle(300, 300, 150, Paintpoint);

        mpath.reset();
        //f要放置在前面
        //如果写成currentprogress/100*300f的话 前半部分都是int值计算后已经是0再*300就没用了
        mpath.moveTo(500,450-(currentprogress/100f*300));
        mpath.lineTo(500,450);
        //450-currentprogress/maxprogress*300f
        mpath.lineTo(count,450);
        mpath.lineTo(count,450-(currentprogress/100f*300));
        for(int i=0;i<10;i++){
            //rQuadTo
            mpath.rQuadTo(20, size, 40, 0);
            mpath.rQuadTo(20, -size, 40, 0);    
        }       

        mcanvas_bitmap.drawPath(mpath, Paintpath);

    // mcanvas_bitmap.drawCircle(300, 300, 150,paintnew );

        canvas.drawBitmap(mbitmap, 0, 0, null);
        canvas.drawText((float)currentprogress/maxprogress*100f+"",300,300, PaintText);


    }
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        width = getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec);
        height = getDefaultSize(getSuggestedMinimumHeight(), heightMeasureSpec);
        mbitmap=Bitmap.createBitmap(width, height, Config.ARGB_8888);
        mcanvas_bitmap=new Canvas(mbitmap);
    }
}

MainActivity(通过Handler修改currentprogress)

注:在布局中给出MyPathView 的id,通过id获得对象,修改currentprogress值

public class MainActivity_path extends Activity implements OnClickListener{
    private Button mbtn_pathview;
    private MyPathView mypathview;
     private int progress;
        private Handler mhanHandler=new Handler(){
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case 0x24:
                    progress++;
                    if(progress<=100){
                        mypathview.setCurrentprogress(progress);
                        mhanHandler.sendEmptyMessageDelayed(0x24, 200);
                    }
                    break;

                default:
                    break;
                }

            };
        };
  @Override
protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.path_view);
    mbtn_pathview=(Button) findViewById(R.id.btn_pathview);
    mypathview=(MyPathView) findViewById(R.id.mypathview);
    mbtn_pathview.setOnClickListener(this);
}
@Override
public void onClick(View v) {
    mhanHandler.sendEmptyMessageDelayed(0x24, 1000);

}
}

你可能感兴趣的:(Android 绘图进阶:仿360水纹进度球(可动正余弦曲线+xfermode))