Android自定义View旋转圆形图片
更新时间:2018年01月24日 08:44:43 作者:WhatYouSeeMe
这篇文章主要为大家详细介绍了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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
相关文章
Android入门之Fragment嵌套Fragment的用法详解
这篇文章主要为大家详细介绍了Android中如何实现Fragment嵌套Fragment的相关资料,文中的示例代码讲解详细,具有一定的借鉴价值,需要的可以参考一下2023-02-02Android短信验证码监听解决onChange多次调用的方法
本篇文章主要介绍了Android短信验证码监听解决onChange多次调用的方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下2018-03-03
最新评论