Android 아래쪽 탐색 컨트롤 인 스 턴 스 코드
위 를 통 해 알 수 있 듯 이 그림 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'
여러분 께 공 유 된 안 드 로 이 드 밑 에 있 는 네 비게 이 션 컨트롤 인 스 턴 스 코드 는 여기 서 끝 났 습 니 다.도움 이 되 셨 으 면 좋 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Kotlin의 기초 - 2부지난 글에서는 Kotlin이 무엇인지, Kotlin의 특징, Kotlin에서 변수 및 데이터 유형을 선언하는 방법과 같은 Kotlin의 기본 개념에 대해 배웠습니다. 유형 변환은 데이터 변수의 한 유형을 다른 데이터...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.