Android 사용자 정의 컨트롤 은 테이프 수치 와 애니메이션 의 원형 진행 바 를 실현 합 니 다.

9409 단어 Android진도 표
본 고 는 다음 그림 에서 보 듯 이 안 드 로 이 드 사용자 정의 컨트롤 을 실현 하여 특정한 팀 이 특정한 시즌 의 포인트 수 와 승 장,마이너스,무승부 수 를 직관 적 으로 보 여줄 수 있다.

먼저 캔버스 에 대해 구역 을 나 누고 전체 컨트롤 은 상하 두 부분 으로 나 뉜 다.
위 에는 큰 링 이 있 고 링 중간 에 두 줄 의 문자 가 있어 어렵 지 않 습 니 다.원심 좌표 와 반지름 을 선택 한 후에 바로 그리 면 됩 니 다.문 자 를 그 리 는 것 도 마찬가지 입 니 다.
아래 부분 은 세 개의 작은 원호 진도 줄 이 고 호의 끝 에 작은 옹 골 진 원 을 그립 니 다.
먼저 좌표 와 반지름 을 선택 한 다음 에 먼저 세 개의 원 환 을 원호 형 진도 조 의 배경 으로 그립 니 다.
그 후에 12 시 부터 진도 호 를 그 려 서 원 환 의 원심 과 반지름 을 알 게 되 었 고 호 는 12 시 와 원 환 원심 의 오프셋 각도 에 대응 하 는 것 도 알 게 되 었 다.
삼각 함 수 를 통 해 진도 호 종점 좌 표를 계산 할 수 있 고 진도 호 종점 좌 표를 원심 으로 작은 실심 원 을 그리 면 된다.
애니메이션 효 과 는 Handler 의 postDelayed 방법 으로 다시 그리 기 를 터치 하면 실 현 됩 니 다.
프로젝트 에서 의 효 과 는 그림 과 같다.

테스트 코드 는 다음 과 같 습 니 다:

final Random random=new Random();
final ScoreBoardView myView=(ScoreBoardView)findViewById(R.id.custom_view);
myView.setOnClickListener(new View.OnClickListener(){
 @Override
 public void onClick(View v){
  myView.setColor(Color.BLUE);
  myView.setScore(random.nextInt(28));
  myView.setWinDrawLose(random.nextInt(12),random.nextInt(15),random.nextInt(26));
 }
});
전체 코드 는 다음 과 같 습 니 다:

public class ScoreBoardView extends View {
 private Context context;
 /*    */
 private int mColor;
 /*   ,   ,   ,   */
 private int mScore, mWinNumber, mDrawNumber, mLoseNumber;
 /*        */
 private final int FULL_SCORE = 30;
 /*     */
 DecelerateInterpolator mDecelerateInterpolator = new DecelerateInterpolator();
 /*      (    )*/
 private int mDuration = 10;
 /*           */
 private int mCurrentTime = 0;
 private TypedValue typedValue;
 private TypedValue typedValue1;
 private Handler mHandler = new Handler();
 private Runnable mAnimation = new Runnable() {
  @Override
  public void run() {
   if (mCurrentTime < mDuration) {
    mCurrentTime++;
    /*      onDraw,onDraw    postDelay     ,         */
    ScoreBoardView.this.invalidate();
   }
  }
 };
 /*    */
 private Paint paint = new Paint();
 /*    */
 private Paint paintText = new Paint();
 
 public ScoreBoardView(Context context) {
  super(context);
  this.context=context;
  init();
 }
 
 public ScoreBoardView(Context context, AttributeSet attrs) {
  super(context, attrs);
  this.context=context;
  init();
 }
 
 public ScoreBoardView(Context context, AttributeSet attrs, int defStyleAttr) {
  super(context, attrs, defStyleAttr);
  this.context=context;
  init();
 }
 
 private void init() {
  /*     ,    */
  mColor = Color.rgb(95, 112, 72);
  mScore = 0;
  mWinNumber = 0;
  mDrawNumber = 0;
  mLoseNumber = 0;
  typedValue=new TypedValue();
  typedValue1=new TypedValue();
  context.getTheme().resolveAttribute(R.attr.maintextclor, typedValue, true);
  context.getTheme().resolveAttribute(R.attr.maintextclor_reverse,typedValue1,true);
 }
 
 @Override
 protected void onDraw(Canvas canvas) {
  super.onDraw(canvas);
  /*        */
  float totalWidth = getWidth();
  float totalHeight = getHeight();
  /*
  * DecelerateInterpolator:        ,           。
  * AccelerateInterpolator:        ,           。
  * CycleInterpolator:        ,               
  * AccelerateDecelerateInterpolator:        ,             。
  * LinearInterpolator:        ,        。
  * */
  /*           */
  float AnimCurrentValue =mDecelerateInterpolator.getInterpolation(1.0f * mCurrentTime / mDuration);
 
  /*      */
  paint.setAntiAlias(true);
  paint.setStyle(Paint.Style.STROKE);
 
  /*   ,     */
  paint.setStrokeWidth(4);
  paint.setColor(mColor);
  /*            */
  float score_radius = totalHeight * 1 / 5, score_circle_x = totalWidth / 2, score_circle_y = totalHeight / 3;
  /*    */
  canvas.drawCircle(score_circle_x, score_circle_y, score_radius, paint);
  /*        */
  paintText.setAntiAlias(true);
  paintText.setStyle(Paint.Style.STROKE);
  /*         */
  /*Paint.Align.CENTER:The text is drawn centered horizontally on the x,y origin*/
  paintText.setTextAlign(Paint.Align.CENTER);
  /*           */
  paintText.setTextSize(score_radius * 3 / 4);
  paintText.setColor(getResources().getColor(typedValue.resourceId));
  /*          */
  canvas.drawText("" + mScore, score_circle_x, score_circle_y, paintText);
  /*          */
  paintText.setTextSize(score_radius * 1 / 4);
  paintText.setAlpha(80);
  /*        */
  canvas.drawText("  ", score_circle_x, score_circle_y + score_radius / 2, paintText);
 
  /*    ,        */
  paint.setStrokeWidth(4);
  paint.setAlpha(255);
  /*         */
  float small_radius = totalHeight / 10;
  /*        x  */
  float[] circleXs = new float[]{totalWidth / 2 - score_radius * 3 / 2,
          totalWidth / 2,
          totalWidth / 2 + score_radius * 3 / 2};
  /*        y  */
  float circleY = totalHeight * 3 / 4;
  /*            */
  float[] theta_values = new float[]{360 * mWinNumber / FULL_SCORE* AnimCurrentValue,
           360 * mDrawNumber / FULL_SCORE* AnimCurrentValue,
           360 * mLoseNumber / FULL_SCORE* AnimCurrentValue};
  /*      ,      */
  paint.setColor(getResources().getColor(typedValue1.resourceId));
  /*          */
  canvas.drawCircle(circleXs[0], circleY, small_radius, paint);// WIN   
  canvas.drawCircle(circleXs[1], circleY, small_radius, paint);// DRAW   
  canvas.drawCircle(circleXs[2], circleY, small_radius, paint);// LOSE   
  /*      ,       */
  paint.setColor(mColor);
  /*drawArc      3    ,    12        ,     270 */
  canvas.drawArc(new RectF(circleXs[0] - small_radius,
         circleY - small_radius,
         circleXs[0] + small_radius,
         circleY + small_radius),
      270, theta_values[0], false, paint);// WIN     
  canvas.drawArc(new RectF(circleXs[1] - small_radius,
         circleY - small_radius,
         circleXs[1] + small_radius,
         circleY + small_radius),
      270, theta_values[1], false, paint);// DRAW     
  canvas.drawArc(new RectF(circleXs[2] - small_radius,
         circleY - small_radius,
         circleXs[2] + small_radius,
         circleY + small_radius),
      270, theta_values[2], false, paint);// LOSE     
  /*           ,   */
  paint.setStyle(Paint.Style.FILL);
  /*    、    、    ,                    */
  canvas.drawCircle(circleXs[0] + small_radius * (float) Math.sin(theta_values[0] * Math.PI / 180),
    circleY - small_radius * (float) Math.cos(theta_values[0] * Math.PI / 180), 6, paint);// WIN     
  canvas.drawCircle(circleXs[1] + small_radius * (float) Math.sin(theta_values[1] * Math.PI / 180),
    circleY - small_radius * (float) Math.cos(theta_values[1] * Math.PI / 180), 6, paint);// DRAW     
  canvas.drawCircle(circleXs[2] + small_radius * (float) Math.sin(theta_values[2] * Math.PI / 180),
    circleY - small_radius * (float) Math.cos(theta_values[2] * Math.PI / 180), 6, paint);// LOSE     
 
  /*    */
  paintText.setColor(getResources().getColor(typedValue.resourceId));
  paintText.setTextSize(small_radius * 2 / 3);
  /*      ,              */
  Paint.FontMetrics fontMetrics = paint.getFontMetrics();
  float textBaseLineOffset = (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
  /*                  */
  canvas.drawText("" + (int)(mWinNumber * AnimCurrentValue), circleXs[0], circleY + textBaseLineOffset, paintText);
  canvas.drawText("" + (int)(mDrawNumber * AnimCurrentValue), circleXs[1], circleY + textBaseLineOffset, paintText);
  canvas.drawText("" + (int)(mLoseNumber * AnimCurrentValue), circleXs[2], circleY + textBaseLineOffset, paintText);
  /*      ,      */
  paintText.setTextSize(small_radius * 4 / 9);
  canvas.drawText("  ", circleXs[0], circleY - small_radius*4/3, paintText);
  canvas.drawText("  ", circleXs[1], circleY - small_radius*4/3, paintText);
  canvas.drawText("  ", circleXs[2], circleY - small_radius*4/3, paintText);
  /*20ms      */
  mHandler.postDelayed(mAnimation, 20);//    
 }
 
 public void setColor(int mColor) {
  this.mColor = mColor;
  invalidate();
 }
 
 public void setScore(int score) {
  this.mScore = score;
  invalidate();
 }
 
 public void setWinDrawLose(int win,int draw,int lose) {
  this.mWinNumber = win;
  this.mDrawNumber = draw;
  this.mLoseNumber = lose;
  mCurrentTime =0;
  invalidate();
 }
}
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기