天天看點

Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端

大家都知道Android的ActionBar是在3.0以上才有的,那麼在3.0以下呢,google并沒有給我提供在3.0以下支援ActionBar的包,但是外國的大牛JakeWharton實作了在3.0以下使用ActionBar, JakeWharton這位大牛是ActionBarSherlock,Android-ViewPagerIndicator ,NineOldAndroids的作者,非常厲害的一個人,Github的關注量超過2.6K,我左側的友情連結裡面有他的Github的首頁連結,有興趣的朋友可以去follow下他,今天我們使用的是他的開源架構ActionBarSherlock,ActionBarSherlock是讓Action Bar功能支援2.X後的所有平台,而且他會自動的判斷是調用原生Action Bar還是使用擴充ActionBar,很多知名的應用也使用這個庫,我之前對ActionBar也不了解,是以就去下了ActionBarSherlock來好好的了解了解ActionBar的使用

  • 我們先從Github上面先下載下傳這個庫,下載下傳位址​​https://github.com/JakeWharton/ActionBarSherlock​​,下載下傳好了解壓如圖
Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端

把紅色框框标記的檔案導入Eclipse裡面,我們可以先看下例子,來了解下ActionBar的一些使用情況

  • 我們建立一個Android工程,叫ViewPagerAndTab,然後指定ActionBarSherlock為ViewPagerAndTab的庫工程,右鍵工程--->Properties
Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端

通過上面的幾步我們就指定ActionBarSherlock為ViewPagerAndTab的庫工程,接下來我們就能在3.0以下使用ActionBar,我這裡使用的是ActionBar  Tab和ViewPager仿網易新聞,我們看看主要代碼的編寫

1.先看布局檔案,裡面一個ViewPager,非常簡單

[html] view plain copy

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:background="@android:color/white">  
  6.     <android.support.v4.view.ViewPager      
  7.         android:id="@+id/viewPager"      
  8.         android:layout_width="fill_parent"      
  9.         android:layout_height="wrap_content" />     
  10. </RelativeLayout>  

2.MainActivity代碼,點選ActionBar的Tab,ViewPager切換不同的Fragment,滑動ViewPager,選中相對應的ActiionBar Tab

[java] view plain copy

  1. package com.example.viewpagerandtabdemo;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import android.os.Bundle;  
  5. import android.support.v4.app.Fragment;  
  6. import android.support.v4.app.FragmentTransaction;  
  7. import android.support.v4.view.ViewPager;  
  8. import android.support.v4.view.ViewPager.OnPageChangeListener;  
  9. import com.actionbarsherlock.app.ActionBar;  
  10. import com.actionbarsherlock.app.ActionBar.Tab;  
  11. import com.actionbarsherlock.app.SherlockFragmentActivity;  
  12. public class MainActivity extends SherlockFragmentActivity implements ActionBar.TabListener, OnPageChangeListener{  
  13.     /** 
  14.      * 頂部Tab的title 
  15.      */  
  16.     private String [] mTabTitles;  
  17.      * ViewPager對象的引用 
  18.     private ViewPager mViewPager;  
  19.      * 裝載Fragment的容器,我們的每一個界面都是一個Fragment 
  20.     private List<Fragment> mFragmentList;  
  21.      * ActionBar對象的引用 
  22.     private ActionBar mActionBar;  
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_main);  
  27.         //從資源檔案在擷取Tab的title  
  28.         mTabTitles = getResources().getStringArray(R.array.tab_title);  
  29.         mFragmentList =  new ArrayList<Fragment>();  
  30.         mViewPager = (ViewPager) findViewById(R.id.viewPager);  
  31.         //設定Adapter  
  32.         mViewPager.setAdapter(new TabPagerAdapter(getSupportFragmentManager(), mFragmentList));  
  33.         //設定監聽  
  34.         mViewPager.setOnPageChangeListener(this);  
  35.         //擷取Action執行個體我們使用getSupportActionBar()方法  
  36.         mActionBar = getSupportActionBar();  
  37.         //隐藏Title  
  38.         mActionBar.setDisplayShowTitleEnabled(false);  
  39.         //隐藏Home logo  
  40.         mActionBar.setDisplayShowHomeEnabled(false);  
  41.         //設定ActionBar的導航模式為Tab  
  42.         mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
  43.         //為ActionBar添加Tab并設定TabListener  
  44.         for(int i=0; i<mTabTitles.length; i++){  
  45.              ActionBar.Tab tab = mActionBar.newTab();  
  46.              tab.setText(mTabTitles[i]);  
  47.              tab.setTabListener(this);  
  48.              mActionBar.addTab(tab, i);  
  49.         }  
  50.         //将Fragment加入到List中,并将Tab的title傳遞給Fragment  
  51.             Fragment fragment = new ItemFragment();  
  52.             Bundle args = new Bundle();  
  53.             args.putString("arg", mTabTitles[i]);  
  54.             fragment.setArguments(args);  
  55.             mFragmentList.add(fragment);  
  56.     }  
  57.     public void onTabSelected(Tab tab, FragmentTransaction ft) {  
  58.         //點選ActionBar Tab的時候切換不同的Fragment界面  
  59.         mViewPager.setCurrentItem(tab.getPosition());  
  60.     public void onTabUnselected(Tab tab, FragmentTransaction ft) {  
  61.     public void onTabReselected(Tab tab, FragmentTransaction ft) {  
  62.     public void onPageScrollStateChanged(int arg0) {  
  63.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
  64.     public void onPageSelected(int arg0) {  
  65.         //滑動ViewPager的時候設定相對應的ActionBar Tab被選中  
  66.         mActionBar.setSelectedNavigationItem(arg0);  
  67. }  

我們使用ActionBarSherlock的時候不再是繼承Activity,而是繼承SherlockActivity,SherlockDialogFragment,SherlockFragmentActivity等等,我這裡用到Fragment,是以繼承SherlockFragmentActivity,我們不能随便設定Activity的theme,以後我們要全屏顯示的時候直接設定android:theme="@android:style/Theme.Black.NoTitleBar"

,我們使用ActionBar就不能這樣設定了,并且不能随便設定他的Theme,必須是Theme.Sherlock, Theme.Sherlock.Light, Theme.Sherlock.Light.DarkActionBar,或者是他們的子樣式,不然就會出java.lang.IllegalStateException異常,是以為了自定義ActionBar的Tab,我們必須修改其style

注意:我們還必須删除ViewPagerAndTab工程libs下面的android-support-v4.jar包,因為在ActionBarSherlock已經包含android-support-v4.jar

3.ViewPager的擴充卡TabPagerAdapter,因為我們用到Fragment,是以我們繼承FragmentStatePagerAdapter而不是PagerAdapter

  1. import android.support.v4.app.FragmentManager;  
  2. import android.support.v4.app.FragmentStatePagerAdapter;  
  3. public class TabPagerAdapter extends FragmentStatePagerAdapter {  
  4.     private List<Fragment> list;  
  5.     //構造函數  
  6.     public TabPagerAdapter(FragmentManager fm, List<Fragment> list) {  
  7.         super(fm);  
  8.         this.list = list;  
  9.     public Fragment getItem(int arg0) {  
  10.         return list.get(arg0);  
  11.     public int getCount() {  
  12.         return list.size();  

4.ItemFragment 繼承SherlockFragment,也可以直接繼承Fragment,裡面的的布局比較簡單,一個TextView用來顯示從Activity傳遞過來的ActionBar Tab的title

  1. import android.view.LayoutInflater;  
  2. import android.view.View;  
  3. import android.view.ViewGroup;  
  4. import android.widget.TextView;  
  5. import com.actionbarsherlock.app.SherlockFragment;  
  6. public class ItemFragment extends SherlockFragment {  
  7.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
  8.             Bundle savedInstanceState) {  
  9.         View contextView = inflater.inflate(R.layout.fragment_item, container, false);  
  10.         TextView mTextView = (TextView) contextView.findViewById(R.id.textview);  
  11.         //擷取Activity傳遞過來的參數  
  12.         Bundle mBundle = getArguments();  
  13.         String title = mBundle.getString("arg");  
  14.         mTextView.setText(title);  
  15.         return contextView;  
  16.     public void onActivityCreated(Bundle savedInstanceState) {  
  17.         super.onActivityCreated(savedInstanceState);  

然後我們将上面的Activity的theme設定成android:theme="@style/Theme.Sherlock.Light.DarkActionBar" 運作項目看看效果,下圖一是項目的效果,圖二是網易的效果

Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端
Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端

是不是相差很大呢?人家下面的訓示條是紅色的,我們做出來的是藍色的,人家選中Tab的字型顔色是紅色,我們的不變色等等,那麼我們要怎麼才能做出網易新聞的那樣子的效果,我們需要改變其style,改變如下

  1. <style name="Themes.ActionBarTab" parent="@style/Theme.Sherlock">  
  2.     <!-- 去除ActionBar的Divider -->  
  3.     <item name="actionBarDivider">@null</item>  
  4.     <!-- 設定ActionBar Tab的高度 -->  
  5.     <item name="actionBarSize">45dip</item>  
  6.     <!-- 設定ActionBar Tab字型的樣式 -->  
  7.     <item name="actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
  8.     <!-- 設定ActionBar Tab的樣式,例如下面的紅色指引,Tab之間的間隙等等 -->  
  9.     <item name="actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
  10.     <!-- 設定ActionBar的樣式,這裡簡單的設定了ActionBar的背景 -->  
  11.     <item name="actionBarStyle">@style/Widget.Slider.ActionBar</item>  
  12. </style>  
  13.  <style name="Widget.Slider.ActionBar" parent="@style/Widget.Sherlock.ActionBar">    
  14.     <item name="backgroundStacked">@drawable/base_action_bar_bg</item>  
  15. <style name="Widget.Sherlock.ActionBar.TabText" parent="android:Widget.Holo.ActionBar.TabText">  
  16.     <item name="android:textColor">@drawable/selector_tabtext</item>  
  17.     <item name="android:textSize">15sp</item>  
  18. <style name="Widget.Sherlock.ActionBar.TabView" parent="Widget">  
  19.     <item name="android:background">@drawable/tab_indicator</item>  
  20.     <item name="android:paddingLeft">8dip</item>  
  21.     <item name="android:paddingRight">8dip</item>  
  22. </style>   

還有一些圖檔,selector我沒有貼出來,可以去下載下傳代碼看看效果,改變style運作效果

Android 開源架構ActionBarSherlock 和 ViewPager 仿網易新聞用戶端

好了,今天的講解到此結束,有疑問的朋友請在下面留言,有興趣的可以看看 開源架構ViewPageIndicator 和 ViewPager 仿網易新聞用戶端Tab标簽

 源碼下載下傳,請點選

很多朋友說自己在4.1上面怎麼設定style沒效果,首先這個庫是在2.X的機器上面使用ActionBar,3.0以後就是使用Andriod自帶的ActionBar,是以在3.0以上的系統使用的style為android自帶的style,是以我們要将style檔案做下修改,如下

  1.   <style name="Themes.ActionBarTab" parent="@style/Theme.Sherlock">  
  2.       <!-- 去除ActionBar的Divider -->  
  3.       <item name="actionBarDivider">@null</item>  
  4. <item name="android:actionBarDivider">@null</item>  
  5.       <!-- 設定ActionBar Tab的高度 -->  
  6.       <item name="actionBarSize">45dip</item>  
  7. <item name="android:actionBarSize">45dip</item>  
  8.       <!-- 設定ActionBar Tab字型的樣式 -->  
  9.       <item name="actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
  10. <item name="android:actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
  11.       <!-- 設定ActionBar Tab的樣式,例如下面的紅色指引,Tab之間的間隙等等 -->  
  12.       <item name="actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
  13. <item name="android:actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
  14.       <!-- 設定ActionBar的樣式,這裡簡單的設定了ActionBar的背景 -->  
  15.       <item name="actionBarStyle">@style/Widget.Slider.ActionBar</item>  
  16. <item name="android:actionBarStyle">@style/Widget.Slider.ActionBar</item>  
  17.   </style>  
  18.    <style name="Widget.Slider.ActionBar" parent="@style/Widget.Sherlock.ActionBar">    
  19.       <item name="backgroundStacked">@drawable/base_action_bar_bg</item>  
  20. <item name="android:backgroundStacked">@drawable/base_action_bar_bg</item>  
  21.   <style name="Widget.Sherlock.ActionBar.TabText" parent="android:Widget.Holo.ActionBar.TabText">  
  22.       <item name="android:textColor">@drawable/selector_tabtext</item>  
  23.       <item name="android:textSize">15sp</item>  
  24.   <style name="Widget.Sherlock.ActionBar.TabView" parent="Widget">  
  25.       <item name="android:background">@drawable/tab_indicator</item>  
  26.       <item name="android:paddingLeft">8dip</item>  
  27.       <item name="android:paddingRight">8dip</item>  
  28.   </style>