Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator
生活随笔
收集整理的這篇文章主要介紹了
Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
效果
演示
說明
為了實(shí)現(xiàn) ViewPager 切換 Fragment 時(shí)的標(biāo)簽效果(類似新聞客戶端導(dǎo)航的效果)
代碼
package com.demo.view;import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Paint.Style; import android.graphics.Path; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.AttributeSet; import android.util.DisplayMetrics; import android.view.Gravity; import android.view.View; import android.view.WindowManager; import android.widget.LinearLayout; import android.widget.TextView;import com.demo.R; import com.demo.factory.Axis;import java.util.List;public class ViewPagerBelowIndicator extends LinearLayout {/*** view的寬度*/private int mWidth=-1;public void setmWidth(int mWidth) {this.mWidth = mWidth;}/*** 默認(rèn)字體大小*/private final float DEFAULT_TEXTSIZE=Axis.scaleTextSize(30);private float textSize=-1f;//字體大小public void setTextSize(float textSize) {this.textSize = textSize;}/*** 指示器文字位置*/private int IndicatePosition = 1;/*** 繪制矩形的畫筆*/private Paint mPaint;/*** path構(gòu)成一個(gè)矩形*/private Path mPath;/*** 矩形的寬度*/private int mTriangleWidth;/*** 畫筆顏色*/private int IndicatorColor = 0xFFFFFFFF;/*** 矩形的高度*/private int mTriangleHeight = 50; //指示條的高度private int mTriangleH;private static final float MAGNIFICATION_DEFAULT_TAB = (float) 3.0;/*** 矩形的寬度為單個(gè)Tab的1/3*/private static final double RADIO_TRIANGEL = 1.0f / 3;/*** 矩形的最大寬度*/private int dimension_triangel_width = (int) (getScreenWidth() / 3 * RADIO_TRIANGEL);/*** 初始時(shí),矩形指示器的偏移量*/private int mInitTranslationX;/*** 手指滑動(dòng)時(shí)的偏移量*/private float mTranslationX;/*** 默認(rèn)的Tab數(shù)量*/private final int COUNT_DEFAULT_TAB = 3;/*** tab數(shù)量*/private int mTabVisibleCount = COUNT_DEFAULT_TAB;/*** tab上的內(nèi)容*/private List<String> mTabTitles;/*** 與之綁定的ViewPager*/public ViewPager mViewPager;/*** 標(biāo)題正常時(shí)的顏色*/private int COLOR_TEXT_NORMAL = 0xFF999999;/*** 標(biāo)題選中時(shí)的顏色*/private int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;public ViewPagerBelowIndicator(Context context) {this(context, null);}public ViewPagerBelowIndicator(Context context, AttributeSet attrs) {super(context, attrs);// 獲得自定義屬性,tab的數(shù)量TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ViewPagerIndicator);mTabVisibleCount = 6;//設(shè)置指示條寬度的放大系數(shù)float magnification = 1.0f / 4;dimension_triangel_width = (int) (getScreenWidth() / 3 * magnification);if (mTabVisibleCount < 0)mTabVisibleCount = COUNT_DEFAULT_TAB;a.recycle();// 初始化畫筆mPaint = new Paint();mPaint.setAntiAlias(true);mPaint.setColor(IndicatorColor);mPaint.setStyle(Style.FILL);//mPaint.setPathEffect(new CornerPathEffect(4));}/*** 繪制指示器*/@Overrideprotected void dispatchDraw(Canvas canvas) {canvas.drawColor(0x00FFFFFF);canvas.save();// 畫筆平移到正確的位置canvas.translate(mInitTranslationX + mTranslationX, getHeight());canvas.drawPath(mPath, mPaint);canvas.restore();super.dispatchDraw(canvas);}/*** 初始化矩形的寬度*/@Overrideprotected void onSizeChanged(int w, int h, int oldw, int oldh) {super.onSizeChanged(w, h, oldw, oldh);mTriangleH = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// widthmTriangleWidth = Math.min(dimension_triangel_width, dimension_triangel_width);//初始化矩形指示器iniTrectangle();// 初始時(shí)的偏移量mInitTranslationX = getWidth() / mTabVisibleCount / 2 - mTriangleWidth/ 2;}/*** 設(shè)置可見的tab的數(shù)量** @param count*/public void setVisibleTabCount(int count) {this.mTabVisibleCount = count;}public void setIndicatePosition(int IndicatePosition){this.IndicatePosition = getHeight();invalidate();}/*** 設(shè)置tab的標(biāo)題內(nèi)容 可選,可以自己在布局文件中寫死** @param datas*/public void setTabItemTitles(List<String> datas) {// 如果傳入的list有值,則移除布局文件中設(shè)置的viewif (datas != null && datas.size() > 0) {this.removeAllViews();this.mTabTitles = datas;for (String title : mTabTitles) {// 添加viewaddView(generateTextView(title));}// 設(shè)置item的click事件setItemClickEvent();}}/*** 對(duì)外的ViewPager的回調(diào)接口*/public interface PageChangeListener {public void onPageScrolled(int position, float positionOffset,int positionOffsetPixels);public void onPageSelected(int position);public void onPageScrollStateChanged(int state);}// 對(duì)外的ViewPager的回調(diào)接口private PageChangeListener onPageChangeListener;// 對(duì)外的ViewPager的回調(diào)接口的設(shè)置public void setOnPageChangeListener(PageChangeListener pageChangeListener) {this.onPageChangeListener = pageChangeListener;}// 設(shè)置關(guān)聯(lián)的ViewPagerpublic void setViewPager(ViewPager mViewPager, int pos) {this.mViewPager = mViewPager;mViewPager.addOnPageChangeListener(new OnPageChangeListener() {@Overridepublic void onPageSelected(int position) {// 設(shè)置字體顏色高亮resetTextViewColor();highLightTextView(position);// 回調(diào)if (onPageChangeListener != null) {onPageChangeListener.onPageSelected(position);}}@Overridepublic void onPageScrolled(int position, float positionOffset,int positionOffsetPixels) {// 滾動(dòng)scroll(position, positionOffset);// 回調(diào)if (onPageChangeListener != null) {onPageChangeListener.onPageScrolled(position,positionOffset, positionOffsetPixels);}}@Overridepublic void onPageScrollStateChanged(int state) {// 回調(diào)if (onPageChangeListener != null) {onPageChangeListener.onPageScrollStateChanged(state);}}});// 設(shè)置當(dāng)前頁mViewPager.setCurrentItem(pos);// 高亮highLightTextView(pos);}/*** 設(shè)置指示器顏色*/public void setIndicatorColor(int IndicatorColor){this.IndicatorColor = IndicatorColor;mPaint.setColor(IndicatorColor);invalidate();}/*** 設(shè)置正常標(biāo)題顏色* @param COLOR_TEXT_NORMAL*/public void setCOLOR_TEXT_NORMAL(int COLOR_TEXT_NORMAL) {this.COLOR_TEXT_NORMAL = COLOR_TEXT_NORMAL;}/*** 設(shè)置選中標(biāo)題顏色* @param COLOR_TEXT_HIGHLIGHTCOLOR*/public void setCOLOR_TEXT_HIGHLIGHTCOLOR(int COLOR_TEXT_HIGHLIGHTCOLOR) {this.COLOR_TEXT_HIGHLIGHTCOLOR = COLOR_TEXT_HIGHLIGHTCOLOR;}/*** 高亮文本** @param position*/protected void highLightTextView(int position) {View view = getChildAt(position);if (view instanceof TextView) {((TextView) view).setTextColor(COLOR_TEXT_HIGHLIGHTCOLOR);}}/*** 重置文本顏色*/private void resetTextViewColor() {for (int i = 0; i < getChildCount(); i++) {View view = getChildAt(i);if (view instanceof TextView) {((TextView) view).setTextColor(COLOR_TEXT_NORMAL);}}}/*** 設(shè)置點(diǎn)擊事件*/public void setItemClickEvent() {int cCount = getChildCount();for (int i = 0; i < cCount; i++) {final int j = i;View view = getChildAt(i);view.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {mViewPager.setCurrentItem(j);}});}}/*** 根據(jù)標(biāo)題生成我們的TextView** @param text* @return*/private TextView generateTextView(String text){TextView tv = new TextView(getContext());LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);lp.width =(mWidth!=-1?mWidth:getScreenWidth())/ mTabVisibleCount;tv.setGravity(Gravity.CENTER);tv.setTextColor(COLOR_TEXT_NORMAL);tv.setText(text);tv.setTextSize(textSize!=-1f?textSize:DEFAULT_TEXTSIZE);tv.setLayoutParams(lp);return tv;}/*** 初始化矩形指示器*/private void iniTrectangle() {mPath = new Path();mPath.rewind();mTriangleHeight = 50;//指示條的高度mPath.moveTo(mTriangleWidth, mTriangleHeight / 5);mPath.lineTo(-mTriangleWidth / 100, mTriangleHeight / 5);mPath.lineTo(-mTriangleWidth / 100, -mTriangleHeight / 5);mPath.lineTo(mTriangleWidth, -mTriangleHeight / 5);mPath.close();}/*** 指示器跟隨手指滾動(dòng),以及容器滾動(dòng)** @param position* @param offset*/public void scroll(int position, float offset) {/*** <pre>* 0-1:position=0 ;1-0:postion=0;* </pre>*/// 不斷改變偏移量,invalidatemTranslationX = getWidth() / mTabVisibleCount * (position + offset);int tabWidth = getScreenWidth() / mTabVisibleCount;// 容器滾動(dòng),當(dāng)移動(dòng)到倒數(shù)最后一個(gè)的時(shí)候,開始滾動(dòng)if (offset > 0 && position >= (mTabVisibleCount - 2)&& getChildCount() > mTabVisibleCount) {if (mTabVisibleCount != 1) {this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth+ (int) (tabWidth * offset), 0);} else// 為count為1時(shí) 的特殊處理{this.scrollTo(position * tabWidth + (int) (tabWidth * offset), 0);}}invalidate();}/*** 設(shè)置布局中view的一些必要屬性;如果設(shè)置了setTabTitles,布局中view則無效*/@Overrideprotected void onFinishInflate() {super.onFinishInflate();int cCount = getChildCount();if (cCount == 0)return;for (int i = 0; i < cCount; i++) {View view = getChildAt(i);LayoutParams lp = (LayoutParams) view.getLayoutParams();lp.weight = 0;lp.width = getScreenWidth() / mTabVisibleCount;view.setLayoutParams(lp);}// 設(shè)置點(diǎn)擊事件setItemClickEvent();}/*** 獲得屏幕的寬度** @return*/public int getScreenWidth() {WindowManager wm = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wm.getDefaultDisplay().getMetrics(outMetrics);return outMetrics.widthPixels;}}使用方式
1 . Activity中初始化設(shè)置
indicator=new ViewPagerBelowIndicator(this);int mWidth= Axis.getWidth()-Axis.scaleX(300)*2;indicator.setmWidth(mWidth);indicator.setVisibleTabCount(3);indicator.setCOLOR_TEXT_NORMAL(Color.BLACK);indicator.setTextSize(Axis.scaleTextSize(32));indicator.setCOLOR_TEXT_HIGHLIGHTCOLOR(ContextCompat.getColor(this,R.color.color3973FF));indicator.setIndicatorColor(Color.TRANSPARENT);RelativeLayout.LayoutParams indicator_lp=new RelativeLayout.LayoutParams(mWidth,HEAD_WIDTH);indicator_lp.addRule(RelativeLayout.CENTER_IN_PARENT);headView.addView(indicator,indicator_lp);2 . 和 ViewPager 對(duì)象關(guān)聯(lián)
List<String> mTitles = Arrays.asList("云端", "車機(jī)", "手機(jī)");//給tab加上標(biāo)題indicator.setTabItemTitles(mTitles);//設(shè)置關(guān)聯(lián)的ViewPager,默認(rèn)顯示第一個(gè)indicator.setViewPager(mViewPager,1);//mViewPager為ViewPager子類總結(jié)
以上是生活随笔為你收集整理的Android 自定义控件 ViewPager头部指示器控件 ViewPagerBelowIndicator的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android RecyclerView
- 下一篇: Android 自定义控件一 带圆形进度