Android 사용자 정의 view 의 모방 결제 보 깨 신용 계기판 예제

14751 단어 android가짜 신용
사용자 정의 view 연습 가짜 알 리 페 이 참깨 신용 계기판
대비 그림:


우선 일부 속성 을 사용자 정의 할 수 있 습 니 다.

<?xml version="1.0" encoding="utf-8"?> 
<resources> 
  <declare-styleable name="RoundIndicatorView"> 
    <!--    --> 
    <attr name="maxNum" format="integer"/> 
    <!--      --> 
    <attr name="startAngle" format="integer"/> 
    <!--       --> 
    <attr name="sweepAngle" format="integer"/> 
  </declare-styleable> 
</resources> 
이 어 구조 방법 에서 사용자 정의 속성 과 붓 을 초기 화 합 니 다.

private void initAttr(AttributeSet attrs) { 
  TypedArray array = context.obtainStyledAttributes(attrs,R.styleable.RoundIndicatorView); 
  maxNum = array.getInt(R.styleable.RoundIndicatorView_maxNum,500); 
  startAngle = array.getInt(R.styleable.RoundIndicatorView_startAngle,160); 
  sweepAngle = array.getInt(R.styleable.RoundIndicatorView_sweepAngle,220); 
  //        
  sweepInWidth = dp2px(8);  
  sweepOutWidth = dp2px(3);  
  array.recycle(); 
} 
 
private void initPaint() { 
  paint = new Paint(Paint.ANTI_ALIAS_FLAG); 
  paint.setDither(true); 
  paint.setStyle(Paint.Style.STROKE); 
  paint.setColor(0xffffffff); 
  paint_2 = new Paint(Paint.ANTI_ALIAS_FLAG); 
  paint_3 = new Paint(Paint.ANTI_ALIAS_FLAG); 
  paint_4 = new Paint(Paint.ANTI_ALIAS_FLAG); 
} 
다음은 onMeasure 를 다시 쓰 는 것 도 간단 합 니 다.확정 값 이 아 닌 300*400 의 크기 를 직접 지정 합 니 다.

@Override 
 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
 
  super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 
  int wSize = MeasureSpec.getSize(widthMeasureSpec); 
 
  int wMode = MeasureSpec.getMode(widthMeasureSpec); 
 
  int hSize = MeasureSpec.getSize(heightMeasureSpec); 
 
  int hMode = MeasureSpec.getMode(heightMeasureSpec); 
 
 
 
  if (wMode == MeasureSpec.EXACTLY ){ 
 
    mWidth = wSize; 
 
  }else { 
 
    mWidth =dp2px(300); 
 
  } 
 
  if (hMode == MeasureSpec.EXACTLY ){ 
 
    mHeight= hSize; 
 
  }else { 
 
    mHeight =dp2px(400); 
 
  } 
 
  setMeasuredDimension(mWidth,mHeight); 
 
} 
핵심 부분 인 onDraw 가 왔 습 니 다.원 의 반지름 을 구조 방법 에서 설정 하지 않도록 주의 하 세 요.그 때 는 view 의 너비 와 높 은 값 을 얻 을 수 없 기 때문에 저 는 onDraw 방법 에서 반지름 을 설정 합 니 다.기본 값 은 view 너비 의 1/4 입 니 다.원점 을 view 의 중심 으로 이동:

@Override 
protected void onDraw(Canvas canvas) { 
  super.onDraw(canvas); 
  radius = getMeasuredWidth()/4; //           ,         
  canvas.save(); 
  canvas.translate(mWidth/2,(mWidth)/2); 
  drawRound(canvas); //      
  drawScale(canvas);//    
  drawIndicator(canvas); //       
  drawCenterText(canvas);//       
  canvas.restore(); 
} 
절차 가 뚜렷 하고 순서대로 계기판 의 네 부분 을 그 려 서 우 리 는 한 부분 씩 본다.
drawRound():이 건 간단 합 니 다.내외 원호 에 필요 한 속성 이 정의 되 었 습 니 다.붓 은 흰색 입 니 다.setAlpha()를 통 해 투명 도 를 설정 합 니 다.범 위 는 00~ff 입 니 다.

private void drawRound(Canvas canvas) { 
  canvas.save(); 
  //   
  paint.setAlpha(0x40); 
  paint.setStrokeWidth(sweepInWidth); 
  RectF rectf = new RectF(-radius,-radius,radius,radius); 
  canvas.drawArc(rectf,startAngle,sweepAngle,false,paint); 
  //   
  paint.setStrokeWidth(sweepOutWidth); 
  int w = dp2px(10); 
  RectF rectf2 = new RectF(-radius-w , -radius-w , radius+w , radius+w); 
  canvas.drawArc(rectf2,startAngle,sweepAngle,false,paint); 
  canvas.restore(); 
} 
제1 부분 완성,그림 참조

drawScale():사용자 정의 view 글 을 몇 편 보 았 다 면 회전 캔버스 로 눈금 과 문 자 를 그 리 는 방법 을 알 고 있 을 것 입 니 다.canvas.rotate 를 호출 하면 캔버스 를 회전 시 킬 수 있 습 니 다.음 수 는 시계 방향 을 대표 합 니 다.여기 서 우 리 는 시작 위 치 를 원점 바로 위,즉 270 도 까지 회전 시 켜 눈금 과 문자 의 좌 표를 잘 계산 할 계획 입 니 다.그림 을 다 그 릴 때마다 시계 반대 방향 으로 눈금 간격 을 돌려 그림 이 끝 날 때 까지 순환 합 니 다.우 리 는 원 도 를 살 펴 보 자.굵 은 눈금 선 은 모두 6 개 이 고 숫자의 눈금 은 다시 굵 은 눈금 선 아래 에 있 으 며 두 개의 굵 은 눈금 선 사이 에 5 개의 가 는 눈금 선 이 있 고 중간 에 있 는 세분 선 아래 에 대응 하 는 문자 가 있다.우 리 는 스 캔 한 각 도 를 30 으로 나 누 면 각 눈금 의 간격 이 고 판단 을 통 해 대응 하 는 눈금 과 문 자 를 그 릴 수 있다.
텍스트 의 너비 와 높이 를 얻 는 방법 은 두 가지 가 있 습 니 다.하 나 는 paint.measuretext(text)로 문자 의 폭 을 측정 하고 반환 값 유형 은 float 이지 만 높이 를 얻 지 못 합 니 다.다른 하 나 는 Rect rect=new Rect();paint.getTextBounds(text,0,text.length(),rect); 텍스트 의 속성 을 rect 에 넣 는 것 은 int 값 에 불과 합 니 다.우리 가 그린 문 자 는 매우 작 기 때문에 첫 번 째 로 높이 가 필요 하지 않 으 면 사용 하 는 것 이 좋 습 니 다.
또한,나 는 문 자 를 그 릴 때 좌표 값 은 문자 의 왼쪽 아래 각 을 대표 하고 일반적인 왼쪽 상단 과 다 르 기 때문에 canvas.drawText 에서 들 어 오 는 xy 좌 표 는 text 의 왼쪽 아래 좌표 이다.

private String[] text ={"  ","  ","  ","  ","  "}; 
private void drawScale(Canvas canvas) { 
  canvas.save(); 
  float angle = (float)sweepAngle/30;//     
  canvas.rotate(-270+startAngle); //            (270) 
  for (int i = 0; i <= 30; i++) { 
    if(i%6 == 0){  //         
      paint.setStrokeWidth(dp2px(2)); 
      paint.setAlpha(0x70); 
      canvas.drawLine(0, -radius-sweepInWidth/2,0, -radius+sweepInWidth/2+dp2px(1), paint); 
      drawText(canvas,i*maxNum/30+"",paint); 
    }else {     //     
      paint.setStrokeWidth(dp2px(1)); 
      paint.setAlpha(0x50); 
      canvas.drawLine(0,-radius-sweepInWidth/2,0, -radius+sweepInWidth/2, paint); 
    } 
    if(i==3 || i==9 || i==15 || i==21 || i==27){ //        
      paint.setStrokeWidth(dp2px(2)); 
      paint.setAlpha(0x50); 
      drawText(canvas,text[(i-3)/6], paint); 
    } 
    canvas.rotate(angle); //    
  } 
  canvas.restore(); 
} 
  private void drawText(Canvas canvas ,String text ,Paint paint) { 
    paint.setStyle(Paint.Style.FILL); 
    paint.setTextSize(sp2px(8)); 
    float width = paint.measureText(text); //  getTextBounds  ,          float,     
//    Rect rect = new Rect(); 
//    paint.getTextBounds(text,0,text.length(),rect); 
    canvas.drawText(text,-width/2 , -radius + dp2px(15),paint); 
    paint.setStyle(Paint.Style.STROKE); 
  } 
두 번 째 부분 이 끝나 면 그림 을 보 세 요.

draw Indicator:이 단 계 는 화 외 원호 의 진도 값 입 니 다.원 도 를 관찰 한 결과 세 가지 문 제 를 해결 해 야 합 니 다.진 도 를 나타 내 는 라디에이터 값 과 작은 원점 의 좌 표 는 어떻게 계산 하고 진도 값 의 투명 도 점 변 은 어떻게 실현 합 니까?작은 원점 이 광원 처럼 가장자리 가 모호 한 효 과 는 어떻게 실현 합 니까?
좌표 계산 에 있어 서도 비교적 간단 합 니 다.현재 값 을 최대 치 에 비교 하고 하나의 비례 를 얻 으 면 진도 조 가 스 캔 한 라디안 을 계산 할 수 있 습 니 다.작은 원점 은 진도 조 의 끝 을 그립 니 다.각 도 는 이미(시작 각도+스 캔 한 각도)가 있 습 니 다.삼각함수 로 계산 하면 됩 니 다.
색상 그 라 데 이 션 에 대해 서 는 paint 의 shader 로 렌 더 링 할 수 있 습 니 다.5 개의 키 가 있 습 니 다.
  • BitmapShader 비트 맵
  • Linear Gradient 선형 그 라 데 이 션
  • RadialGradient 광속 점 변
  • SweetGradient 경사도 점차 변화
  • ComposeShader 혼합 그 라 데 이 션
  •  우 리 는 경사도 그 라 데 이 션 을 사용 하여 이 루어 집 니 다.좌표 와 하나의 색상 배열 에 들 어가 면 색상 에 대한 경사도 그 라 데 이 션 을 실현 할 수 있 습 니 다.여기 서 우 리 는 색상 에 대한 수정 은 당연히 투명 도 를 수정 할 뿐 입 니 다.우 리 는 32 비트 의 색상 값 8 위 가 투명 도 를 나타 내 는 것 을 알 고 있 습 니 다.
    작은 도 트 에 광원 과 같은 가장자리 퍼 지 효과 가 있 습 니 다.저 는 paint 의 setMask Filter 를 사 용 했 습 니 다.그 중 하 나 는 BlurMask Filter 가 가장자리 퍼 지 효 과 를 실현 할 수 있 습 니 다~(다른 방법 이 있 는 지 모 르 겠 습 니 다)   코드
    
    private int[] indicatorColor = {0xffffffff,0x00ffffff,0x99ffffff,0xffffffff}; 
    여기 색상 배열 이 이렇게 값 을 추출 하 는 이 유 는 글 마지막 에 설명 합 니 다.
    
    private void drawIndicator(Canvas canvas) { 
      canvas.save(); 
      paint_2.setStyle(Paint.Style.STROKE); 
      int sweep; 
      if(currentNum<=maxNum){ 
        sweep = (int)((float)currentNum/(float)maxNum*sweepAngle); 
      }else { 
        sweep = sweepAngle; 
      } 
      paint_2.setStrokeWidth(sweepOutWidth); 
      Shader shader =new SweepGradient(0,0,indicatorColor,null); 
      paint_2.setShader(shader); 
      int w = dp2px(10); 
      RectF rectf = new RectF(-radius-w , -radius-w , radius+w , radius+w); 
      canvas.drawArc(rectf,startAngle,sweep,false,paint_2); 
      float x = (float) ((radius+dp2px(10))*Math.cos(Math.toRadians(startAngle+sweep))); 
      float y = (float) ((radius+dp2px(10))*Math.sin(Math.toRadians(startAngle+sweep))); 
      paint_3.setStyle(Paint.Style.FILL); 
      paint_3.setColor(0xffffffff); 
      paint_3.setMaskFilter(new BlurMaskFilter(dp2px(3), BlurMaskFilter.Blur.SOLID)); //        
      canvas.drawCircle(x,y,dp2px(3),paint_3); 
      canvas.restore(); 
    } 
    
    하드웨어 가속 을 닫 는 것 을 기억 하 십시오.바로를 추가 하 는 것 입 니 다.
    3 부 완료,그림 보기

    draw Center Text:이 단 계 는 간단 합 니 다.방금 말 한 문 자 를 그 릴 때 왼쪽 아래 에서 시작 하 는 것 과 두 가지 문자 폭 의 차 이 를 측정 하면 됩 니 다.
    
    private void drawCenterText(Canvas canvas) { 
      canvas.save(); 
      paint_4.setStyle(Paint.Style.FILL); 
      paint_4.setTextSize(radius/2); 
      paint_4.setColor(0xffffffff); 
      canvas.drawText(currentNum+"",-paint_4.measureText(currentNum+"")/2,0,paint_4); 
      paint_4.setTextSize(radius/4); 
      String content = "  "; 
      if(currentNum < maxNum*1/5){ 
        content += text[0]; 
      }else if(currentNum >= maxNum*1/5 && currentNum < maxNum*2/5){ 
        content += text[1]; 
      }else if(currentNum >= maxNum*2/5 && currentNum < maxNum*3/5){ 
        content += text[2]; 
      }else if(currentNum >= maxNum*3/5 && currentNum < maxNum*4/5){ 
        content += text[3]; 
      }else if(currentNum >= maxNum*4/5){ 
        content += text[4]; 
      } 
      Rect r = new Rect(); 
      paint_4.getTextBounds(content,0,content.length(),r); 
      canvas.drawText(content,-r.width()/2,r.height()+20,paint_4); 
      canvas.restore(); 
    } 
    
    여기까지 그리 기 부분 이 거의 완성 되 지 않 았 습 니 다.다음은 값 을 바 꿀 때 애니메이션 효 과 를 실현 하고 배경 색 을 바 꾸 는 것 입 니 다.
    setCurrent NumAnim 은 사용자 가 호출 할 수 있 도록 제공 합 니 다.속성 애니메이션 을 통 해 현재 값 을 변경 할 수 있 습 니 다.현재 값(currentNum)에 setter 와 getter 를 추가 해 야 합 니 다.속성 애니메이션 내부 에서 호출 해 야 하기 때 문 입 니 다.
    애니메이션 의 시간 에 대해 계산 공식 을 간단하게 쓰 고 애니메이션 과정 을 감청 하여 배경 색 의 변 화 를 실현 한다.어떻게 해야만 알 리 페 이 깨 신용 처럼 레 드 오렌지 옐 로 우 블 루 의 그 라 데 이 션 을 할 수 있 습 니까?나 는 내 생각 에 따라 세 가지 색깔 사이 의 그 라 데 이 션 효 과 를 실현 했다.
    여러분 은 속성 애니메이션 을 배 울 때 플러그 인 평가 기의 역할 을 알 아야 합 니 다.저 는 ArgbEvaluator 평가 기 를 사용 하여 색상 의 점진 적 인 변 화 를 실현 하고 그의 evaluate 방법 을 호출 하여 0~1 의 비례 를 전달 하고 시작 과 끝 에 있 는 색 을 전달 하면 현재 비례 에 따라 이 두 색 사이 에 있 는 색상 값 을 얻 을 수 있 습 니 다.
    여기 서 저 는 빨간색 에서 오렌지,그리고 파란색 까지 의 그 라 데 이 션 을 실 현 했 습 니 다.최대 치 는 500 이 라 고 가정 하면 현재 치 x 는 0~250 과정 에서 빨간색 에서 오렌지,x/(500/2)까지 0~1 의 변화 비례 를 얻 을 수 있 습 니 다.현재 치 는 250~500 과정 에서 오렌지 에서 파란색 까지 0~1 의 변화 과정 비례 가 필요 합 니 다.계산 방법 은(x-250)/(250)입 니 다.  그 중 250 은(500/2)얻 은 것 이다.이런 사고방식 에 따라 당연히 더 많은 색깔 간 의 점차 적 인 변 화 를 실현 할 수 있다.바로 방법 을 강구 하여 각 구간 에서 0~1 의 비례 치 를 계산 하면 된다.데이터 형식 변환 에 주의 하 세 요.코드 를 올 리 세 요!
    
    public int getCurrentNum() { 
      return currentNum; 
    } 
     
    public void setCurrentNum(int currentNum) { 
      this.currentNum = currentNum; 
      invalidate(); 
    } 
    public void setCurrentNumAnim(int num) { 
      float duration = (float)Math.abs(num-currentNum)/maxNum *1500+500; //            
      ObjectAnimator anim = ObjectAnimator.ofInt(this,"currentNum",num); 
      anim.setDuration((long) Math.min(duration,2000)); 
      anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 
        @Override 
        public void onAnimationUpdate(ValueAnimator animation) { 
          int value = (int) animation.getAnimatedValue(); 
          int color = calculateColor(value); 
          setBackgroundColor(color); 
        } 
      }); 
      anim.start(); 
    } 
    private int calculateColor(int value){ 
      ArgbEvaluator evealuator = new ArgbEvaluator(); 
      float fraction = 0; 
      int color = 0; 
      if(value <= maxNum/2){ 
        fraction = (float)value/(maxNum/2); 
        color = (int) evealuator.evaluate(fraction,0xFFFF6347,0xFFFF8C00); //     
      }else { 
        fraction = ( (float)value-maxNum/2 ) / (maxNum/2); 
        color = (int) evealuator.evaluate(fraction,0xFFFF8C00,0xFF00CED1); //     
      } 
      return color; 
    } 
    
    짜 잔 짜 잔~외부 에서 setCurrent NumAnim 을 호출 하면 애니메이션 의 수 치 를 바 꿀 수 있 습 니 다.


    자,그리고 마지막 질문 은 앞에서 언급 한 것 입 니 다.
    왜 투명도 그 라 데 이 션 색상 배열 이 이 렇 습 니까?
    
    private int[] indicatorColor = {0xffffffff,0x00ffffff,0x99ffffff,0xffffffff}; 
    대개 불투명-->투명-->반투명-->불투명 한 변화
    ―첫 번 째 는 불필요 하지 않 습 니까?왜 처음부터 불투명 해 야 합 니까?
    답:저도 좀 궁금 합 니 다.sweepGradient 색상 의 점차 적 인 변 화 는 x 정 축 에서 시작 되 기 때 문 입 니 다.제 색상 배열 이 이 렇 습 니 다.즉,투명->반투명->불투명:
    
    private int[] indicatorColor = {0x00ffffff,0x99ffffff,0xffffffff}; 
    그러면 원 을 그 려 서 이렇게 생 겼 어 요.

    그리고 우리 의 계기판 은 160 도 에서 시작 하여 220 도 를 쓸 었 다.즉,이렇게 일부 각도(0~20 도)가 투명 해 지면 우리 가 원 하 는 효과 가 아니 라 는 것 이다.그래서 나 는 이렇게 썼 다.
    
    private int[] indicatorColor = {0xffffffff,0x00ffffff,0x99ffffff,0xffffffff}; 
    이런 배열.이렇게 그 려 져 있어 요.

    이렇게 하면 적어도 0~20 도 는 하 얗 게 보이 고 전체 진도 조 는 투명 에서 불투명 까지 의 효 과 를 실현 한다.
    사실 우아 하 지 는 않 아 요.시작 각도 와 스 캔 한 각 도 는 사용자 정의 로 변경 할 수 있 기 때문이다.그래서 친구 들 에 게 더 좋 은 방법 이 있 나 요?
    원본 주소:http://xiazai.jb51.net/201701/yuanma/diy_roundindicator_jb51.rar
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기