您好,登錄后才能下訂單哦!
一個自定義View,記錄一下思路和代碼以備以后使用。
思路:
1.首先要畫一個圓形圖片和一個圓形背景圖(通過自定義View);
2.自定義View基本步驟初始化屬性,測量寬高和中心點(diǎn),然后繪制圖片;
3.通過handler實(shí)現(xiàn)圖片的角度旋轉(zhuǎn).然后然后就慢慢擼.
效果圖:
1、廢話不多直接上代碼
public class MusicPlayerView extends View { private static final long ROTATE_DELAY = 5;//旋轉(zhuǎn)動作時間 private int mRotateDegrees;//旋轉(zhuǎn)的角度 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(); } /** * 判讀是否在旋轉(zhuǎn) * @return */ public boolean isRotating() { return isRotating; } /** * 開始旋轉(zhuǎn)圖片 */ public void start(){ isRotating=true; mRotate.removeCallbacksAndMessages(null); mRotate.postDelayed(mRunnableRotate,ROTATE_DELAY); postInvalidate(); } /** * 停止圖片旋轉(zhuǎn) */ public void stop(){ isRotating = false; postInvalidate(); } /** * 通過本地圖片設(shè)置封面圖 */ public void setCoverDrawable(int coverDrawable) { Drawable drawable = getContext().getResources().getDrawable(coverDrawable); mBitmapCover = drawableToBitmap(drawable); createShader(); postInvalidate(); } /** * 網(wǎng)絡(luò)圖片加載使用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(); } /** * 測量寬高,設(shè)置中心點(diǎn)中心點(diǎn)位置,創(chuàng)建陰影 * * @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); //取寬高最小值設(shè)置圖片寬高 mWidth = minSide; mHeight = minSide; setMeasuredDimension(mWidth, mHeight); //重新設(shè)置寬高 //中心點(diǎn)位置 mCenterX = mWidth / 2f; mCenterY = mHeight / 2f; //設(shè)置圖片顯示位置 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) { //如果封面為為創(chuàng)建默認(rèn)顏色 mBitmapCover = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888); mBitmapCover.eraseColor(mCoverColor); } mCoverScale = ((float) mWidth) / (float) mBitmapCover.getWidth(); //創(chuàng)建縮放后的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轉(zhuǎn)換為位圖 為BitmapShader準(zhǔn)備 * * @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.差點(diǎn)忘記一個attrs屬性
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="play_view"> <attr name="cover" format="integer"/> </declare-styleable> </resources>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。