Android自定义View,实现Progress(水波纹动画)

来源:互联网 发布:在手机淘宝怎么改评论 编辑:程序博客网 时间:2024/05/13 21:49

这里写图片描述

代码贴出来,方便自己回顾和大家借鉴
下载Demo地址:自定义 Progress(水波纹动画)

实现方法:

xml文件`

<com.example.jiaojiao.waveprogressdemo.DynamicWave                android:id="@+id/dw_progress"                android:background="#ffffff"                android:layout_width="80dp"                android:layout_height="80dp"                android:layout_margin="5dp"                android:layout_centerInParent="true" />`   

自定义View

/** * 简介:波浪进度条 */public class DynamicWave extends View {    // 圆    private Paint paint;    //    private int roundWidth = 10;    //    private int roundHeight = 10;    private int roundWidth = 8;    private int roundHeight = 8;    private Paint paint2;    // 波纹颜色    private static int WAVE_PAINT_COLOR;// = 0x880000aa;    // y = Asin(wx+b)+h    private float STRETCH_FACTOR_A=7;    private static final int OFFSET_Y = 0;    // 第一条水波移动速度    private static final int TRANSLATE_X_SPEED_ONE = 1;    // 第二条水波移动速度    private static final int TRANSLATE_X_SPEED_TWO = 2;    private float mCycleFactorW;    private int mTotalWidth, mTotalHeight;    private float[] mYPositions;    private float[] mResetOneYPositions;    private float[] mResetTwoYPositions;    private int mXOffsetSpeedOne;    private int mXOffsetSpeedTwo;    private int mXOneOffset;    private int mXTwoOffset;    private Paint mWavePaint;    private Paint mWavePaint2;    private Paint mWavePaint3;    private DrawFilter mDrawFilter;    private float currentY=50;    private float lastY=0;    private Bitmap bitmaps;    public DynamicWave(Context context, AttributeSet attrs) {        super(context, attrs);        // 圆        if (attrs != null) {            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundAngleImageView);            assert a != null;            roundWidth = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundWidth, roundWidth);            roundHeight = a.getDimensionPixelSize(R.styleable.RoundAngleImageView_roundHeight, roundHeight);        } else {            float density = context.getResources().getDisplayMetrics().density;            roundWidth = (int) (roundWidth * density);            roundHeight = (int) (roundHeight * density);        }        paint = new Paint();        paint.setColor(Color.WHITE);        paint.setAntiAlias(true);        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));        paint2 = new Paint();        paint2.setXfermode(null);        STRETCH_FACTOR_A=2.2f*getResources().getDisplayMetrics().density;        // 将dp转化为px,用于控制不同分辨率上移动速度基本一致        mXOffsetSpeedOne = (int) (TRANSLATE_X_SPEED_ONE*getResources().getDisplayMetrics().density);//UIUtils.dipToPx(context, TRANSLATE_X_SPEED_ONE);        mXOffsetSpeedTwo = (int) (TRANSLATE_X_SPEED_TWO*getResources().getDisplayMetrics().density);//UIUtils.dipToPx(context, TRANSLATE_X_SPEED_TWO);        WAVE_PAINT_COLOR=context.getResources().getColor(R.color.orange);        // 初始绘制波纹的画笔        mWavePaint = new Paint();        // 去除画笔锯齿        mWavePaint.setAntiAlias(true);        // 设置风格为实线        mWavePaint.setStyle(Paint.Style.FILL);        // 设置画笔颜色        mWavePaint.setColor(WAVE_PAINT_COLOR);        mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);        // 第二条波纹        mWavePaint2=new Paint();        // 去除画笔锯齿        mWavePaint2.setAntiAlias(true);        // 设置风格为实线        mWavePaint2.setStyle(Paint.Style.FILL);        // 设置画笔颜色        mWavePaint2.setColor(context.getResources().getColor(R.color.dynamic_wave_orange));    }    @SuppressWarnings("NullableProblems")    @Override    public void draw(Canvas canvas) {        Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas2 = new Canvas(bitmap);        super.draw(canvas2);        canvas.drawBitmap(toRoundCorner(bitmap, 1), 0, 0, paint2);    }    // 当前进度    public void setProgress(float current){        if (-1==current){            currentY=-1;        }else {            currentY=current-STRETCH_FACTOR_A;        }        invalidate();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        // 从canvas层面去除绘制时锯齿        canvas.setDrawFilter(mDrawFilter);        if (0<=currentY){            float js=currentY/100*getHeight();            if(0<=js){                lastY=js;            }else {                lastY=0;            }        }else {            lastY=0;            currentY=-1;        }        resetPositonY();        for (int i = 0; i < mTotalWidth; i++) {            // 减400只是为了控制波纹绘制的y的在屏幕的位置,大家可以改成一个变量,然后动态改变这个变量,从而形成波纹上升下降效果            // 绘制第一条水波纹            canvas.drawLine(i, mTotalHeight - mResetOneYPositions[i] - lastY, i,                    mTotalHeight,                    mWavePaint2);            // 绘制第二条水波纹            canvas.drawLine(i, mTotalHeight - mResetTwoYPositions[i] - lastY, i,                    mTotalHeight,                    mWavePaint);        }        // 改变两条波纹的移动点        mXOneOffset += mXOffsetSpeedOne;        mXTwoOffset += mXOffsetSpeedTwo;        // 如果已经移动到结尾处,则重头记录        if (mXOneOffset >= mTotalWidth) {            mXOneOffset = 0;        }        if (mXTwoOffset > mTotalWidth) {            mXTwoOffset = 0;        }        // 引发view重绘,一般可以考虑延迟20-30ms重绘,空出时间片        //postInvalidate();        if (-1!=currentY){            postInvalidateDelayed(30);        }    }    private void resetPositonY() {        // mXOneOffset代表当前第一条水波纹要移动的距离        int yOneInterval = mYPositions.length - mXOneOffset;        // 使用System.arraycopy方式重新填充第一条波纹的数据        System.arraycopy(mYPositions, mXOneOffset, mResetOneYPositions, 0, yOneInterval);        System.arraycopy(mYPositions, 0, mResetOneYPositions, yOneInterval, mXOneOffset);        int yTwoInterval = mYPositions.length - mXTwoOffset;        System.arraycopy(mYPositions, mXTwoOffset, mResetTwoYPositions, 0,                yTwoInterval);        System.arraycopy(mYPositions, 0, mResetTwoYPositions, yTwoInterval, mXTwoOffset);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        // 记录下view的宽高        mTotalWidth = w;        mTotalHeight = h;        // 用于保存原始波纹的y值        mYPositions = new float[mTotalWidth];        // 用于保存波纹一的y值        mResetOneYPositions = new float[mTotalWidth];        // 用于保存波纹二的y值        mResetTwoYPositions = new float[mTotalWidth];        // 将周期定为view总宽度        mCycleFactorW = (float) (2 * Math.PI / mTotalWidth);        // 根据view总宽度得出所有对应的y值        for (int i = 0; i < mTotalWidth; i++) {            mYPositions[i] = (float) (STRETCH_FACTOR_A * Math.sin(mCycleFactorW * i) + OFFSET_Y);        }    }    // 圆    public static Bitmap toRoundCorner(Bitmap bitmap, float ratio) {        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),                bitmap.getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas = new Canvas(output);        final Paint paint = new Paint();        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());        final RectF rectF = new RectF(rect);        paint.setAntiAlias(true);        canvas.drawARGB(0, 0, 0, 0);        canvas.drawRoundRect(rectF, bitmap.getWidth() / ratio,                bitmap.getHeight() / ratio, paint);        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));        canvas.drawBitmap(bitmap, rect, rect, paint);        return output;    }    private void drawLiftUp(Canvas canvas) {        Path path = new Path();        path.moveTo(0, roundHeight);        path.lineTo(0, 0);        path.lineTo(roundWidth, 0);        path.arcTo(new RectF(                        0,                        0,                        roundWidth * 2,                        roundHeight * 2),                -90,                -90);        path.close();        canvas.drawPath(path, paint);    }    private void drawLiftDown(Canvas canvas) {        Path path = new Path();        path.moveTo(0, getHeight() - roundHeight);        path.lineTo(0, getHeight());        path.lineTo(roundWidth, getHeight());        path.arcTo(new RectF(                        0,                        getHeight() - roundHeight * 2,                        roundWidth * 2,                        getHeight()),                90,                90);        path.close();        canvas.drawPath(path, paint);    }    private void drawRightDown(Canvas canvas) {        Path path = new Path();        path.moveTo(getWidth() - roundWidth, getHeight());        path.lineTo(getWidth(), getHeight());        path.lineTo(getWidth(), getHeight() - roundHeight);        path.arcTo(new RectF(                getWidth() - roundWidth * 2,                getHeight() - roundHeight * 2,                getWidth(),                getHeight()), 0, 90);        path.close();        canvas.drawPath(path, paint);    }    private void drawRightUp(Canvas canvas) {        Path path = new Path();        path.moveTo(getWidth(), roundHeight);        path.lineTo(getWidth(), 0);        path.lineTo(getWidth() - roundWidth, 0);        path.arcTo(new RectF(                        getWidth() - roundWidth * 2,                        0,                        getWidth(),                        roundHeight * 2),                -90,                90);        path.close();        canvas.drawPath(path, paint);    }}

Activity

    private DynamicWave dw_progress;    private TextView tv_at_present;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();    }    private void initView() {        dw_progress = (DynamicWave) findViewById(R.id.dw_progress);        tv_at_present = (TextView) findViewById(R.id.tv_at_present);        tv_at_present.setText("30%");        dw_progress.setProgress(30);    }
1 0
原创粉丝点击