android tab選項卡的使用

 項目作完了,寫寫博客,在項目中遇到的一些問題,或者是本身以爲很不錯的東西。這一篇主要是想和你們分享一下我在項目中封裝的一個東西,就是tab選項卡。先看看效果圖:android

我在網上看了不少有關選項卡的demo,但是發現都不太符合個人需求,萬惡的產品經理想作的效果是選項卡中的文字有多長,文字下方的線就顯示多長,無奈之下,本身寫了。因爲項目中不少地方都有用這個東東,因此我就封裝了這一個,先看看代碼。數組

這是封裝的代碼:ide

public class ViewPagerIndicator extends HorizontalScrollView implements
OnPageChangeListener, OnClickListener {

private RelativeLayout[] tabArr;// tab數組
private String[] tabTexts;// tab標題數組
private int[] tabTextWidthArr;// tab標題寬度數組

private int currTabPosition;// 當前選中的tab
private float fromTransX;// 遊標在啓動動畫以前的X軸座標
private int tabSpacing;// tab之間的間距
private int cursorPadding;// tab默認和cursor長度同樣
private int mTextColor = getResources().getColor(R.color.gray_666666);
private float mTextSize = 13;
private int tabLength;// tab個數
private int diviceWidth;// 設備寬度px
private float fromScaleX = 1.0f;
private int baseCursorWidth;// 初始化的遊標寬度, 縮放動畫每次以此爲標準
private Boolean autoArrange = true;
private Boolean isPageFirstScrolled = true;
private int unSelectTextColor = getResources().getColor(R.color.gray_999999); //設置選中字體的顏色
private int selectTextColor = getResources().getColor(R.color.blue_45a7ff); //設置未選中字體的顏色


private Context mContext;
private ViewPager mViewPager;
private LinearLayout tabLy;// tab的橫向線性佈局
private ImageView cursor;// 遊標
private Handler handler = new Handler();
View line;


public ViewPagerIndicator(Context context) {
super(context);
// TODO Auto-generated constructor stub
init();
}

public ViewPagerIndicator(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
init();
}

public ViewPagerIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
init();
}

/**
* 初始化基本佈局
*/
private void init() {
// TODO Auto-generated method stub
mContext = getContext();
diviceWidth = DensityUtil.getDisplayWidth((Activity) mContext);
// 設置屬性
this.setBackgroundColor(getResources().getColor(R.color.white));
this.setHorizontalScrollBarEnabled(false);// 去掉滾動條
this.setVisibility(View.GONE);
// 加載ScrollView的內容佈局
View v = View.inflate(mContext, R.layout.viewpager_indicator_layout, null);
tabLy = (LinearLayout) v.findViewById(R.id.main_tab);// Tab佈局
cursor = (ImageView) v.findViewById(R.id.main_cursor);// 遊標

line = v.findViewById(R.id.line); //得到中間那條線
this.addView(v);
}


public void setLinevisibility(boolean isShow) {
line.setVisibility(isShow ? View.VISIBLE : View.GONE);
}

/**
* 設置參數.
*
* @param tabSpacing tab間距
* @param cursorPadding 遊標向左右延伸的距離, 默認爲0, 也即和tab文本同樣長
* @param viewPager 設置ViewPager
* @param tabTexts tab內容數組
* @param autoArrange 當tab長度不足屏幕寬度時, 是否自動進行擺列, 默認爲true
*/
public void setParams(int tabSpacing, int cursorPadding, String[] tabTexts,
ViewPager viewPager, Boolean autoArrange) {
if (tabTexts == null || tabTexts.length < 1) {
return;
}
this.tabSpacing = tabSpacing;
this.cursorPadding = cursorPadding;
this.tabTexts = tabTexts;
this.mViewPager = viewPager;
this.autoArrange = autoArrange;

this.setVisibility(View.VISIBLE);
initTabSpacing();
initTabs();
initCursor();
onPageSelected(currTabPosition);// 初始化tab樣式和動畫
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(this);
}
}

/**
* 肯定tab間隙長度
*/
private void initTabSpacing() {
// TODO Auto-generated method stub
tabLength = tabTexts.length;
int tabTextsWidth = 0;// tab文本總長度
TextView tv = new TextView(mContext);
tabTextWidthArr = new int[tabLength];
for (int i = 0; i < tabLength; i++) {
tv.setTextSize(mTextSize);
tabTextWidthArr[i] = (int) tv.getPaint().measureText(tabTexts[i]);
tabTextsWidth += tabTextWidthArr[i];
}
int scrollViewWidth = tabTextsWidth + tabLength * tabSpacing;
// 默認, tab(包括間隙)總長度小於屏幕寬度時, 從新計算間距, 讓各個tab均勻填滿scrollview
if (autoArrange && scrollViewWidth < diviceWidth) {
tabSpacing = (diviceWidth - tabTextsWidth) / tabLength;
}
}

/**
* 初始化Tab
*/
private void initTabs() {
tabLy.removeAllViews();
tabArr = new RelativeLayout[tabLength];
TextView tabTextView = null;
for (int i = 0; i < tabLength; i++) {
// 初始化tabArr
LinearLayout.LayoutParams tabParam = new LinearLayout.LayoutParams(
tabTextWidthArr[i] + tabSpacing, LayoutParams.MATCH_PARENT);
tabArr[i] = (RelativeLayout) View.inflate(mContext,
R.layout.viewpager_indicator_tab, null);
tabArr[i].setLayoutParams(tabParam);
tabArr[i].setTag(i);
tabArr[i].setOnClickListener(this);
// 初始化tabTextViewArr
tabTextView = (TextView) tabArr[i].findViewById(R.id.tab_tv);
tabTextView.setTextSize(mTextSize);
tabTextView.setTextColor(mTextColor);
tabTextView.setText(tabTexts[i]);
// 添加子tab
tabLy.addView(tabArr[i], i);
}
}

@Override
public void onClick(View v) {
int i = (Integer) v.getTag();
setTabClick(i);
}

/**
* 設置當前Tab點擊時事件
*
* @param position
*/
private void setTabClick(int position) {
// 若是點擊的爲當前的Tab,則滾回到頂部, 不然切換
if (position == currTabPosition) {

} else {
mViewPager.setCurrentItem(position);
}
}

/**
* 初始化cursor長度
*/
private void initCursor() {
// TODO Auto-generated method stub
baseCursorWidth = tabTextWidthArr[currTabPosition] + cursorPadding;
RelativeLayout.LayoutParams cursorLp = (RelativeLayout.LayoutParams) cursor
.getLayoutParams();
cursorLp.width = baseCursorWidth;
cursor.setLayoutParams(cursorLp);
}

@Override
public void onPageScrollStateChanged(int arg0) {
}

@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}

@Override
public void onPageSelected(final int position) {
// TODO Auto-generated method stub
currTabPosition = position;
setTabStyle(position);// 改變tab字體顏色
handler.post(new Runnable() {

@Override
public void run() {
setTabAnimation(position);
}
});
}


/**
* 設置未選中tab字體的顏色
*/
public void setUnSelectTextColor(int UnSelectTextColor) {
this.unSelectTextColor = UnSelectTextColor;
}

/**
* 設置選中tab字體的顏色
*/
public void setSelectTextColor(int selectTextColor) {
this.selectTextColor = selectTextColor;
}

/**
* 設置tab字體的大小
*/
public void setTextSize(int textSize){
this.mTextSize = textSize;
}


/**
* 設置選中項背景和字體顏色
*
* @param position
*/
private void setTabStyle(int position) {
// 還原Tab的背景和字體顏色
for (int i = 0; i < tabLength; i++) {
((TextView) tabArr[i].getChildAt(0)).setTextColor(unSelectTextColor);
}
// 改變 選中文本的顏色, 同時紅點消失
((TextView) tabArr[position].getChildAt(0)).setTextColor(selectTextColor);
}

/**
* 設置tab的動畫
*
* @param position
*/
private void setTabAnimation(final int position) {
// 選中的tab中心位置到scrollview最左邊位置的距離
int offset = 0;
for (int i = 0; i < position; i++) {
offset += tabTextWidthArr[i] + tabSpacing;
}
offset += (tabTextWidthArr[position] + tabSpacing) / 2;
// tab滾動到居中位置
int scrollOffset = offset - diviceWidth / 2 <= 0 ? 0 : offset
- diviceWidth / 2;
smoothScrollTo(scrollOffset, 0);

// 移動動畫
offset -= (tabTextWidthArr[0] / 2 + cursorPadding / 2);

Animation translateAnim = new TranslateAnimation(isPageFirstScrolled ? offset : fromTransX, offset, 0,
0);
fromTransX = offset;
isPageFirstScrolled = false;

// 縮放動畫, 以初始化的cursor爲縮放參考
offset = tabTextWidthArr[currTabPosition] + cursorPadding;
float toScaleX = (float) offset / (float) baseCursorWidth;
Animation scaleAnim = new ScaleAnimation(fromScaleX, toScaleX, 1.0f,
1.0f, Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);// 中間爲縮放中心
fromScaleX = toScaleX;

// 將兩個動畫添加進集合, 同時執行
AnimationSet anim = new AnimationSet(true);
anim.addAnimation(scaleAnim); // 注意: 先添加縮放動畫, 不然會出問題, 緣由不知
anim.addAnimation(translateAnim);
anim.setDuration(300);
anim.setFillAfter(true);
cursor.startAnimation(anim); // 開始動畫
}


}




viewpager_indicator_layout文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

<View
android:id="@+id/line"
android:layout_width="1px"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="@color/gray_cccccc"
android:layout_marginTop="5dp"
android:layout_marginBottom="5dp"
android:visibility="gone"
/>


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<LinearLayout
android:id="@+id/main_tab"
android:layout_width="wrap_content"
android:layout_height="0dip"
android:layout_weight="1"
android:gravity="center_vertical"
android:orientation="horizontal" />

<View
android:layout_width="match_parent"
android:layout_height="1px"
android:background="@color/gray_cccccc" />
</LinearLayout>

<ImageView
android:id="@+id/main_cursor"
android:layout_width="wrap_content"
android:layout_height="2dip"
android:layout_alignParentBottom="true"
android:scaleType="matrix"
android:src="@drawable/youdan_cursor_bg" />

</RelativeLayout>












而後在佈局文件中用:

<com.manqian.mqlibrary.view.ViewPagerIndicator
android:id="@+id/horizontal_scrollview"
android:layout_width="match_parent"
android:layout_height="47dp" />

<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

這裏個人說一下,
com.manqian.mqlibrary.view.ViewPagerIndicator  這個是你把這個封裝的文件放在項目的路徑,這個是個人路徑,有的同窗就會直接複製過去,發現報錯,要會靈活一點。好了,我先說說一下個人思路,你們能夠看到,我封裝的時候繼承了什麼吧,對的,就是這個horizontalscrollview,這個是水平的scrollview,也就是說是它可使得tab能夠水平滑動,還有我實現了幾個監聽器,經過監聽器中的幾個方法,從中配合來實現這個功能,具體的,我在代碼上註釋的比較清楚了。但願對你們有用。
相關文章
相關標籤/搜索