使用ViewPager+Fragment來實現帶滾動條的多屏滑動-IndicatorFragmentActivity
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow
也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!
轉載請註明出處:http://blog.csdn.net/singwhatiwanna/article/details/17201587介紹
在android應用中,多屏滑動是一種很常見的風格,博主之前也寫過一些多屏滑動的demo,比如滾動banner(http://blog.csdn.net/singwhatiwanna/article/details/8875241)和仿tabhost的控制元件。這次給大家介紹一種效果更好的風格:帶滾動條的多屏滑動,類似於google play裡面的風格。如果你看過我之前寫的banner,你就會發現那個banner是原生的,沒有采用viewpager啥的,所以程式碼很長,如果採用ViewPager,程式碼就會短很多,但是使用ViewPager也有弊端:需要匯入android-support-v4.jar、細節無法控制。不過現在情況已經不一樣了,android-support-v4中提供了很多實用的功能,以至於現在新建一個android工程預設都會匯入這個jar包。那我們就也採用viewpager來做滑動吧。另外一個概念就是Fragment和FragmentActivity,Fragment是一個特殊的類,有著和activity一致的生命週期和view一致的介面,也就是Fragment就等於具有生命週期的View,但是,要注意的是:Fragment並不是View,它和View沒有繼承關係。使用Fragment的好處是:Fragment可以重用,而且每個Fragment可以在內部處理自己的業務就像activity一樣,這樣模組間耦合較低,比把所有的業務都寫在一個activity內部邏輯要清晰很多。還有就是,由於每個模組的業務都在Fragment內部來實現,這樣activity只要管理好幾個Fragment就行了,不需要做和業務相關的事情,最後,Fragment可以用來做不同解析度機型的適配。Fragment在sdk(android 3.0及更高)和android-support-v4裡面都有,但是由於相容性的問題,我們只能使用android-support-v4裡面的Fragment,除非你想你的apk只跑在3.0以後的android手機上,FragmentActivity的情況和Fragment類似。關於Fragment和FragmentActivity,其實有一些基本的用法需要了解一下,但是考慮到Fragment不是本文的重點,所以這裡就不介紹了,另外,本文只用Fragment做了一個簡單的介面,大家應該一看就懂,好了,言歸正傳。
IndicatorFragmentActivity的實現過程
1 新建一個工程,目錄結構如下:
2 實現ui包下的三個檔案
ViewPagerCompat.java:這是一個ViewPager的加強類,主要是為了解決滑動衝突的問題。不然的話,在ViewPager內部加入ListView等可滑動控制元件,兩者之間會產生干擾。
在這裡想多說一下,關於此類問題,解決辦法是:重寫父控制元件的onInterceptTouchEvent函式,在move的時候根據需要返回true,比如左右滑動返回true,其他情況均返回false。這樣,當左右滑動的時候,由於onInterceptTouchEvent返回了true,父控制元件就能處理,其他情況,事件將傳遞到listview中,listview自身可以處理上下滑動。
public class ViewPagerCompat extends ViewPager { //mViewTouchMode表示ViewPager是否全權控制滑動事件,預設為false,即不控制 private boolean mViewTouchMode = false; public ViewPagerCompat(Context context, AttributeSet attrs) { super(context, attrs); } public void setViewTouchMode(boolean b) { if (b && !isFakeDragging()) { //全權控制滑動事件 beginFakeDrag(); } else if (!b && isFakeDragging()) { //終止控制滑動事件 endFakeDrag(); } mViewTouchMode = b; } /** * 在mViewTouchMode為true的時候,ViewPager不攔截點選事件,點選事件將由子View處理 */ @Override public boolean onInterceptTouchEvent(MotionEvent event) { if (mViewTouchMode) { return false; } return super.onInterceptTouchEvent(event); } @Override public boolean onTouchEvent(MotionEvent ev) { try { return super.onTouchEvent(ev); } catch (Exception e) { return false; } } /** * 在mViewTouchMode為true或者滑動方向不是左右的時候,ViewPager將放棄控制點選事件, * 這樣做有利於在ViewPager中加入ListView等可以滑動的控制元件,否則兩者之間的滑動將會有衝突 */ @Override public boolean arrowScroll(int direction) { if (mViewTouchMode) return false; if (direction != FOCUS_LEFT && direction != FOCUS_RIGHT) return false; return super.arrowScroll(direction); }}
下面兩個檔案程式碼有點多,沒有粘出來,後面附有下載地址,大家可以下載下來看看,程式碼都做了註釋的。有什麼疑問歡迎交流。
TitleIndicator.java:這個一個帶滾動條的選項卡,會隨著viewpager的滑動而滑動,其實現思想是這樣的:每個選項卡是一個view,根據需要可以add多個view也就是多個選項卡進來,選項卡下部還有一個滾動條,滾動條是用canvas畫出來的。所有的invalidate方法均會觸發onDraw,當頁面滾動的時候,會有一個滾動距離,然後onDraw被觸發後,就會在新位置重新畫上滾動條(其實就是畫線)。
IndicatorFragmentActivity.java:這是IndicatorFragmentActivity的主介面,用於管理上述兩個view,對子類提供protected abstract int supplyTabs(List<TabInfo> tabs)介面來生成頁面。
下面主要介紹下如何使用這個IndicatorFragmentActivity。
如何使用?
請按如下步驟:
1 新建一個類繼承IndicatorFragmentActivity,然後實現supplyTabs抽象方法,提供生成選項卡所需的資料
public class MainActivity extends IndicatorFragmentActivity { public static final int FRAGMENT_ONE = 0; public static final int FRAGMENT_TWO = 1; public static final int FRAGMENT_THREE = 2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } //在這裡提供資料來進行初始化 @Override protected int supplyTabs(List<TabInfo> tabs) { tabs.add(new TabInfo(FRAGMENT_ONE, getString(R.string.fragment_one), FragmentOne.class)); tabs.add(new TabInfo(FRAGMENT_TWO, getString(R.string.fragment_two), FragmentTwo.class)); tabs.add(new TabInfo(FRAGMENT_THREE, getString(R.string.fragment_three), FragmentThree.class)); //返回的下標表示介面初始化的時候所指向的fragment的序號 return FRAGMENT_TWO; }}
2 為每個選項卡提供fragment類
最簡單的fragment,啥都不做,就載入一個layout然後初始化一個listview。其實我的demo裡有3個介面一樣的fragment,但是博主為了偷懶,直接寫了一個BaseFragment,讓它們3個都繼承這個BaseFragment,反正介面都一樣嘛。
public class BaseFragment extends Fragment { protected View mMainView; protected static ArrayList<Map<String, Object>> mlistItems; protected Context mContext; static { mlistItems = new ArrayList<Map<String, Object>>(); for (int i = 0; i < 20; i++) { Map<String, Object> map = new HashMap<String, Object>(); map.put("name", "name#" + i); map.put("sex", i % 2 == 0 ? "male" : "female"); mlistItems.add(map); } } public BaseFragment() { super(); } @Override public void onAttach(Activity activity) { super.onAttach(activity); mContext = activity.getApplicationContext(); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { mMainView = inflater.inflate(R.layout.fragment_one, container, false); ListView listView = (ListView) mMainView.findViewById(R.id.list); SimpleAdapter adapter = new SimpleAdapter(mContext, mlistItems, R.layout.listview_item, new String[] { "name", "sex" }, new int[] { R.id.name, R.id.download }); listView.setAdapter(adapter); return mMainView; }}
這樣就ok了,是不是挺簡單的,也就是說,如果你想要這種效果的話,只要匯入ui包裡面的3個類,然後再按上述2個步驟去做就行了,效果也是很好的。另外就是選項卡的顏色以及滾動條的顏色都是可以調的,而且每個選項卡上面是支援顯示其他標識的,比如一個小紅點啥的,就類似於那種有新訊息的狀態。有什麼問題,歡迎大家在下面留言和我交流。
程式碼下載:http://download.csdn.net/detail/singwhatiwanna/6680173