1. 程式人生 > >Android 之一個很好的Viewpager滑動指示器

Android 之一個很好的Viewpager滑動指示器

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 static final int COUNT_DEFAULT_TAB = 4;
/**
* tab數量
*/
private int mTabVisibleCount = COUNT_DEFAULT_TAB;


/**
* 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,
COUNT_DEFAULT_TAB);
if (mTabVisibleCount < 0)
mTabVisibleCount = COUNT_DEFAULT_TAB;
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 = getWidth() / mTabVisibleCount / 2 - mTriangleWidth
/ 2;
}


/**
* 設定可見的tab的數量

* @param count
*/
public void setVisibleTabCount(int count)
{
this.mTabVisibleCount = count;
}


/**
* 設定tab的標題內容 可選,可以自己在佈局檔案中寫死

* @param datas
*/
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();
}


}


/**
* 對外的ViewPager的回撥介面

* @author zhy

*/
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
public void setViewPager(ViewPager mViewPager, 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(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);
}


/**
* 高亮文字

* @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);
}
}
}


/**
* 設定點選事件
*/
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);
}
});
}
}


/**
* 根據標題生成我們的TextView

* @param text
* @return
*/
private TextView generateTextView(String text)
{
TextView tv = new TextView(getContext());
LinearLayout.LayoutParams lp = new LinearLayout.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;
}


/**
* 初始化三角形指示器
*/
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();
}


/**
* 指示器跟隨手指滾動,以及容器滾動

* @param position
* @param offset
*/
public void scroll(int position, float offset)
{
/**
* <pre>
*  0-1:position=0 ;1-0:postion=0;
* </pre>
*/
// 不斷改變偏移量,invalidate
mTranslationX = getWidth() / mTabVisibleCount * (position + offset);


int tabWidth = getScreenWidth() / mTabVisibleCount;


// 容器滾動,當移動到倒數最後一個的時候,開始滾動
if (offset > 0 && position >= (mTabVisibleCount - 2)
&& getChildCount() > mTabVisibleCount)
{
if (mTabVisibleCount != 1)
{
this.scrollTo((position - (mTabVisibleCount - 2)) * tabWidth
+ (int) (tabWidth * offset), 0);
} else
// 為count為1時 的特殊處理
{
this.scrollTo(
position * tabWidth + (int) (tabWidth * offset), 0);
}
}


invalidate();
}


/**
* 設定佈局中view的一些必要屬性;如果設定了setTabTitles,佈局中view則無效
*/
@Override
protected void onFinishInflate()
{
Log.e("TAG", "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();


}


/**
* 獲得螢幕的寬度

* @return
*/
public int getScreenWidth()
{
WindowManager wm = (WindowManager) getContext().getSystemService(
Context.WINDOW_SERVICE);
DisplayMetrics outMetrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrics);
return outMetrics.widthPixels;
}


}

相關推薦

Android 之一Viewpager滑動指示器

public class ViewPagerIndicator extends LinearLayout{/*** 繪製三角形的畫筆*/private Paint mPaint;/*** path構成一個三角形*/private Path mPath;/*** 三角形的寬度*/private int mTri

的OJ網站

acc 應該 ica class dev tco 友好 題目 如果 很友好的OJ網站(OJ是open judge,在線評測) POJ 北京大學ACM ZOJ 浙江大學ACM WOJ 武漢大學ACM(一個題目提交通過後,可以查看通過該題的所有代碼) 唯一不好的地方是

用SQL語法(SqlServer)

base class ESS lse 簡單 table 可能 錯誤 mat 1,MERGE INTO 語句: 這個語法僅需要一次全表掃描就完成了全部工作,執行效率要高於INSERT+UPDATE,作用還是很強大的(簡單的說就是它可以批量更新和插入處理一個數據集,如果存在就更

推薦幾的程式設計線上測試平臺 online judge

現在又不少線上測試平臺,這些平臺提供了很多很好的程式設計題,當然著名的acm中會有很多難題,如果你想挑戰自己的智力極限,如果你對程式設計很有興趣,那麼就可以去這些平臺註冊,然後程式設計提交,跟其他程式設計高手一較高下。 線上測試平臺往往提供多種語言的支援,對於一道題,你

分享45android例項原始碼,強大.收藏吧!!!

新增微訊號:apkbus,回覆“視訊”即可獲取400套免費Android開發視訊教程分享45個android例項原始碼,很好很強大http://www.apkbus.com/android-20978-1-1.htmlandriod鬧鐘原始碼http://www.apkbu

Android 具有動畫的 Viewpager滑動CircleIndicator指示器

1.自定義屬性:attrs.xml <?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name="CircleIndicator"

AndroidViewPager新增滑動指示器(2)

上一篇博文使用了開源庫PagerSlidingTabStrip來實現ViewPager的滑動指示器 其實Google官方的Android Support Design包也提供了TabLayout來實現滑動指示器的效果 TabLayout的使用方法也十分簡單,

Android開發——打造簡單的Viewpager指示器(小圓點指示器

ges 其它 tar contex 但是 state 定義 效果 布局 準備工作: 1.兩張不同顏色的小圓點圖片,可以去阿裏巴巴矢量圖網站搜索 我把我使用的圖片貼出來 2.一個簡單的Viewpager的實現 下面是簡單的Viewpager實現步驟:

華為李航 NLP 有 5 基本問題,深度學習有4做得

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Android Viewpager巢狀Viewpager滑動衝突。

場景:tablayout繫結viewpager,viewpager巢狀fragement,其中一個fragment中嵌套了一個子viewpager,導致不能正常滑動。 解決方法: 重寫viewpager的canScroll()方法。 @Override protected bo

[Android]Kongzue.BaseOkHttpV3 - 一款上手的BaseOkHttp封裝

BaseOkHttp V3 Github github.com/kongzue/Bas… 簡介 BaseOkHttp V3是基於BaseOkHttp V2( github.com/kongzue/Bas… )的升級版本,基於能夠快速建立常用請求連結而封裝的庫。

Android 應用開發---ViewPager---5.使用Fragment實現ViewPager滑動

ViewPager 詳解(五)-----使用Fragment實現ViewPager滑動 在第一個頁面加一個Btn                                          第一頁面向第二頁面滑動             第二頁面向第三個頁面滑

Android設計模式之一例子讓你徹底明白工廠模式(Factory Pattern)

提出疑問 這幾天研究工廠模式的時候,看到網上的一些文章中舉的例子我就很疑惑,我相信這也是許多人的疑惑:工廠模式的功能就是建立例項,我們建立例項直接new不就完了嗎,幹嘛還得再封裝一層工廠類,然後用工廠類再去new出這個例項?這不多此一舉嗎? 比如我看到這樣的

Android設計模式之一例子讓你徹底明白裝飾者模式(Decorator Pattern)

導讀 這篇文章中我不會使用概念性文字來說明裝飾者模式,因為通常概念性的問題都很抽象,很難懂,使得讀者很難明白到底為什麼要使用這種設計模式,我們設計模式的誕生,肯定是前輩們在設計程式的時候遇到了某種困難,為了避免這種苦難的發生,從而設計出來的這種設計模式,所以這

android viewpager+fragment與利用viewpager滑動分頁小技巧

一:簡單的實現viewpage進行fragment的滑動切換 public class LcVpFragment extends Fragment{ @Override public void onActivityCreated(Bundle savedInsta

Android中github上面一個的重新整理庫SmartRefreshLayout

SmartRefreshLayout支援:Listview、GridView、Recyclerview, 甚至TextView等等幾乎所有控制元件的重新整理 使用方法: 1.引入依賴: compile 'com.scwang.smartrefresh:SmartRefreshLa

一個實用,學習android xml佈局檔案

用了各種佈局組合成一個漂亮的見面。新手很實用的一個例子,大家學習一下。。。。。。分享 本例用到了(相對佈局,線性佈局的各種巢狀使用) 效果圖片: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout

解決viewpager中兩item迴圈左右滑動出現崩潰問題

在 instantiateItem()方法中 新增如下程式碼  @Override            public Object instantiateItem(ViewGroup container, int position) {            View v

android viewpager 滑動分頁以及禁止劃屏 (模擬新浪)

    這一篇將之加工一下,模擬實現新浪裡面的功能,vierpager 分頁.     在新浪微博訊息一欄中是這樣的(注意看title):                  上部分頁欄可以用gridview來實現,不過為了省事在這就用textview代替了.  貼出程

Android Studio之初體驗 ---- 強大

一、介紹     很多android 開發者都感嘆做android開發竟然都沒有一款專門的軟體來使用,不像IOS有Xcode,WP有VS。一般做android開發都是eclipse或者ADT或者In