android 打造炫酷導航欄(仿UC頭條)
來自: http://blog.csdn.net/qq_16064871/article/details/50682388
年后開始上班甚是清閑,所以想搗鼓一些東西。在翻閱大神杰作Android 教你打造炫酷的ViewPagerIndicator 不僅僅是高仿MIUI 的時候看到下面有一條評論說,如果導航欄能滑動就更好了。我就想我可以去改一下就可以。然后又想感覺有點像UC的頭條的界面。于是就往里面加東西,調試寫代碼。弄了兩天有點效果了,寫出來看看了。
項目下載地址:http://download.csdn.net/detail/qq_16064871/9434291
1、先看效果
用咔咔大師錄屏的gif效果,有點失真。


這是第一個版本的效果。因為我不斷往里面加東西,所以有幾個版本了。
2、這個版本基本代碼
實現思路就是自定義繪制了。主要有兩層,第一層是ViewPagerIndicator。主要負責導航欄的三角形指示器的繪制,以及頁面滑動的回調,控制。當然這里需要android.support.v4.view.ViewPager這東西配合使用。
第二層是,導航欄的滑動效果,以及最左、最右有 反彈的效果。這個效果我是從以前一篇博文改動到了這里來。鏈接:android 滾動條下拉反彈的效果(類似微信朋友圈)。這里效果是垂直,改為橫向就行了。還有這兩層同時使用需要處理就是滑動不要沖突就可以了。
xml布局代碼:
<com.ucnew.view.BounceScrollView
android:id="@+id/id_scrollview"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:scrollbars="none" >
<com.ucnew.view.ViewPagerIndicator
android:id="@+id/id_indicator"
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal"
mmsx:item_count="4" >
</com.ucnew.view.ViewPagerIndicator>
</com.ucnew.view.BounceScrollView> 3、自定義view的java代碼
ViewPagerIndicator
package com.ucnew.view;
import java.util.List;
import com.ucnew.activity.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.CornerPathEffect;
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.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.TextView;
public class ViewPagerIndicator extends LinearLayout
{
//繪制三角形的畫筆
private Paint mPaint;
//path構成一個三角形
private Path mPath;
//三角形的寬度
private int mTriangleWidth;
// 三角形的高度
private int mTriangleHeight;
//三角形的寬度為單個Tab的1/6
private static final float RADIO_TRIANGEL = 1.0f / 6;
// 三角形的最大寬度
private final int DIMENSION_TRIANGEL_WIDTH = (int) (getScreenWidth() / 3 * RADIO_TRIANGEL);
//初始時,三角形指示器的偏移量
private int mInitTranslationX;
// 手指滑動時的偏移量
private float mTranslationX;
// tab數量
private int mTabVisibleCount;
// tab上的內容
private List<String> mTabTitles;
// 與之綁定的ViewPager
public ViewPager mViewPager;
// 標題正常時的顏色
private static final int COLOR_TEXT_NORMAL = 0x77FFFFFF;
//標題選中時的顏色
private static final int COLOR_TEXT_HIGHLIGHTCOLOR = 0xFFFFFFFF;
public ViewPagerIndicator(Context context)
{
this(context, null);
}
public ViewPagerIndicator(Context context, AttributeSet attrs)
{
super(context, attrs);
// 獲得自定義屬性,tab的數量
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.ViewPagerIndicator);
mTabVisibleCount = a.getInt(R.styleable.ViewPagerIndicator_item_count,4);
if (mTabVisibleCount < 0)
mTabVisibleCount = 4;
a.recycle();
// 初始化畫筆
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.parseColor("#ffffffff"));
mPaint.setStyle(Style.FILL);
mPaint.setPathEffect(new CornerPathEffect(3));
}
//繪制指示器
@Override
protected void dispatchDraw(Canvas canvas)
{
canvas.save();
// 畫筆平移到正確的位置
canvas.translate(mInitTranslationX + mTranslationX, getHeight() + 1);
canvas.drawPath(mPath, mPaint);
canvas.restore();
super.dispatchDraw(canvas);
}
//初始化三角形的寬度
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
mTriangleWidth = (int) (w / mTabVisibleCount * RADIO_TRIANGEL);// 1/6 of
// width
mTriangleWidth = Math.min(DIMENSION_TRIANGEL_WIDTH, mTriangleWidth);
// 初始化三角形
initTriangle();
// 初始時的偏移量
mInitTranslationX = getScreenWidth() / mTabVisibleCount / 2 - mTriangleWidth / 2;
}
//設置可見的tab的數量
public void setVisibleTabCount(int count)
{
this.mTabVisibleCount = count;
}
//設置tab的標題內容 可選,生成textview加入布局,靈活處理
public void setTabItemTitles(List<String> datas)
{
// 如果傳入的list有值,則移除布局文件中設置的view
if (datas != null && datas.size() > 0)
{
this.removeAllViews();
this.mTabTitles = datas;
for (String title : mTabTitles)
{
// 添加view
addView(generateTextView(title));
}
// 設置item的click事件
setItemClickEvent();
}
}
//根據標題生成我們的TextView
private TextView generateTextView(String text)
{
TextView tv = new TextView(getContext());
LinearLayout.LayoutParams lp = new LayoutParams(
LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
lp.width = getScreenWidth() / mTabVisibleCount;
tv.setGravity(Gravity.CENTER);
tv.setTextColor(COLOR_TEXT_NORMAL);
tv.setText(text);
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16);
tv.setLayoutParams(lp);
return tv;
}
//對外的ViewPager的回調接口
public interface PageChangeListener
{
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels);
public void onPageSelected(int position);
public void onPageScrollStateChanged(int state);
}
// 對外的ViewPager的回調接口
private PageChangeListener onPageChangeListener;
// 對外的ViewPager的回調接口的設置
public void setOnPageChangeListener(PageChangeListener pageChangeListener)
{
this.onPageChangeListener = pageChangeListener;
}
// 設置關聯的ViewPager,以及傳入 BounceScrollView,進行設置滾動
public void setViewPager(ViewPager mViewPager, final BounceScrollView scrollView, int pos)
{
this.mViewPager = mViewPager;
mViewPager.setOnPageChangeListener(new OnPageChangeListener()
{
@Override
public void onPageSelected(int position)
{
// 設置字體顏色高亮
resetTextViewColor();
highLightTextView(position);
// 回調
if (onPageChangeListener != null)
{
onPageChangeListener.onPageSelected(position);
}
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels)
{
// 滾動
scroll(scrollView,position, positionOffset);
// 回調
if (onPageChangeListener != null)
{
onPageChangeListener.onPageScrolled(position,
positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageScrollStateChanged(int state)
{
// 回調
if (onPageChangeListener != null)
{
onPageChangeListener.onPageScrollStateChanged(state);
}
}
});
// 設置當前頁
mViewPager.setCurrentItem(pos);
// 高亮
highLightTextView(pos);
}
//高亮文本
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);
}
}
}
// 設置點擊事件
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()
{
@Override
public void onClick(View v)
{
mViewPager.setCurrentItem(j);
}
});
}
}
// 初始化三角形指示器
private void initTriangle()
{
mPath = new Path();
mTriangleHeight = (int) (mTriangleWidth / 2 / Math.sqrt(2));
mPath.moveTo(0, 0);
mPath.lineTo(mTriangleWidth, 0);
mPath.lineTo(mTriangleWidth / 2, -mTriangleHeight);
mPath.close();
}
//指示器跟隨手指滾動,以及容器滾動
public void scroll(BounceScrollView scrollView,int position, float offset)
{
// 不斷改變偏移量,invalidate
mTranslationX = getScreenWidth() / mTabVisibleCount * (position + offset);
int tabWidth = getScreenWidth() / mTabVisibleCount;
// 容器滾動,當移動到倒數最后一個的時候,開始滾動
if (offset > 0 && position >= (mTabVisibleCount - 1) && getChildCount() > mTabVisibleCount)
{
if (mTabVisibleCount != 1)
{
//下面注釋掉,是滾動ViewPagerIndicator這個LinearLayout
// this.scrollTo((position - (mTabVisibleCount - 1)) * tabWidth + (int) (tabWidth * offset), 0);
//只滾動滾動條,禁止滾動lineayout
scrollView.setScrolledTo((position - (mTabVisibleCount - 1)) * tabWidth + (int) (tabWidth * offset), 0);
} else
// 為count為1時 的特殊處理
{
this.scrollTo(position * tabWidth + (int) (tabWidth * offset), 0);
// scrollView.setScrolledTo(position * tabWidth + (int) (tabWidth * offset), 0);
}
}
//處理特殊情況
else if (offset > 0 && position <= mTabVisibleCount - 1) {
scrollView.setScrolledTo(0, 0);
}
invalidate();
}
//設置布局中view的一些必要屬性;如果設置了setTabTitles,布局中view則無效
@Override
protected void onFinishInflate()
{
super.onFinishInflate();
int cCount = getChildCount();
if (cCount == 0)
return;
for (int i = 0; i < cCount; i++)
{
View view = getChildAt(i);
LinearLayout.LayoutParams lp = (LayoutParams) view
.getLayoutParams();
lp.weight = 0;
lp.width = getScreenWidth() / mTabVisibleCount;
view.setLayoutParams(lp);
}
// 設置點擊事件
setItemClickEvent();
}
//獲得屏幕的寬度
public int getScreenWidth()
{
WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels ;
}
} BounceScrollView
package com.ucnew.view;
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.TranslateAnimation;
import android.widget.HorizontalScrollView;
/**
* ScrollView反彈效果的實現
*/
public class BounceScrollView extends HorizontalScrollView {
// 孩子View
private View inner;
// 點擊時x坐標
private float x;
// 矩形(這里只是個形式,只是用于判斷是否需要動畫
private Rect normal = new Rect();
// 是否開始計算
private boolean isCount = false;
private RotatImageView mRotatImageView;
public BounceScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
/***
* 根據 XML 生成視圖工作完成.該函數在生成視圖的最后調用,在所有子視圖添加完之后. 即使子類覆蓋了 onFinishInflate
* 方法,也應該調用父類的方法,使該方法得以執行.
*/
@Override
protected void onFinishInflate() {
if (getChildCount() > 0) {
inner = getChildAt(0);
}
}
//手動需要設置滾動位置
public void setScrolledTo(int position, float positionOffset) {
this.scrollTo(position,(int) positionOffset);
}
//監聽touch
@Override
public boolean onTouchEvent(MotionEvent ev) {
if (inner != null) {
commOnTouchEvent(ev);
}
return super.onTouchEvent(ev);
}
//觸摸事件
public void commOnTouchEvent(MotionEvent ev) {
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_UP:
// 手指松開.
if (isNeedAnimation()) {
animation();
isCount = false;
}
break;
/***
* 排除出第一次移動計算,因為第一次無法得知y坐標, 在MotionEvent.ACTION_DOWN中獲取不到,
* 因為此時是MyScrollView的touch事件傳遞到到了LIstView的孩子item上面.所以從第二次計算開始.
* 然而我們也要進行初始化,就是第一次移動的時候讓滑動距離歸0. 之后記錄準確了就正常執行.
*/
case MotionEvent.ACTION_MOVE:
final float preX = x;// 按下時的y坐標
float nowX = ev.getX();// 時時y坐標
int deltaX = (int) (preX - nowX);// 滑動距離
if (!isCount) {
deltaX = 0; // 在這里要歸0.
}
x = nowX;
// 當滾動到最上或者最下時就不會再滾動,這時移動布局
if (isNeedMove()) {
// 初始化頭部矩形
if (normal.isEmpty()) {
// 保存正常的布局位置
normal.set(inner.getLeft(), inner.getTop(),
inner.getRight(), inner.getBottom());
}
// 移動布局
inner.layout(inner.getLeft() - deltaX / 4, inner.getTop(),
inner.getRight() - deltaX / 4, inner.getBottom());
//圖片加號旋轉,如果不需要這個直接刪了就行
if (mRotatImageView != null) {
mRotatImageView.setRotationLeft();
}
}
isCount = true;
break;
default:
break;
}
}
//回縮動畫
public void animation() {
// 開啟移動動畫
TranslateAnimation ta = new TranslateAnimation(0, 0, inner.getTop(),
normal.top);
ta.setDuration(200);
inner.startAnimation(ta);
// 設置回到正常的布局位置
inner.layout(normal.left, normal.top, normal.right, normal.bottom);
normal.setEmpty();
}
//設置圖片加號旋轉
public void setRotatImageView(RotatImageView rotatImageView){
this.mRotatImageView = rotatImageView;
}
// 是否需要開啟動畫
public boolean isNeedAnimation() {
return !normal.isEmpty();
}
/***
* 是否需要移動布局 inner.getMeasuredHeight():獲取的是控件的總高度
* getHeight():獲取的是屏幕的高度
*/
public boolean isNeedMove() {
int offset = inner.getMeasuredWidth() - getWidth();
int scrollX = getScrollX();
// 0是頂部反彈
//是底部反彈加上
if (scrollX == 0 || scrollX == offset) {
return true;
}
return false;
}
} 都有很詳細的注釋,以及測試需要說明。
那么就直接看下一個版本。
4、看下一個版本效果

多了一個圖標,這個圖標可以用來監聽,等等。
我后面搗鼓加了一個旋轉動畫,動畫效果可能不是很好。但也可以看看。
5、xml代碼
有一些自定義屬性以及效果的代碼就不貼,感興趣下載源碼。看不懂的,看我前幾篇文章,自定義控件使用。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:mmsx="http://schemas.android.com/apk/res/com.ucnew.activity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffffff"
android:orientation="vertical" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#8000bf5f" >
<com.ucnew.view.BounceScrollView
android:id="@+id/id_scrollview"
android:layout_width="0dp"
android:layout_height="45dp"
android:layout_weight="1"
android:focusableInTouchMode="false"
android:scrollbars="none" >
<com.ucnew.view.ViewPagerIndicator
android:id="@+id/id_indicator"
android:layout_width="match_parent"
android:layout_height="45dp"
android:orientation="horizontal"
mmsx:item_count="4" >
</com.ucnew.view.ViewPagerIndicator>
</com.ucnew.view.BounceScrollView>
<com.ucnew.view.RotatImageView
android:id="@+id/id_rotat_imageView"
android:layout_width="50dp"
android:layout_height="wrap_content"
android:paddingLeft="30dp"
android:layout_gravity="center"
mmsx:src="@drawable/add" >
</com.ucnew.view.RotatImageView>
</LinearLayout>
<android.support.v4.view.ViewPager
android:id="@+id/id_vp"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</android.support.v4.view.ViewPager>
</LinearLayout> 6、增加以及這里主要主要需要改的代碼。
ViewPagerIndicator類的這個函數
//獲得屏幕的寬度
public int getScreenWidth()
{
WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
//獲取是整個屏幕的寬度,我試過自定義寬度測量寬度,不行。因為本身還沒內容,是后面添加的。所以需要后面加東西
//需要這里減去寬度就行。其中這里減去120就是60dp的寬度
return outMetrics.widthPixels -100;
} 還有一個圖片的旋轉類RotatImageView
package com.ucnew.view;
import com.ucnew.activity.R;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class RotatImageView extends View {
private Paint paint = null; // 畫筆
private Bitmap mbitmap = null; // 圖片位圖
private Bitmap bitmapDisplay = null;
private Matrix matrix = null;
private int mWidth = 0; // 圖片的寬度
private int mHeight = 0; // 圖片的高度
private float fAngle = 180.0f; // 圖片旋轉
private PaintFlagsDrawFilter mDrawFilter;
public RotatImageView(Context context) {
super(context);
}
public RotatImageView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
/**
* 初始化一些自定義的參數
*
* @param context
* @param attrs
* @param defStyle
*/
public RotatImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.RotatImageView, defStyle, 0);
int n = a.getIndexCount();
for (int i = 0; i < n; i++) {
int attr = a.getIndex(i);
switch (attr) {
// 原始圖片,在布局里面獲取
case R.styleable.RotatImageView_src:
mbitmap = BitmapFactory.decodeResource(getResources(),a.getResourceId(attr, 0));
bitmapDisplay = mbitmap;
break;
}
}
a.recycle();
mDrawFilter = new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG|Paint.FILTER_BITMAP_FLAG);
paint = new Paint();
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
matrix = new Matrix();
}
/**
* 計算控件的高度和寬度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
// 設置寬度
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
//match_parent或者設置的精確值獲取
//MeasureSpec.EXACTLY
if (specMode == MeasureSpec.EXACTLY)
{
mWidth = specSize;
}
else
{
// 由圖片決定的寬
//getPaddingLeft(),getPaddingRight()這兩個值是控件屬性的向內偏移的距離值,所以的一起計算
//區別于layout_marginLeft,兩個控件的左間距值設置
int desireByImg = getPaddingLeft() + getPaddingRight()
+ mbitmap.getWidth();
// wrap_content
if (specMode == MeasureSpec.AT_MOST)
{
//所以最小的值,寬度的話是左右內偏移距離之和
mWidth = Math.min(desireByImg, specSize);
} else
mWidth = desireByImg;
}
// 設置高度,部分解釋同上
specMode = MeasureSpec.getMode(heightMeasureSpec);
specSize = MeasureSpec.getSize(heightMeasureSpec);
//match_parent或者設置的精確值獲取
//MeasureSpec.EXACTLY
if (specMode == MeasureSpec.EXACTLY)
{
mHeight = specSize;
} else
{
int desire = getPaddingTop() + getPaddingBottom()
+ mbitmap.getHeight();
// wrap_content
if (specMode == MeasureSpec.AT_MOST)
{
mHeight = Math.min(desire, specSize);
} else
mHeight = desire;
}
//計算好的寬度以及高度是值,設置進去
setMeasuredDimension(mWidth, mHeight);
}
// 向左旋轉
public void setRotationLeft() {
fAngle = fAngle - 20;
setAngle();
}
// 向右旋轉
public void setRotationRight() {
fAngle = fAngle + 20;
setAngle();
}
private boolean isRoate = false;
// 設置旋轉比例
private void setAngle() {
Log.i("Show", String.valueOf(fAngle));
isRoate = true;
//設置圖片的旋轉中心,即繞(X,Y)這點進行中心旋轉 要旋轉的角度
matrix.preRotate(fAngle, (float)mbitmap.getWidth()/2, (float)mbitmap.getHeight()/2);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//消除鋸齒, 圖片旋轉后的鋸齒消除不成功,實在不行圖片邊緣加一些白色像素點
canvas.setDrawFilter(mDrawFilter);
if (isRoate) {
canvas.drawBitmap(bitmapDisplay, matrix, paint);
isRoate = false;
}else {
canvas.drawBitmap(bitmapDisplay, 0, 0, paint);
}
}
} activity調用以及初始化這些自定義控件
package com.ucnew.activity;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.ucnew.activity.R;
import com.ucnew.fragment.VpSimpleFragment;
import com.ucnew.view.BounceScrollView;
import com.ucnew.view.RotatImageView;
import com.ucnew.view.ViewPagerIndicator;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.Window;
public class MainActivity extends FragmentActivity
{
private List<Fragment> mTabContents = new ArrayList<Fragment>();
private FragmentPagerAdapter mAdapter;
private ViewPager mViewPager;
private List<String> mDatas = Arrays.asList("頁面1", "頁面2", "頁面3", "頁面4",
"頁面5", "頁面6", "頁面7", "頁面8", "頁面9");
private ViewPagerIndicator mIndicator;
private BounceScrollView mScrollView;
private RotatImageView mRotatImageView;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.vp_indicator);
initView();
initDatas();
//設置Tab上的標題
mIndicator.setTabItemTitles(mDatas);
mViewPager.setAdapter(mAdapter);
//設置關聯的ViewPager
mIndicator.setViewPager(mViewPager,mScrollView,0);
//設置關聯的圖片旋轉,根據需要設置,效果不是很好
mScrollView.setRotatImageView(mRotatImageView);
}
private void initDatas()
{
for (String data : mDatas)
{
VpSimpleFragment fragment = VpSimpleFragment.newInstance(data);
mTabContents.add(fragment);
}
mAdapter = new FragmentPagerAdapter(getSupportFragmentManager())
{
@Override
public int getCount()
{
return mTabContents.size();
}
@Override
public Fragment getItem(int position)
{
return mTabContents.get(position);
}
};
}
private void initView()
{
mScrollView = (BounceScrollView) findViewById(R.id.id_scrollview);
mViewPager = (ViewPager) findViewById(R.id.id_vp);
mIndicator = (ViewPagerIndicator) findViewById(R.id.id_indicator);
mRotatImageView = (RotatImageView)findViewById(R.id.id_rotat_imageView);
}
}
還有部分代碼沒貼。自已下載查看吧。
7、最后效果圖

錄屏不是很清晰,來一張截圖,夠清晰的

項目下載地址:http://download.csdn.net/detail/qq_16064871/9434291
用到知識
Android 教你打造炫酷的ViewPagerIndicator 不僅僅是高仿MIUI