Android开发旋转圆形图片自定义View

撸了一个自定义View,记录一下思路和代码以备以后使用.
思路:
1,首先要画一个圆形图片和一个圆形背景图(通过自定义View);
2,自定义View基本步骤初始化属性,测量宽高和中心点,然后绘制图片;
3,通过handler实现图片的角度旋转.然后然后就慢慢撸.
效果图:
这里写图片描述
1,废话不多直接上代码

public class MusicPlayerView extends View {
    private static final long ROTATE_DELAY = 5;//旋转动作时间
    private int mRotateDegrees;//旋转的角度
    private Handler mRotate;
    private int mWidth;
    private int mHeight;
    private float mCenterX;
    private float mCenterY;
    private RectF rectF;
    private Bitmap mBitmapCover;
    private float mCoverScale;
    private BitmapShader mShader;
    private Paint paint;
    private boolean isRotating;
    private final Runnable mRunnableRotate = new Runnable() {
        @Override
        public void run() {
            if (isRotating) {
                updateCoverRotate();
                mRotate.postDelayed(mRunnableRotate, ROTATE_DELAY);
            }
        }
    };

    /**
     * 更新封面角度,重新绘制图片
     */

    private void updateCoverRotate() {
        mRotateDegrees += 1;
        mRotateDegrees = mRotateDegrees % 360;
        postInvalidate();
    }

    /**
     * 判读是否在旋转
     * @return
     */
    public boolean isRotating() {
        return isRotating;
    }

    /**
     * 开始旋转图片
     */
    public void start(){
        isRotating=true;
        mRotate.removeCallbacksAndMessages(null);
        mRotate.postDelayed(mRunnableRotate,ROTATE_DELAY);
        postInvalidate();
    }

    /**
     * 停止图片旋转
     */
    public void stop(){
        isRotating = false;
        postInvalidate();
    }

    /**
     * 通过本地图片设置封面图
     */
    public void setCoverDrawable(int coverDrawable) {
        Drawable drawable = getContext().getResources().getDrawable(coverDrawable);
        mBitmapCover = drawableToBitmap(drawable);
        createShader();
        postInvalidate();
    }
    /**
     * 网络图片加载使用Picasso图片加载工具
     *
     * @param imageUrl
     */
    public void setCoverURL(String imageUrl) {
        Picasso.with(getContext()).load(imageUrl).into(target);
    }

    public MusicPlayerView(Context context) {
        super(context);
        init(context, null);
    }

    public MusicPlayerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public MusicPlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context, attrs);
    }

    /**
     * 初始化View资源
     *
     * @param context
     * @param attrs
     */
    private void init(Context context, AttributeSet attrs) {
        setWillNotDraw(false);
        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.play_view);
        Drawable mDrawableCover = a.getDrawable(R.styleable.play_view_cover);
        if (mDrawableCover != null) {
            mBitmapCover = drawableToBitmap(mDrawableCover);
        }
        a.recycle();
        mRotateDegrees = 0;
        //通过handler更新图片角度
        mRotate = new Handler();
        rectF = new RectF();
    }

    /**
     * 测量宽高,设置中心点中心点位置,创建阴影
     *
     * @param widthMeasureSpec
     * @param heightMeasureSpec
     */

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        mWidth = MeasureSpec.getSize(widthMeasureSpec);
        mHeight = MeasureSpec.getSize(heightMeasureSpec);
        int minSide = Math.min(mWidth, mHeight);    //取宽高最小值设置图片宽高
        mWidth = minSide;
        mHeight = minSide;
        setMeasuredDimension(mWidth, mHeight);      //重新设置宽高
        //中心点位置
        mCenterX = mWidth / 2f;
        mCenterY = mHeight / 2f;
        //设置图片显示位置
        rectF.set(20.0f, 20.0f, mWidth - 20.0f, mHeight - 20.0f);
        createShader();
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (mShader == null) {
            return;
        }
        //画封面图片 判读图片的中心距离xy,算出边角大小,然后画圆
        float radius = mCenterX <= mCenterY ? mCenterX - 75.0f : mCenterY - 75.0f;
        canvas.rotate(mRotateDegrees, mCenterX, mCenterY);
        canvas.drawCircle(mCenterX, mCenterY, radius, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:

                break;
        }
        return super.onTouchEvent(event);
    }



    private Target target = new Target() {
        @Override
        public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
            mBitmapCover = bitmap;
            createShader();
            postInvalidate();
        }

        @Override
        public void onBitmapFailed(Drawable errorDrawable) {

        }

        @Override
        public void onPrepareLoad(Drawable placeHolderDrawable) {

        }
    };
    private int mCoverColor = Color.YELLOW;

    private void createShader() {
        if (mWidth == 0) {
            return;
        }
        if (mBitmapCover == null) {    //如果封面为为创建默认颜色
            mBitmapCover = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
            mBitmapCover.eraseColor(mCoverColor);
        }
        mCoverScale = ((float) mWidth) / (float) mBitmapCover.getWidth();
        //创建缩放后的bitmap
        mBitmapCover = Bitmap.createScaledBitmap(mBitmapCover,
                (int) (mBitmapCover.getWidth() * mCoverScale), (int) (mBitmapCover.getHeight() * mCoverScale), true);
        mShader = new BitmapShader(mBitmapCover, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(mShader);
    }

    /**
     * 将drawable转换为位图 为BitmapShader准备
     *
     * @param drawable
     * @return
     */
    private Bitmap drawableToBitmap(Drawable drawable) {
        if (drawable instanceof BitmapDrawable) {
            return ((BitmapDrawable) drawable).getBitmap();
        }
        int width = drawable.getIntrinsicWidth();
        width = width > 0 ? width : 1;
        int height = drawable.getIntrinsicHeight();
        height = height > 0 ? height : 1;
        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);
        return bitmap;
    }
}

2.差点忘记一个attrs属性

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <declare-styleable name="play_view">
        <attr name="cover"  format="integer"/>
    </declare-styleable>
</resources>
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值