Android 아래쪽 탐색 컨트롤 인 스 턴 스 코드

1.먼저 최종 효 과 를 보 여 드 리 겠 습 니 다.

위 를 통 해 알 수 있 듯 이 그림 1 은 간단 한 사용 입 니 다.그림 2,그림 3 은 ViewPager 와 결합 하여 공동으로 사용 할 수 있 고 ViewPager 의 미끄럼 에 따라 그 라 데 이 션 색 을 바 꿀 수 있 습 니 다.다른 점 은 그림 2 는 선택 하지 않 고 선택 하지 않 은 두 장의 그림 입 니 다.그림 3 의 선택 은 선택 하지 않 고 선택 하지 않 은 한 장의 그림 은 색 만 변 했 습 니 다.
수요
xml 레이아웃 에 컨트롤 을 도입 하고 데 이 터 를 연결 할 수 있 습 니 다.코드 에 감청 리 셋 을 설정 하고 설정 사용 이 매우 간단 합 니 다!
3.수요 분석
우리 가 다년간 명확 하지 않 은 수요 항목 을 한 경험 에 따 르 면 상기 수 요 는 그래도 명확 한 편 이다.그러면 우 리 는 LinearLayout 에 하위 View 컨트롤 을 추가 할 수 있 습 니 다.이 하위 View 컨트롤 은 우리 가 사용자 정의 한 모든 tab 항목 입 니 다.물론 LinearLayout 에 대해 가중치 를 설정 해 야 합 니 다.
수요 가 대체적으로 명확 한 후에 모든 목적 의 하위 View 컨트롤 을 디자인 합 니 다.이 하위 View 컨트롤 은 상태 변 화 를 전환 할 수 있 고 한 장,두 장 모두 상 태 를 전환 할 수 있 습 니 다(그림 1,그림 3 참조).그러면 이 View 는 아래쪽 에 표 시 된 텍스트 를 설정 할 수 있 습 니 다.선택 한 색상,선택 하지 않 은 색상,선택 하지 않 은 그림,선택 하지 않 은 그림,텍스트 크기,지시 점 이 있 는 지 설정,지시 점 크기 설정,지시 점 그림 설정 등 을 설정 할 수 있 습 니 다.
4.Tab 항목 인터페이스
수요 분석 을 통 해 우 리 는 다음 과 같은 Tab 서브 View 조작 인 터 페 이 스 를 정의 할 수 있 습 니 다.

자세 한 친 구 는 인터페이스 에 선택 한 그림 과 선택 하지 않 은 그림 을 설정 하지 않 은 이 유 를 발견 할 수 있 습 니 다.이 속성 은 통용 되 지 않 기 때문에 서로 다른 실현 에서 정 의 를 내 립 니 다.
5.Tab 항목 실현

클래스 의 상속 관계 및 설명:
아 날로 그 는 다음 과 같다.

TabViewBase 에서 주요 한 방법 은 측정 이 고 다른 것 은 모두 인터페이스 에 대한 간단 한 실현 이다.

@Override 
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
//     icon   
int bitmapWidth = Math.min(getMeasuredWidth() - getPaddingLeft() 
- getPaddingRight(), getMeasuredHeight() - getPaddingTop() 
- getPaddingBottom() - mTextBound.height()); 
int left = getMeasuredWidth() / 2 - bitmapWidth / 2; 
int top = (getMeasuredHeight() - mTextBound.height()) / 2 - bitmapWidth / 2; 
//   icon      
mIconRect = new Rect(left, top, left + bitmapWidth, top + bitmapWidth); 
//          
int indicatorRadius = mIndicatorSize / 2; 
int tabRealHeight = bitmapWidth + mTextBound.height(); 
mIndicatorRect = new Rect(left + tabRealHeight* 4/5 - indicatorRadius, top, left+tabRealHeight* 4/5 + indicatorRadius, top + mIndicatorSize); 
} 
상기 코드 에서 볼 수 있 듯 이 문자 의 높이 를 측정 하고 컨트롤 의 높이 로 문자 의 높이 와 컨트롤 의 너비 대 비 를 빼 고 작은 그림 의 크기,즉 설 정 된 그림 을 정사각형 으로 해 야 한다.그렇지 않 으 면 변형 이 생 길 수 있다.
일반 두 장의 그림 을 전환 하 는 TabView 의 그림 을 보십시오.

@Override 
protected void onDraw(Canvas canvas) { 
super.onDraw(canvas); 
setupTargetBitmap(canvas); 
drawIndicator(canvas); 
if(null != mText) { 
drawTargetText(canvas); 
} 
} 
/** 
*        
* @param canvas 
*/ 
private void setupTargetBitmap(Canvas canvas) { 
canvas.drawBitmap(isSelected ? mSelectedIconBitmap : mUnselectedIconBitmap, null, mIconRect, null); 
} 
/** 
*       
* @param canvas 
*/ 
protected void drawIndicator(Canvas canvas) { 
if(isIndicateDisplay) { 
canvas.drawBitmap(mIndicatorBitmap, null, mIndicatorRect, null); 
} 
} 
/** 
*      
* @param canvas 
*/ 
protected void drawTargetText(Canvas canvas) { 
mTextPaint.setColor(isSelected ? mSelectedColor : mUnselectedColor); 
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2 
- mTextBound.width() / 2, 
mIconRect.bottom + mTextBound.height(), mTextPaint); 
}
매우 간단 한 것 을 볼 수 있 습 니 다.아이콘 그림 을 그리고 지시 점 을 그립 니 다.아이콘 그림 을 그 릴 때 현재 항목 이 선택 상태 에 있 는 지 판단 하고 선택 여부 에 따라 다른 그림 을 그립 니 다.지시 점 을 그 릴 때 표시 점 이 설정 되 어 있 는 지 먼저 판단 합 니 다.아래쪽 텍스트 가 있 으 면 아래쪽 텍스트 를 오래 그립 니 다.
ViewPager 두 장의 그림 을 볼 때 우 리 는 효과 도 를 가지 고 와 서 관찰 합 니 다.

ViewPager 의 스크롤 아이콘 이 그 라 데 이 션 되 고 일반적인 변화 에 따라 두 가지 모드 가 있 습 니 다.OK.알 고 나 면 우 리 는 쉽게 그림 을 그 릴 수 있 습 니 다.두 장의 그림 을 그 릴 수 있 지만 그 릴 때 투명 도 를 조절 하면 됩 니 다.그 렇 죠?간단 하지 않 습 니까?

@Override 
protected void onDraw(Canvas canvas) { 
super.onDraw(canvas); 
int alpha = (int) Math.ceil((255 * mAlpha)); 
drawSourceBitmap(canvas, alpha); 
drawTargetBitmap(canvas, alpha); 
if(null != mText) { 
drawSourceText(canvas, alpha); 
drawTargetText(canvas, alpha); 
} 
drawIndicator(canvas); 
} 
/** 
*         
* @param canvas 
* @param alpha 
*/ 
private void drawSourceBitmap(Canvas canvas, int alpha) { 
mPaint.setAntiAlias(true); 
mPaint.setDither(true); 
mPaint.setAlpha(255 - alpha); 
canvas.drawBitmap(mUnselectedIconBitmap, null, mIconRect, mPaint); 
} 
/** 
*        
* @param canvas 
* @param alpha 
*/ 
private void drawTargetBitmap(Canvas canvas, int alpha) { 
mPaint.setAntiAlias(true); 
mPaint.setDither(true); 
mPaint.setAlpha(alpha); 
canvas.drawBitmap(mSelectedIconBitmap, null, mIconRect, mPaint); 
} 
/** 
*        
* @param canvas 
* @param alpha 
*/ 
private void drawSourceText(Canvas canvas, int alpha) { 
mTextPaint.setTextSize(mTextSize); 
mTextPaint.setColor(mUnselectedColor); 
mTextPaint.setAlpha(255 - alpha); 
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2 
- mTextBound.width() / 2, 
mIconRect.bottom + mTextBound.height(), mTextPaint); 
} 
/** 
*       
* @param canvas 
* @param alpha 
*/ 
private void drawTargetText(Canvas canvas, int alpha) { 
mTextPaint.setColor(mSelectedColor); 
mTextPaint.setAlpha(alpha); 
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2 
- mTextBound.width() / 2, 
mIconRect.bottom + mTextBound.height(), mTextPaint); 
}
코드 에 있 는 mAlpha 는 ViewPager 가 굴 러 가 는 백분율 로 선 택 된 아이콘 과 선택 되 지 않 은 텍스트 를 각각 그립 니 다.그러나 그 릴 때 설정 한 투명도 가 다 르 면 그 라 데 이 션 효과 가 있 습 니 다.
ViewPager 의 한 장의 그림 을 볼 때 우 리 는 효과 도 를 가지 고 와 서 관찰 합 니 다.

private void setupTargetBitmap(int alpha) { 
mBitmap = Bitmap.createBitmap(getMeasuredWidth(), getMeasuredHeight(), Config.ARGB_8888); 
mCanvas = new Canvas(mBitmap); 
mPaint = new Paint(); 
mPaint.setColor(mSelectedColor); 
mPaint.setAntiAlias(true); 
mPaint.setDither(true); 
mPaint.setAlpha(alpha); 
mCanvas.drawRect(mIconRect, mPaint); 
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 
mPaint.setAlpha(255); 
mCanvas.drawBitmap(mIconBitmap, null, mIconRect, mPaint); 
} 
private void drawSourceText(Canvas canvas, int alpha) { 
mTextPaint.setTextSize(mTextSize); 
mTextPaint.setColor(mUnselectedColor); 
mTextPaint.setAlpha(255 - alpha); 
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2 
- mTextBound.width() / 2, 
mIconRect.bottom + mTextBound.height(), mTextPaint); 
} 
private void drawTargetText(Canvas canvas, int alpha) { 
mTextPaint.setColor(mSelectedColor); 
mTextPaint.setAlpha(alpha); 
canvas.drawText(mText, mIconRect.left + mIconRect.width() / 2 
- mTextBound.width() / 2, 
mIconRect.bottom + mTextBound.height(), mTextPaint); 
}
그림 을 그 리 는 과정 은 크게 두 장의 그림 과 같 습 니 다.다른 점 은 그림 을 그 릴 때 Paint 가 Xfermode 를 설정 하여 색상 의 그 라 데 이 션 을 제어 하 는 것 입 니 다.
OK,Tab 항목 의 사용자 정의 View 가 끝나 면 나머지 는 훨씬 간단 합 니 다.
6.정의 속성
다음은 LinearLayout 의 전체 컨트롤 을 계승 하여 속성 을 정의 하 는 것 입 니 다.

tabIcons 가 한 장의 그림 으로 그 라 데 이 션 효과 가 특수 한 것 을 볼 수 있 습 니 다.tabSelected Icons 와 tabUnselected Icon 은 두 장의 아이콘 으로 전환 효과 가 특수 합 니 다.
7.컨트롤 작성
3 중 양식 에 공공 적 인 부분 이 있 기 때문에 우 리 는 축적 추출 을 한다.아 날로 그 구 조 는 다음 과 같다.

1.구조 함수 사용자 정의 속성 초기 화
TabIndicatorBase 에서 사용자 정의 속성 초기 화

private void init(Context context, AttributeSet attrs) { 
setOrientation(LinearLayout.HORIZONTAL); 
setGravity(Gravity.CENTER); 
//Load defaults from resources 
final Resources res = getResources(); 
final int defaultSelectedColor = res.getColor(R.color.default_tab_view_selected_color); 
final int defaultUnselectedColor = res.getColor(R.color.default_tab_view_unselected_color); 
final float defaultTextSize = res.getDimension(R.dimen.default_tab_view_text_size); 
final float defaultTabPadding = res.getDimension(R.dimen.default_tab_view_padding); 
final float defaultIndicatorSize = res.getDimension(R.dimen.default_tab_view_indicator_size); 
// Styleables from XML 
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TabIndicator); 
//      ,  tab      
if (a.hasValue(R.styleable.TabIndicator_tabLabels)) { 
mLabels = a.getTextArray(R.styleable.TabIndicator_tabLabels); 
} 
mSelectedColor = a.getColor(R.styleable.TabIndicator_tabSelectedColor, defaultSelectedColor); 
mUnselectedColor = a.getColor(R.styleable.TabIndicator_tabUnselectedColor, defaultUnselectedColor); 
mTextSize = (int) a.getDimension(R.styleable.TabIndicator_tabTextSize, defaultTextSize); 
mIndicatorSize = (int) a.getDimension(R.styleable.TabIndicator_TabIndicatorSize, defaultIndicatorSize); 
mTabPadding = (int) a.getDimension(R.styleable.TabIndicator_tabItemPadding, defaultTabPadding); 
handleStyledAttributes(a); 
a.recycle(); 
initView(); 
}
일부 속성 은 공공 이 아니 기 때문에 handle StyleAttributes(a)의 추상 적 인 방법 을 정의 하여 하위 클래스 에서 이 루어 집 니 다.
2.뷰 초기 화

/** 
*       
*/ 
private void initView() { 
LayoutParams params = new LayoutParams(0, LayoutParams.MATCH_PARENT, 1); 
params.gravity = Gravity.CENTER; 
int size = getTabSize(); 
for (int i = 0; i < size; i++) { 
final int index = i; 
T tabItemView = createTabView(); 
tabItemView.setPadding(mTabPadding, mTabPadding, mTabPadding, mTabPadding); 
//       
if(null != mLabels) { 
tabItemView.setText(mLabels[index]); 
tabItemView.setTextSize(mTextSize); 
} 
tabItemView.setSelectedColor(mSelectedColor); 
tabItemView.setUnselectedColor(mUnselectedColor); 
tabItemView.setIndicatorSize(mIndicatorSize); 
setProperties(tabItemView, i); 
this.addView(tabItemView, params); 
tabItemView.setTag(index); // CheckedTextView      tag,        、    
mCheckedList.add(tabItemView); //  CheckedTextView   list ,     
tabItemView.setOnClickListener(new OnClickListener() 
@Override 
public void onClick(View v) { 
setTabsDisplay(index); //              
if (null != mTabListener) { 
mTabListener.onTabSelected(index); // tab          
} 
} 
}); 
//             ,        
if (i == 0) { 
tabItemView.setSelected(true); 
} else { 
tabItemView.setSelected(false); 
} 
} 
}
Tab 항목 생 성 및 특수 한 속성 설정 은 모두 추상 적 인 방법 으로 하위 클래스 에 맡 깁 니 다.

/** 
*   TabView 
* @return 
*/ 
protected abstract T createTabView(); 
/** 
*        
* @param t 
*/ 
protected abstract void setProperties(T t, int index); 
3.하위 클래스 구현
여기 가 모두 비교적 간단 하기 때문에 우 리 는 그 중의 간단 한 두 아이콘 그림 을 선택 하여 설명 한다.

@Override 
protected void handleStyledAttributes(TypedArray a) { 
//      ,  tab      
int selectedIconsResId = a.getResourceId(R.styleable.TabIndicator_tabSelectedIcons, 0); 
TypedArray ta = getContext().getResources().obtainTypedArray(selectedIconsResId); 
int len = ta.length(); 
mSelectedDrawableIds = new int[len]; 
for(int i = 0; i < len; i++) { 
mSelectedDrawableIds[i] = ta.getResourceId(i, 0); 
} 
int unselectedIconsResId = a.getResourceId(R.styleable.TabIndicator_tabUnselectedIcons, 0); 
ta = getContext().getResources().obtainTypedArray(unselectedIconsResId); 
len = ta.length(); 
mUnselectedDrawableIds = new int[len]; 
for(int i = 0; i < len; i++) { 
mUnselectedDrawableIds[i] = ta.getResourceId(i, 0); 
} 
ta.recycle(); 
}
xml 에서 설정 한 선택 및 선택 되 지 않 은 아이콘 을 읽 었 습 니 다.
TabView 생 성

@Override 
protected TabView createTabView() { 
return new TabView(getContext()); 
} 
특수 속성 설정

@Override 
protected void setProperties(TabView tabView, int index) { 
tabView.setSelectedIcon(mSelectedDrawableIds[index]); 
tabView.setUnselectedIcon(mUnselectedDrawableIds[index]); 
} 
항목 개수 가 져 오기

@Override 
protected int getTabSize() { 
return mSelectedDrawableIds.length; 
}
8.소스 코드 와 예시
github 주소 제공:Android-TabIndicator
또한,github 에 스타 또는 f**k 나 를 환영 합 니 다!
9.한 줄 의 도입 창고
프로젝트 가 Gradle 빌 드 를 사용 하면 build.gradle 파일 에 다음 줄 을 dependencies 에 추가 해 야 합 니 다.
compile 'com.kevin:tabindicator:1.0.1'
여러분 께 공 유 된 안 드 로 이 드 밑 에 있 는 네 비게 이 션 컨트롤 인 스 턴 스 코드 는 여기 서 끝 났 습 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다!

좋은 웹페이지 즐겨찾기