轉載請註明出處。java
在本人開發第一個安卓應用的時候就想到多屏滑動的界面(相似於微信5.0的滑動界面,已經流行了很長一段時間),鑑於知識有限,變依靠Tabhos實現了這種效果。思路是:監聽並計算滑動距離,切換Tabhost。你可能已經想到了,沒錯,效果特別差,Tabhost切換僅僅是刷了一下頁面而已,什麼也沒作。後來在網上搜到,導入(如今新建項目都是默認導入)android-support-v4.jar實現裏面的ViewPager就好了。android
在Activity裏面創建一個ViewPager,而後將咱們須要的視圖添加到裏面就好了。固然最好的方法是ViewPager+Fragment去實現。Fragment相似於Activity,有本身的生命週期。canvas
(想要具體瞭解就去谷歌查詢API文檔)微信
如下爲正文:佈局
項目文件:this
PagerScrollerActivity和TitleIndicator爲此項目的核心功能。spa
PagerScrollerActivity是就是一個繼承了FragmentActivity抽象的類,實現了項目具體功能(管理TitleIndicator).net
關鍵代碼:blog
private void initView() throws IndexOutOfBoundsException, NullPointerException { setTabsAndAdapter(); //抽象方法,用於實例化Fragment頁面以及標題欄 viewPager = (ViewPager) findViewById(R.id.vPager); // 設置viewpager內部頁面之間的間距 viewPager.setPageMargin(getResources().getDimensionPixelSize(R.dimen.fragment_viewpager_margin)); // 設置viewpager內部頁面間距的drawable viewPager.setPageMarginDrawable(color.myblue); viewPager.setAdapter(adapter); //必須讓viewPager設置此OnPageChangeListener的實現類,才能對滑動和頁面狀態監聽 viewPager.setOnPageChangeListener(this); title = (TitleIndicator) findViewById(R.id.title); title.init(tabs, viewPager); } }
PagerScrollerActivity實現 onPageScrolled(int position, float positionOffset, int positionOffsetPixels)用於監聽滾動過程,以實現標題欄的實時滾動。繼承
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
//title 爲 TitleIndicator的實例 title.onScroll((viewPager.getWidth() + viewPager.getPageMargin()) * position + positionOffsetPixels);
//讀者可在紙上畫出多個頁面的示意圖,本身進行計算便能得出這個結果(將座標想象成全部頁面以及變局的總和) }
TitleIndicator是標題欄,數據來自List<TabInfo> tabs,實現實時滾動遊標以及點擊子標題切換到頁面
先貼上TabInfo的關鍵代碼
public class TabInfo {
//用於獲取到子標題的佈局內容,須要的話能夠添加ImageView. public View getTab(LayoutInflater inflater, ViewGroup root) { tab = inflater.inflate(R.layout.tab_item, root, false); tv = (TextView) tab.findViewById(R.id.tab_name); tv.setText(name); tab.setId(id); return tab; } }
TitleIndicator的初始化操做
public void init(List<TabInfo> tabs, ViewPager viewPager) { this.viewPager = viewPager; setWillNotDraw(false);// 調用invalidate()時強制調用onDraw()方法
totalTabs = tabs.size(); // 設置標題的每個Tab的位置屬性 for (int i = 0; i < totalTabs; i++) { View view = tabs.get(i).getTab(inflater, this); LinearLayout.LayoutParams lP = (LinearLayout.LayoutParams) view.getLayoutParams(); lP.gravity = Gravity.CENTER_VERTICAL; view.setOnClickListener(this); addView(view); } setCurrentTab(currentTab); }
TitleIndicator的關鍵代碼,用於重繪遊標
protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); if (!initialize) { initTab(canvas); } float scroll_x = 0; if (totalTabs != 0) { // 計算滾動條實際滾動距離 scroll_x = (currentLocationlX - ((currentTab) * (mWidth + viewPager.getPageMargin()))) / totalTabs; } else { scroll_x = currentLocationlX; } cursorPath.rewind();// 清楚以前的路徑狀態 float left_x = currentTab * cursorWidth + scroll_x; float right_x = (currentTab + 1) * cursorWidth + scroll_x; float top_y = mHeight - cursorHeight - 2; float bottom_y = mHeight - 2; cursorPath.moveTo(left_x, top_y); // 移動到基點到左上角 cursorPath.lineTo(right_x, top_y); // 畫線:基點到右上角 cursorPath.lineTo(right_x, bottom_y);// 基點到右下角 cursorPath.lineTo(left_x, bottom_y);// 基點到左下角 cursorPath.close(); canvas.drawPath(cursorPath, paint); initialize = true; }
設置當前顯示的頁面
public void setCurrentTab(int i) { // 清除舊Tab的文字狀態 View view = getChildAt(currentTab); view.setSelected(false); currentTab = i; // 設置新Tab的文字狀態 view = getChildAt(currentTab); view.setSelected(true); invalidate(); if (viewPager.getCurrentItem() != i) viewPager.setCurrentItem(i); }
注:轉載請註明出處。
大神就不要看這麼渣的文章了,新手看看就還行。
本人在網上找了許多demo。後來發現幾乎都是同一個大神的文章(http://blog.csdn.net/singwhatiwanna/article/details/17201587),這位大神的demo功能實現很是完善,但本人徹底是安卓(java)新手,裏面核心代碼可以看懂,可是許多細節的不是很清楚。在讀懂這個demo的代碼後,本身嘗試着寫一個相似的demo(幾乎是同樣的,只是功能簡單些,對於我這種安卓新手來講比較容易讀懂的)。