Android 사용자 정의 뷰 구현 인증 코드

이 글 은 홍 양의Android 사용자 정의 뷰(1)의 확장 과Android 사용자 정의 View 구조 함수 상세 설명안의 내용 에 대한 전재 이다.
우선 declare-styleable 태그 declare-styleable 태그 의 역할 은 사용자 정의 컨트롤 에 사용자 정의 속성 을 추가 하 는 것 입 니 다.예 를 들 어 다음 과 같 습 니 다.
(텍스트 의 색상,크기,길이,배경 색 을 정의 합 니 다)

<declare-styleable name="CustomTitleView">
 <attr name="titleColor" format="color" />
 <attr name="titleSize" format="dimension" />
 <attr name="titleBackground" format="color" />
 <attr name="titleLenth" format="integer" />
 </declare-styleable>
Android 는 사용자 정의 속성 을 제공 합 니 다.format 의 인 자 는 다음 과 같 습 니 다.
(reference、color、boolean、dimension、float、integer、string、fraction、enum、flag)
1.reference:자원 ID:
이 속성 을 설정 하면 이 속성 은@string|@drawable 등 자원 파일 을 호출 하 는 역할 을 합 니 다.
2. color:
이 속성의 역할 은 색상 값 8 또는 6 비트 의 16 진수 색상 값 을 설정 하 는 것 입 니 다.예 를 들 어 TextView 의 textColor 등 속성 을 설정 하 는 역할 이 같 습 니 다(예 를 들 어\#ff 000 을 빨간색 으로 설정 하 는 등)
3.boolean:
이 매개 변 수 는 true 나 false 를 설정 하 는 역할 을 합 니 다.
4.dimension:
이 매개 변 수 는 px,dip,dp,sp 등 사이즈 값 을 설정 하 는 역할 을 합 니 다.
5.float:
이 매개 변 수 는 부동 소수점 데 이 터 를 설정 하 는 역할 을 합 니 다.
6.integer:
이 매개 변 수 는 성형 데 이 터 를 설정 하 는 역할 을 합 니 다.
7.string:
이 매개 변 수 는 TextView 의 text 속성 과 같은 문자열 데 이 터 를 설정 하 는 역할 을 합 니 다.
8.fraction:
이 매개 변 수 는 백분율 데 이 터 를 설정 하 는 역할 을 합 니 다.
9:enum:
이 매개 변 수 는 이 attr 의 name 속성 에 고정된 매개 변 수 를 설정 하 는 것 과 같 습 니 다.예 를 들 어 선형 구조의 orientation 속성 은 vertical 또는 horizontal 만 설정 할 수 있 습 니 다.
10:flag:
이 매개 변 수 는:비트 또는 연산
사용자 정의 View 의 절 차 는?
1.사용자 정의 View 의 속성
2.View 의 구조 방법 에서 사용자 정의 속성 을 얻 을 수 있 습 니 다.
3,다시 쓰기 onMeasure
4.다시 쓰기 onDraw
어떤 때 는 onMeasure 방법 은 다시 쓰 지 않 아 도 됩 니 다.예 를 들 어 시스템 자체 구성 요소 등 입 니 다.
그리고 필요 한 속성 을 정의 해 보도 록 하 겠 습 니 다.

 //  
 private StringBuffer mTitleText;
 //     
 private int mTitleColor;
 //     
 private int mTitleSize;
 //    
 private int mBackground;
 //            
 private int mLenth;
 //            
 private Rect mBound;
 //  
 private Paint mPaint;
 //     
 private Random random = new Random();
 //     
 private int padding_left;
 //    
 String[] data = {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
  "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
  "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"};
그리고 우 리 는 세 가지 구조 방법 을 다시 쓴다.우리 가 주의해 야 할 것 은?
1.코드 에서 new 사용자 정의 View 인 스 턴 스 를 직접 사용 할 때 첫 번 째 구조 함 수 를 호출 합 니 다.
2.xml 레이아웃 파일 에서 사용자 정의 View 를 호출 할 때 두 번 째 구조 함 수 를 호출 합 니 다.
3.xml 레이아웃 파일 에서 사용자 정의 View 를 호출 하고 사용자 정의 탭 에 사용자 정의 속성 이 있 을 때 여기 서 호출 하 는 것 은 두 번 째 구조 함수 입 니 다.
즉,시스템 은 기본적으로 Custom View 의 앞의 두 구조 함수 만 호출 하고 세 번 째 구조 함수 의 호출 은 보통 우리 가 구조 함수 에서 주동 적 으로 호출 하 는 것 이다(예 를 들 어 두 번 째 구조 함수 에서 세 번 째 구조 함 수 를 호출 하 는 것).
사용자 정의 속성 획득 에 대해 서 는 구조 함수 에서 obtainStyled Attributes 함 수 를 통 해 이 루어 집 니 다.

public CustomTitleView(Context context) {
 this(context, null);
 }

 public CustomTitleView(Context context, AttributeSet attrs) {
 this(context, attrs, 0);
 }

 public CustomTitleView(Context context, AttributeSet attrs, int defStyleAttr) {
 super(context, attrs, defStyleAttr);
 setOnClickListener(this);
 TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomTitleView);
 int n = typedArray.getIndexCount();
 for (int i = 0; i < n; i++) {
  int attr = typedArray.getIndex(i);
  switch (attr) {
  case R.styleable.CustomTitleView_titleColor:
   mTitleColor = typedArray.getColor(attr, Color.BLACK);
   break;
  case R.styleable.CustomTitleView_titleSize:
   mTitleSize = typedArray.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));
   break;
  case R.styleable.CustomTitleView_titleBackground:
   mBackground = typedArray.getColor(attr, Color.BLACK);
   break;
  case R.styleable.CustomTitleView_titleLenth:
   mLenth = typedArray.getInteger(attr, 4);
   break;
  }
 }
 //  
 typedArray.recycle();
 mPaint = new Paint();
 randomText();
 mPaint.setTextSize(mTitleSize);
 //      
 mBound = new Rect();
 //            ,            ,                   ,      rect  
 mPaint.getTextBounds(mTitleText.toString(), 0, mTitleText.length(), mBound);
 }

obtainStyled Attributes 의 두 번 째 속성 은 방금 attrs.xml 파일 에 있 던 declare-styleable 탭 을 호출 하 는 name 입 니 다.
그리고 onMeasure 방법 을 다시 써 서 getMeasured Length 방법 으로 너비 와 높이 를 계산 합 니 다.

/**
 *     
 *
 * @param lenth widthMeasureSpec heightMeasureSpec
 * @param isWidth true     ,false     
 */
 private int getMeasuredLength(int lenth, boolean isWidth) {
 if (isWidth) {
  if (MeasureSpec.getMode(lenth) == MeasureSpec.EXACTLY) {
  //       ,  MeasureSpec.getSize()        
  return MeasureSpec.getSize(lenth);
  } else {
  //   warp_content,         
  /**
   *            
   *   getTextBounds       Text   
   *           View    text       getPaddingLeft()+getPaddingRight()+textwidth        view        
   *        getPaddingLeft()+getPaddingRight()+              ,          ,         +  ,                        getPaddingLeft()+getPaddingRight()+Math.max(     ,     )       
   */
  if (MeasureSpec.getMode(lenth) == MeasureSpec.AT_MOST) {
   mPaint.setTextSize(mTitleSize);
   mPaint.getTextBounds(mTitleText.toString(), 0, mTitleText.length(), mBound);
   float textwidth = mBound.width();
   int desired = (int) (getPaddingLeft() + textwidth + getPaddingRight());
   return Math.min(desired,MeasureSpec.getSize(lenth));
  }

  }
 } else {
  if (MeasureSpec.getMode(lenth) == MeasureSpec.EXACTLY) {
  //         ,  MeasureSpec.getSize()        
  return MeasureSpec.getSize(lenth);
  } else {
  if (MeasureSpec.getMode(lenth) == MeasureSpec.AT_MOST) {
   //   warp_content,         
   mPaint.setTextSize(mTitleSize);
   mPaint.getTextBounds(mTitleText.toString(), 0, mTitleText.length(), mBound);
   float texthgeight = mBound.height();
   int desired = (int) (getPaddingTop() + texthgeight + getPaddingBottom());
   return Math.min(desired,MeasureSpec.getSize(lenth));
  }
  }
 }
 return 0;
 }

그리고 onMeasure 방법 에서 호출 합 니 다.

@Override
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 setMeasuredDimension(getMeasuredLength(widthMeasureSpec, true), getMeasuredLength(heightMeasureSpec, false));
 }
시스템 이 측정 해 준 높이 와 너 비 는 모두 MATCHPARNET,우리 가 명확 한 너비 와 높이 를 설정 할 때 시스템 이 측정 해 준 결 과 는 우리 가 설정 한 결과 입 니 다.우리 가 WRAP 로 설정 할 때.CONTENT,혹은 MATCHPARENT 시스템 이 측정 해 준 결 과 는 MATCH 입 니 다.파 렌 트 길이.
그래서 WRAP 를 설 치 했 을 때CONTENT 때,우 리 는 스스로 측정 해 야 한다.즉,onMeasure 방법 을 다시 쓰 는 것 이다.
다시 쓰기 전에 MeasureSpec 의 specMode 를 알 아 보 세 요.모두 세 가지 유형 입 니 다.
EXACTLY:보통 명확 한 값 이나 MATCH 를 설정 합 니 다.PARENT
AT_MOST:하위 레이아웃 이 최대 치 로 제한 되 어 있 음 을 나타 내 며,일반적으로 WARP 입 니 다.CONTENT
UNSPECIFIED:하위 레이아웃 을 원 하 는 만큼 크게 사용 하지 않 는 다 는 뜻 입 니 다.
여기 서 일부 초보 자 들 은 getMode 와 getSize 의 역할 을 이해 하지 못 할 수도 있 습 니 다.먼저 getMode()는 넓 고 높 은 설정 모델 을 판단 하고 얻 은 후에 판단 할 수 있 습 니 다.예 를 들 어

//xx  widthMeasureSpec  heightMeasureSpec

if(MeasureSpec.getMode(xx)==MeasureSpec.EXACTLY){
 //          match_parent      layout_width layout_height         andorid:layout_width="100dp",           MeasureSpec.getSize(xx)        
}else if(MeasureSpec.getMode(xx)==MeasureSpec.EXACTLY){
 //         wrap_content,              
}else{
 //               ,      ,        AdapterView,  measure       
}

그리고 저희 가 onDraw 방법 을 다시 써 보 겠 습 니 다.

 @Override
 protected void onDraw(Canvas canvas) {
 super.onDraw(canvas);
 padding_left = 0;
 mPaint.setColor(mBackground);
 canvas.drawRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), mPaint);
 mPaint.setColor(mTitleColor);
 for (int i = 0; i < mTitleText.length(); i++) {
  randomTextStyle(mPaint);
  padding_left += mPaint.measureText(String.valueOf(mTitleText.charAt(i)))+10;
  canvas.drawText(String.valueOf(mTitleText.charAt(i)), padding_left, getHeight() / 2 + mBound.height() / 2, mPaint);
 }
 }
private void randomTextStyle(Paint paint) {
 paint.setFakeBoldText(random.nextBoolean()); //true   ,false    
 float skewX = random.nextInt(11) / 10;
 skewX = random.nextBoolean() ? skewX : -skewX;
 paint.setTextSkewX(skewX); //float    ,      ,    
 paint.setUnderlineText(true); //true    ,false     
 paint.setStrikeThruText(false); //true    ,false     
 }
여기에 여러 개의 문자열 을 그 렸 고 그 려 진 문자열 마다 비 뚤 어 졌 습 니 다.그러면 우 리 는 randomTextStyle()을 사용 하면 문 자 를 그 릴 때마다 모든 문자 가 다른 스타일 로 설정 할 수 있 습 니 다.여기 서 drawText 의 몇 가지 인 자 를 말씀 드 리 겠 습 니 다.첫 번 째 인 자 는 그 려 야 할 문자 내용 입 니 다.두 번 째 인 자 는 x 축 으로 왼쪽 거리 에 해당 합 니 다.세 번 째 매개 변 수 는 Y 축 이 고 네 번 째 매개 변 수 는 paint 의 인 스 턴 스 입 니 다.제 친 구 는 drawText 의 좌표 그리 기 에 관심 이 있 는 사람 은 android canvas drawText()문자 가운데 에 있 는 것 을 볼 수 있 습 니 다.
마지막 으로 레이아웃 파일 에서 사용자 정의 view 를 참조 합 니 다.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 xmlns:cq="http://schemas.android.com/apk/res-auto"
 android:layout_width="match_parent"
 android:layout_height="match_parent"
 android:orientation="horizontal">

 <chapter.com.rxjavachapter.CustomTitleView
 android:layout_width="wrap_content"
 android:layout_height="wrap_content"
 android:layout_centerInParent="true"
 android:padding="10dp"
 cq:titleBackground="@android:color/black"
 cq:titleColor="#ff0000"
 cq:titleLenth="4"
 cq:titleSize="10sp" />

</RelativeLayout>

루트 레이아웃 에 xmlns:xx=을 추가 합 니 다.http://schemas.android.com/apk/res-auto"여기 xx 는 모든 자모 일 수 있 습 니 다."
그리고 xx 로 우리 가 attr 의 name 에 값 을 설정 하 는 것 을 누 르 면 마지막 에 이 루어 진 효 과 는 이 렇 습 니 다.

인증 코드 view 인 만큼 인증 코드 내용 을 바 꾸 려 면 누 르 는 클릭 이 벤트 를 열 고 세 번 째 구조 방법 에 click 이 벤트 를 추가 해 야 합 니 다.

 @Override
 public void onClick(View v) {
 randomText();
 postInvalidate();
 }
/**
 *         
 *
 * @return
 */
 private void randomText() {
 mTitleText = new StringBuffer();
 for (int i = 0; i < mLenth; i++) {
  mTitleText.append(data[(int) (Math.random() * data.length)]);
 }
 }

 /**
 *        
 *
 * @return
 */
 public String getCode() {
 return mTitleText.toString();
 }

 /**
 *       
 *
 * @return
 */
 public boolean isEqual(String code) {
 if (code != null) {
  return code.toUpperCase().equals(getCode().toUpperCase()) ? true : false;
 } else {
  return false;
 }
 }

이렇게 하면 한 번 의 인증 코드 내용 을 바 꾸 는 것 을 클릭 할 수 있 습 니 다.그리고 우 리 는 두 가지 방법 을 열 어 인증 코드 를 판단 하거나 인증 코드 를 얻 을 수 있 습 니 다.저 는 간단 한 인증 코드 일 뿐 입 니 다.여러분 은 스스로 더 많은 것 을 추가 할 수 있 습 니 다.
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기