• Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端


    Android 开源框架ActionBarSherlock 和 ViewPager 仿网易新闻客户端 - Mobile Internet developer - 博客频道 - CSDN.NET

    大家都知道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的使用

    把红色框框标记的文件导入Eclipse里面,我们可以先看下例子,来了解下ActionBar的一些使用情况

    • 我们新建一个Android工程,叫ViewPagerAndTab,然后指定ActionBarSherlock为ViewPagerAndTab的库工程,右键工程--->Properties

    通过上面的几步我们就指定ActionBarSherlock为ViewPagerAndTab的库工程,接下来我们就能在3.0以下使用ActionBar,我这里使用的是ActionBar  Tab和ViewPager仿网易新闻,我们看看主要代码的编写

    1.先看布局文件,里面一个ViewPager,非常简单

    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.       
    7.     <android.support.v4.view.ViewPager      
    8.         android:id="@+id/viewPager"      
    9.         android:layout_width="fill_parent"      
    10.         android:layout_height="wrap_content" />     
    11.   
    12. </RelativeLayout>  
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white">
    
        <android.support.v4.view.ViewPager
            android:id="@+id/viewPager"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content" />   
    
    </RelativeLayout>

    2.MainActivity代码,点击ActionBar的Tab,ViewPager切换不同的Fragment,滑动ViewPager,选中相对应的ActiionBar Tab

    1. package com.example.viewpagerandtabdemo;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.List;  
    5.   
    6. import android.os.Bundle;  
    7. import android.support.v4.app.Fragment;  
    8. import android.support.v4.app.FragmentTransaction;  
    9. import android.support.v4.view.ViewPager;  
    10. import android.support.v4.view.ViewPager.OnPageChangeListener;  
    11.   
    12. import com.actionbarsherlock.app.ActionBar;  
    13. import com.actionbarsherlock.app.ActionBar.Tab;  
    14. import com.actionbarsherlock.app.SherlockFragmentActivity;  
    15.   
    16. public class MainActivity extends SherlockFragmentActivity implements ActionBar.TabListener, OnPageChangeListener{  
    17.     /** 
    18.      * 顶部Tab的title 
    19.      */  
    20.     private String [] mTabTitles;  
    21.       
    22.     /** 
    23.      * ViewPager对象的引用 
    24.      */  
    25.     private ViewPager mViewPager;  
    26.       
    27.     /** 
    28.      * 装载Fragment的容器,我们的每一个界面都是一个Fragment 
    29.      */  
    30.     private List<Fragment> mFragmentList;  
    31.       
    32.     /** 
    33.      * ActionBar对象的引用 
    34.      */  
    35.     private ActionBar mActionBar;  
    36.   
    37.     @Override  
    38.     protected void onCreate(Bundle savedInstanceState) {  
    39.         super.onCreate(savedInstanceState);  
    40.         setContentView(R.layout.activity_main);  
    41.           
    42.         //从资源文件在获取Tab的title  
    43.         mTabTitles = getResources().getStringArray(R.array.tab_title);  
    44.         mFragmentList =  new ArrayList<Fragment>();  
    45.           
    46.         mViewPager = (ViewPager) findViewById(R.id.viewPager);  
    47.         //设置Adapter  
    48.         mViewPager.setAdapter(new TabPagerAdapter(getSupportFragmentManager(), mFragmentList));  
    49.         //设置监听  
    50.         mViewPager.setOnPageChangeListener(this);  
    51.           
    52.           
    53.         //获取Action实例我们使用getSupportActionBar()方法  
    54.         mActionBar = getSupportActionBar();  
    55.           
    56.         //隐藏Title  
    57.         mActionBar.setDisplayShowTitleEnabled(false);  
    58.         //隐藏Home logo  
    59.         mActionBar.setDisplayShowHomeEnabled(false);  
    60.         //设置ActionBar的导航模式为Tab  
    61.         mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);  
    62.           
    63.           
    64.         //为ActionBar添加Tab并设置TabListener  
    65.         for(int i=0; i<mTabTitles.length; i++){  
    66.              ActionBar.Tab tab = mActionBar.newTab();  
    67.              tab.setText(mTabTitles[i]);  
    68.              tab.setTabListener(this);  
    69.              mActionBar.addTab(tab, i);  
    70.         }  
    71.           
    72.           
    73.         //将Fragment加入到List中,并将Tab的title传递给Fragment  
    74.         for(int i=0; i<mTabTitles.length; i++){  
    75.             Fragment fragment = new ItemFragment();  
    76.             Bundle args = new Bundle();  
    77.             args.putString("arg", mTabTitles[i]);  
    78.             fragment.setArguments(args);  
    79.               
    80.             mFragmentList.add(fragment);  
    81.         }  
    82.           
    83.     }  
    84.       
    85.       
    86.   
    87.     @Override  
    88.     public void onTabSelected(Tab tab, FragmentTransaction ft) {  
    89.         //点击ActionBar Tab的时候切换不同的Fragment界面  
    90.         mViewPager.setCurrentItem(tab.getPosition());  
    91.     }  
    92.   
    93.     @Override  
    94.     public void onTabUnselected(Tab tab, FragmentTransaction ft) {  
    95.   
    96.     }  
    97.   
    98.     @Override  
    99.     public void onTabReselected(Tab tab, FragmentTransaction ft) {  
    100.           
    101.     }  
    102.       
    103.       
    104.     @Override  
    105.     public void onPageScrollStateChanged(int arg0) {  
    106.           
    107.     }  
    108.   
    109.     @Override  
    110.     public void onPageScrolled(int arg0, float arg1, int arg2) {  
    111.           
    112.     }  
    113.   
    114.     @Override  
    115.     public void onPageSelected(int arg0) {  
    116.         //滑动ViewPager的时候设置相对应的ActionBar Tab被选中  
    117.         mActionBar.setSelectedNavigationItem(arg0);  
    118.     }  
    119.   
    120.   
    121. }  
    package com.example.viewpagerandtabdemo;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentTransaction;
    import android.support.v4.view.ViewPager;
    import android.support.v4.view.ViewPager.OnPageChangeListener;
    
    import com.actionbarsherlock.app.ActionBar;
    import com.actionbarsherlock.app.ActionBar.Tab;
    import com.actionbarsherlock.app.SherlockFragmentActivity;
    
    public class MainActivity extends SherlockFragmentActivity implements ActionBar.TabListener, OnPageChangeListener{
    	/**
    	 * 顶部Tab的title
    	 */
    	private String [] mTabTitles;
    
    	/**
    	 * ViewPager对象的引用
    	 */
    	private ViewPager mViewPager;
    
    	/**
    	 * 装载Fragment的容器,我们的每一个界面都是一个Fragment
    	 */
    	private List<Fragment> mFragmentList;
    
    	/**
    	 * ActionBar对象的引用
    	 */
    	private ActionBar mActionBar;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_main);
    
    		//从资源文件在获取Tab的title
    		mTabTitles = getResources().getStringArray(R.array.tab_title);
    		mFragmentList =  new ArrayList<Fragment>();
    
    		mViewPager = (ViewPager) findViewById(R.id.viewPager);
    		//设置Adapter
    		mViewPager.setAdapter(new TabPagerAdapter(getSupportFragmentManager(), mFragmentList));
    		//设置监听
    		mViewPager.setOnPageChangeListener(this);
    
    		//获取Action实例我们使用getSupportActionBar()方法
    		mActionBar = getSupportActionBar();
    
    		//隐藏Title
    		mActionBar.setDisplayShowTitleEnabled(false);
    		//隐藏Home logo
    		mActionBar.setDisplayShowHomeEnabled(false);
    		//设置ActionBar的导航模式为Tab
    		mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
    
    		//为ActionBar添加Tab并设置TabListener
    		for(int i=0; i<mTabTitles.length; i++){
    			 ActionBar.Tab tab = mActionBar.newTab();
    			 tab.setText(mTabTitles[i]);
    			 tab.setTabListener(this);
    			 mActionBar.addTab(tab, i);
    		}
    
    		//将Fragment加入到List中,并将Tab的title传递给Fragment
    		for(int i=0; i<mTabTitles.length; i++){
    			Fragment fragment = new ItemFragment();
    			Bundle args = new Bundle();
    			args.putString("arg", mTabTitles[i]);
    			fragment.setArguments(args);
    
    			mFragmentList.add(fragment);
    		}
    
    	}
    
    	@Override
    	public void onTabSelected(Tab tab, FragmentTransaction ft) {
    		//点击ActionBar Tab的时候切换不同的Fragment界面
    		mViewPager.setCurrentItem(tab.getPosition());
    	}
    
    	@Override
    	public void onTabUnselected(Tab tab, FragmentTransaction ft) {
    
    	}
    
    	@Override
    	public void onTabReselected(Tab tab, FragmentTransaction ft) {
    
    	}
    
    	@Override
    	public void onPageScrollStateChanged(int arg0) {
    
    	}
    
    	@Override
    	public void onPageScrolled(int arg0, float arg1, int arg2) {
    
    	}
    
    	@Override
    	public void onPageSelected(int arg0) {
    		//滑动ViewPager的时候设置相对应的ActionBar Tab被选中
    		mActionBar.setSelectedNavigationItem(arg0);
    	}
    
    }
    

    我们使用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. package com.example.viewpagerandtabdemo;  
    2.   
    3. import java.util.List;  
    4.   
    5. import android.support.v4.app.Fragment;  
    6. import android.support.v4.app.FragmentManager;  
    7. import android.support.v4.app.FragmentStatePagerAdapter;  
    8.   
    9. public class TabPagerAdapter extends FragmentStatePagerAdapter {  
    10.     private List<Fragment> list;  
    11.       
    12.     //构造函数  
    13.     public TabPagerAdapter(FragmentManager fm, List<Fragment> list) {  
    14.         super(fm);  
    15.         this.list = list;  
    16.     }  
    17.   
    18.     @Override  
    19.     public Fragment getItem(int arg0) {  
    20.         return list.get(arg0);  
    21.     }  
    22.   
    23.     @Override  
    24.     public int getCount() {  
    25.         return list.size();  
    26.     }  
    27.   
    28. }  
    package com.example.viewpagerandtabdemo;
    
    import java.util.List;
    
    import android.support.v4.app.Fragment;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.FragmentStatePagerAdapter;
    
    public class TabPagerAdapter extends FragmentStatePagerAdapter {
    	private List<Fragment> list;
    
    	//构造函数
    	public TabPagerAdapter(FragmentManager fm, List<Fragment> list) {
    		super(fm);
    		this.list = list;
    	}
    
    	@Override
    	public Fragment getItem(int arg0) {
    		return list.get(arg0);
    	}
    
    	@Override
    	public int getCount() {
    		return list.size();
    	}
    
    }

    4.ItemFragment 继承SherlockFragment,也可以直接继承Fragment,里面的的布局比较简单,一个TextView用来显示从Activity传递过来的ActionBar Tab的title

    1. package com.example.viewpagerandtabdemo;  
    2.   
    3. import android.os.Bundle;  
    4. import android.view.LayoutInflater;  
    5. import android.view.View;  
    6. import android.view.ViewGroup;  
    7. import android.widget.TextView;  
    8.   
    9. import com.actionbarsherlock.app.SherlockFragment;  
    10.   
    11.   
    12. public class ItemFragment extends SherlockFragment {  
    13.   
    14.     @Override  
    15.     public View onCreateView(LayoutInflater inflater, ViewGroup container,  
    16.             Bundle savedInstanceState) {  
    17.           
    18.         View contextView = inflater.inflate(R.layout.fragment_item, container, false);  
    19.         TextView mTextView = (TextView) contextView.findViewById(R.id.textview);  
    20.           
    21.         //获取Activity传递过来的参数  
    22.         Bundle mBundle = getArguments();  
    23.         String title = mBundle.getString("arg");  
    24.           
    25.         mTextView.setText(title);  
    26.           
    27.         return contextView;  
    28.     }  
    29.   
    30.     @Override  
    31.     public void onActivityCreated(Bundle savedInstanceState) {  
    32.         super.onActivityCreated(savedInstanceState);  
    33.     }  
    34.   
    35. }  
    package com.example.viewpagerandtabdemo;
    
    import android.os.Bundle;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import com.actionbarsherlock.app.SherlockFragment;
    
    public class ItemFragment extends SherlockFragment {
    
    	@Override
    	public View onCreateView(LayoutInflater inflater, ViewGroup container,
    			Bundle savedInstanceState) {
    
    		View contextView = inflater.inflate(R.layout.fragment_item, container, false);
    		TextView mTextView = (TextView) contextView.findViewById(R.id.textview);
    
    		//获取Activity传递过来的参数
    		Bundle mBundle = getArguments();
    		String title = mBundle.getString("arg");
    
    		mTextView.setText(title);
    
    		return contextView;
    	}
    
    	@Override
    	public void onActivityCreated(Bundle savedInstanceState) {
    		super.onActivityCreated(savedInstanceState);
    	}
    
    }

    然后我们将上面的Activity的theme设置成android:theme="@style/Theme.Sherlock.Light.DarkActionBar" 运行项目看看效果,下图一是项目的效果,图二是网易的效果

    是不是相差很大呢?人家下面的指示条是红色的,我们做出来的是蓝色的,人家选中Tab的字体颜色是红色,我们的不变色等等,那么我们要怎么才能做出网易新闻的那样子的效果,我们需要改变其style,改变如下

    1. <style name="Themes.ActionBarTab" parent="@style/Theme.Sherlock">  
    2.     <!-- 去除ActionBar的Divider -->  
    3.     <item name="actionBarDivider">@null</item>  
    4.       
    5.     <!-- 设置ActionBar Tab的高度 -->  
    6.     <item name="actionBarSize">45dip</item>  
    7.       
    8.     <!-- 设置ActionBar Tab字体的样式 -->  
    9.     <item name="actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
    10.       
    11.     <!-- 设置ActionBar Tab的样式,例如下面的红色指引,Tab之间的间隙等等 -->  
    12.     <item name="actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
    13.       
    14.     <!-- 设置ActionBar的样式,这里简单的设置了ActionBar的背景 -->  
    15.     <item name="actionBarStyle">@style/Widget.Slider.ActionBar</item>  
    16. </style>  
    17.   
    18.   
    19.  <style name="Widget.Slider.ActionBar" parent="@style/Widget.Sherlock.ActionBar">    
    20.     <item name="backgroundStacked">@drawable/base_action_bar_bg</item>  
    21. </style>  
    22.   
    23. <style name="Widget.Sherlock.ActionBar.TabText" parent="android:Widget.Holo.ActionBar.TabText">  
    24.     <item name="android:textColor">@drawable/selector_tabtext</item>  
    25.     <item name="android:textSize">15sp</item>  
    26. </style>  
    27.   
    28. <style name="Widget.Sherlock.ActionBar.TabView" parent="Widget">  
    29.     <item name="android:background">@drawable/tab_indicator</item>  
    30.     <item name="android:paddingLeft">8dip</item>  
    31.     <item name="android:paddingRight">8dip</item>  
    32. </style>   
        <style name="Themes.ActionBarTab" parent="@style/Theme.Sherlock">
            <!-- 去除ActionBar的Divider -->
            <item name="actionBarDivider">@null</item>
    
            <!-- 设置ActionBar Tab的高度 -->
            <item name="actionBarSize">45dip</item>
    
            <!-- 设置ActionBar Tab字体的样式 -->
            <item name="actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>
    
            <!-- 设置ActionBar Tab的样式,例如下面的红色指引,Tab之间的间隙等等 -->
            <item name="actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>
    
            <!-- 设置ActionBar的样式,这里简单的设置了ActionBar的背景 -->
            <item name="actionBarStyle">@style/Widget.Slider.ActionBar</item>
        </style>
    
         <style name="Widget.Slider.ActionBar" parent="@style/Widget.Sherlock.ActionBar">
            <item name="backgroundStacked">@drawable/base_action_bar_bg</item>
        </style>
    
        <style name="Widget.Sherlock.ActionBar.TabText" parent="android:Widget.Holo.ActionBar.TabText">
            <item name="android:textColor">@drawable/selector_tabtext</item>
            <item name="android:textSize">15sp</item>
        </style>
    
        <style name="Widget.Sherlock.ActionBar.TabView" parent="Widget">
            <item name="android:background">@drawable/tab_indicator</item>
            <item name="android:paddingLeft">8dip</item>
            <item name="android:paddingRight">8dip</item>
        </style> 

    还有一些图片,selector我没有贴出来,可以去下载代码看看效果,改变style运行效果

     

    好了,今天的讲解到此结束,有疑问的朋友请在下面留言,有兴趣的可以看看 开源框架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.         
    6.       <!-- 设置ActionBar Tab的高度 -->  
    7.       <item name="actionBarSize">45dip</item>  
    8. <item name="android:actionBarSize">45dip</item>  
    9.         
    10.       <!-- 设置ActionBar Tab字体的样式 -->  
    11.       <item name="actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
    12. <item name="android:actionBarTabTextStyle">@style/Widget.Sherlock.ActionBar.TabText</item>  
    13.         
    14.       <!-- 设置ActionBar Tab的样式,例如下面的红色指引,Tab之间的间隙等等 -->  
    15.       <item name="actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
    16. <item name="android:actionBarTabStyle">@style/Widget.Sherlock.ActionBar.TabView</item>  
    17.         
    18.       <!-- 设置ActionBar的样式,这里简单的设置了ActionBar的背景 -->  
    19.       <item name="actionBarStyle">@style/Widget.Slider.ActionBar</item>  
    20. <item name="android:actionBarStyle">@style/Widget.Slider.ActionBar</item>  
    21.   </style>  
    22.     
    23.     
    24.    <style name="Widget.Slider.ActionBar" parent="@style/Widget.Sherlock.ActionBar">    
    25.       <item name="backgroundStacked">@drawable/base_action_bar_bg</item>  
    26. <item name="android:backgroundStacked">@drawable/base_action_bar_bg</item>  
    27.   </style>  
    28.   
    29.   <style name="Widget.Sherlock.ActionBar.TabText" parent="android:Widget.Holo.ActionBar.TabText">  
    30.       <item name="android:textColor">@drawable/selector_tabtext</item>  
    31.       <item name="android:textSize">15sp</item>  
    32.   </style>  
    33.   
    34.   <style name="Widget.Sherlock.ActionBar.TabView" parent="Widget">  
    35.       <item name="android:background">@drawable/tab_indicator</item>  
    36.       <item name="android:paddingLeft">8dip</item>  
    37.       <item name="android:paddingRight">8dip</item>  
    38.   </style>   
  • 相关阅读:
    kubernetes故障收集
    Redis三种集群模式介绍
    php opcache是什么
    php ob_clean()函数详解
    Java8 Stream 关于分组、聚合等常用的操作测试
    动画折叠和展开不固定高度的元素
    VirtualBox桥接网卡无法访问百度等网站
    centos7查看磁盘空间
    git pull时奇怪的需要密码
    nginx.service注册系统服务
  • 原文地址:https://www.cnblogs.com/seven1979/p/4274835.html
Copyright © 2020-2023  润新知