AndroidカスタムViewはQQ音楽の中で円形の回転皿を実現します。


QQ音楽の中で丸い回転の皿
考え方の分析:
1、オンメアスでView全体の幅と高さを測定した後、幅の高さを設定します。
2、私達のresの写真資源を取得した後、ondrawの方法で円形の写真を描きます。
3、HandlerからRunnableを送信して、回転スレッドを起動します。(丸い顔写真を作りたいなら、このステップは削除できます。)
4、レイアウトに私達のViewを使う
効果図:

私たちの変数情報を貼り付けます。

//view     
int mHeight = 0; 
int mWidth = 0; 
//     
Bitmap bitmap = null; 
//          
int radius = 0; 
//        
Matrix matrix = new Matrix(); 
//        
int degrees = 0; 
ステップ1:全体の幅と高さを測定し、幅の高さを設定する。

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 //    View     
 mWidth = measuredWidth(widthMeasureSpec); 
 mHeight= measuredHeight(heightMeasureSpec); 
 setMeasuredDimension(mWidth, mHeight); 
} 
 
private int measuredWidth(int widthMeasureSpec) { 
 int Mode = MeasureSpec.getMode(widthMeasureSpec); 
 int Size = MeasureSpec.getSize(widthMeasureSpec); 
 if (Mode == MeasureSpec.EXACTLY) { 
  mWidth = Size; 
 } else { 
  //        
  int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth(); 
  if (Mode == MeasureSpec.AT_MOST) { 
   //    Padding    ,      View   
   mWidth = Math.min(value, Size); 
  } 
 } 
 return mWidth; 
} 
 
private int measuredHeight(int heightMeasureSpec) { 
 int Mode = MeasureSpec.getMode(heightMeasureSpec); 
 int Size = MeasureSpec.getSize(heightMeasureSpec); 
 if (Mode == MeasureSpec.EXACTLY) { 
  mHeight = Size; 
 } else { 
  //        
  int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight(); 
  if (Mode == MeasureSpec.AT_MOST) { 
   //    Padding    ,      View   
   mHeight = Math.min(value, Size); 
  } 
 } 
 return mHeight; 
} 
措置の2:私達のresのピクチャーの資源を獲得した後に、ondraw方法の中で円形のピクチャーを描きます。

//  res      
bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); 
@Override 
protected void onDraw(Canvas canvas) { 
 super.onDraw(canvas); 
 canvas.concat(matrix); 
 //        View       
 radius = Math.min(mWidth, mHeight); 
 //          ,        
 bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false); 
 //      
 canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null); 
 matrix.reset(); 
} 
 
private Bitmap createCircleImage(Bitmap source, int radius) { 
 Paint paint = new Paint(); 
 paint.setAntiAlias(true); 
 Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888); 
 //            
 Canvas canvas = new Canvas(target); 
 //       
 canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint); 
 //  SRC_IN            
 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
 //    , (0,0)  
 canvas.drawBitmap(source, 0, 0, paint); 
 return target; 
} 
ステップ3:RunnableをHandlerで送信することにより、回転スレッドを起動する。

//     
mHandler.post(runnable); 
[java] view plain copy  CODE              
//-----------    ----------- 
Handler mHandler = new Handler(); 
Runnable runnable = new Runnable() { 
 @Override 
 public void run() { 
  matrix.postRotate(degrees++, radius / 2, radius / 2); 
  //   
  invalidate(); 
  mHandler.postDelayed(runnable, 50); 
 } 
}; 
ステップ4:レイアウトの中で私達のViewを使います。

<com.handsome.cycle.MyCycleView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" /> 
次は全体のソースコードです。

public class MyCycleView extends View { 
 
 //view     
 int mHeight = 0; 
 int mWidth = 0; 
 //     
 Bitmap bitmap = null; 
 //          
 int radius = 0; 
 //        
 Matrix matrix = new Matrix(); 
 //        
 int degrees = 0; 
 
 //-----------    ----------- 
 Handler mHandler = new Handler(); 
 Runnable runnable = new Runnable() { 
  @Override 
  public void run() { 
   matrix.postRotate(degrees++, radius / 2, radius / 2); 
   //   
   invalidate(); 
   mHandler.postDelayed(runnable, 50); 
  } 
 }; 
 
 public MyCycleView(Context context) { 
  super(context); 
  initView(); 
 } 
 
 public MyCycleView(Context context, AttributeSet attrs) { 
  super(context, attrs); 
  initView(); 
 } 
 
 public MyCycleView(Context context, AttributeSet attrs, int defStyleAttr) { 
  super(context, attrs, defStyleAttr); 
  initView(); 
 } 
 
 public void initView() { 
  //  res      
  bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.icon); 
  //     
  mHandler.post(runnable); 
 } 
 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
  super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
  //    View     
  mWidth = measuredWidth(widthMeasureSpec); 
  mHeight = measuredHeight(heightMeasureSpec); 
  setMeasuredDimension(mWidth, mHeight); 
 } 
 
 private int measuredWidth(int widthMeasureSpec) { 
  int Mode = MeasureSpec.getMode(widthMeasureSpec); 
  int Size = MeasureSpec.getSize(widthMeasureSpec); 
  if (Mode == MeasureSpec.EXACTLY) { 
   mWidth = Size; 
  } else { 
   //        
   int value = getPaddingLeft() + getPaddingRight() + bitmap.getWidth(); 
   if (Mode == MeasureSpec.AT_MOST) { 
    //    Padding    ,      View   
    mWidth = Math.min(value, Size); 
   } 
  } 
  return mWidth; 
 } 
 
 private int measuredHeight(int heightMeasureSpec) { 
  int Mode = MeasureSpec.getMode(heightMeasureSpec); 
  int Size = MeasureSpec.getSize(heightMeasureSpec); 
  if (Mode == MeasureSpec.EXACTLY) { 
   mHeight = Size; 
  } else { 
   //        
   int value = getPaddingTop() + getPaddingBottom() + bitmap.getHeight(); 
   if (Mode == MeasureSpec.AT_MOST) { 
    //    Padding    ,      View   
    mHeight = Math.min(value, Size); 
   } 
  } 
  return mHeight; 
 } 
 
 @Override 
 protected void onDraw(Canvas canvas) { 
  super.onDraw(canvas); 
  canvas.concat(matrix); 
  //        View       
  radius = Math.min(mWidth, mHeight); 
  //          ,        
  bitmap = Bitmap.createScaledBitmap(bitmap, radius, radius, false); 
  //      
  canvas.drawBitmap(createCircleImage(bitmap, radius), 0, 0, null); 
  matrix.reset(); 
 } 
 
 private Bitmap createCircleImage(Bitmap source, int radius) { 
  Paint paint = new Paint(); 
  paint.setAntiAlias(true); 
  Bitmap target = Bitmap.createBitmap(radius, radius, Bitmap.Config.ARGB_8888); 
  //            
  Canvas canvas = new Canvas(target); 
  //       
  canvas.drawCircle(radius / 2, radius / 2, radius / 2, paint); 
  //  SRC_IN            
  paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); 
  //    , (0,0)  
  canvas.drawBitmap(source, 0, 0, paint); 
  return target; 
 } 
} 
以上が本文の全部です。皆さんの勉強に役に立つように、私たちを応援してください。