Android学习

来源:互联网 发布:mac怎么关闭应用程序 编辑:程序博客网 时间:2024/04/30 15:46

【FastDev4Android框架开发】Android Design支持库TabLayout打造仿网易新闻Tab标签效果(三十七) 

标签: 网易tablayoutsupportviewpagerfragment
 220人阅读 评论(0) 收藏 举报
 分类:

目录(?)[+]

转载请标明出处:

http://blog.csdn.net/developer_jiangqq/article/details/50158985

本文出自:【江清清的博客】

().前言:   

          仿36Kr客户端开发过程中,因为他们网站上面的新闻文章分类比较多,所以我这边还是打算模仿网易新闻APP的主界面新闻标签Tab以及页面滑动效果来进行实现。要实现的顶部的Tab标签的效果有很多方法例如采用开源项目ViewPagerIndicator中的TabPageIndicator就可以实现。不过我们今天不讲ViewPagerIndicator,我们来讲一下Google今年发布的TabLayout组件。在2015年的Google大会上,google发布的新的AndroidSupport Design库,里面也包含了几个新的控件,那么TabLayout就是其中一个。使用该组件我们可以很轻松的实现TabPageIndicator效果,并且该为官方的,可以向下兼容很多版本而且可以更加统一Material Design效果。不过查看TabLayout的源码发现该组件也是继承自HorizontalScrollView实现。

          使用HorizontalScrollView打造仿网易tab标签效果,点击进入...

          本例子具体代码已经上传到下面的项目中,欢迎各位去star和fork一下。

         FastDev4Android框架项目地址:https://github.com/jiangqqlmj/FastDev4Android

().使用方式:   

        2.1.我这边的项目采用Android Studio进行开发的,所以首先要引入TabLayout的依赖库,如下:

[html] view plaincopy
  1. compile'com.android.support:design:23.1.1'  
  2. compile'com.android.support:appcompat-v7:23.1.1'  


().效果实现:  

          我们现在需要仿照网易新闻(36Kr客户端)Tab标签切换以及底部新闻页面切换的效果。Tab标签实现采用TabLayout组件,底部页面切换采用Fragment+ViewPager+FragmentStatePagerAdapter实现。

          []:承载FragmentActivity这边就不讲解了,具体可以看上一篇文章和本项目的代码即可。那我们直接从Fragment开始讲起。

          3.1.首先我们需要给Fragment创建一个布局文件如下:

[html] view plaincopy
  1. <?xmlversionxmlversion="1.0" encoding="utf-8"?>  
  2. <LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
  3.    xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:orientation="vertical"android:layout_width="match_parent"  
  5.    android:layout_height="match_parent">  
  6.     <!--顶部tab标签容器-->  
  7.     <android.support.design.widget.TabLayout  
  8.        android:layout_width="match_parent"  
  9.        android:layout_height="wrap_content"  
  10.         android:id="@+id/tab_layout"  
  11.        android:background="@color/white"  
  12.        app:tabIndicatorColor="@color/color_selected"  
  13.        app:tabSelectedTextColor="@color/color_selected"  
  14.        app:tabTextColor="@color/color_unselected"  
  15.    
  16.        ></android.support.design.widget.TabLayout>  
  17.     <android.support.v4.view.ViewPager  
  18.        android:id="@+id/info_viewpager"  
  19.        android:layout_width="fill_parent"  
  20.        android:layout_height="fill_parent"  
  21.         />  
  22. </LinearLayout>  

        该布局主要为两个控件:第一部分为TableLayout组件该为Tab标签的容器,第二部分为ViewPager组件主要用于显示若干个Fragment进行页面切换。大家在TabLayout组件中应该已经注意到了三个自定义属性如下:

[html] view plaincopy
  1. app:tabIndicatorColor="@color/white"                 // 下方滚动的下划线颜色   
  2. app:tabSelectedTextColor="@color/gray"               // tab被选中后,文字的颜色   
  3. app:tabTextColor="@color/white"                      // tab默认的文字颜色   

这三个自定义属性是TabLayout提供的,我们可以任意修改标题颜色以及指示器的颜色,除此之外还提供了以下一些风格设置方法:

  • tabMaxWidth
  • tabIndicatorColor
  • tabIndicatorHeight
  • tabPaddingStart
  • tabPaddingEnd
  • tabBackground
  • tabTextAppearance
  • tabSelectedTextColor

      3.2.接着是是CNKFixedPagerAdapter,该为ViewPager的自定义适配器,在ViewPager中的每一项采用Fragment实现,所以传入了得Fragment的页面的集合,同时还定义了Tab显示标题的数组。

[java] view plaincopy
  1. package com.chinaztt.fda.adapter;  
  2. import android.support.v4.app.Fragment;  
  3. import android.support.v4.app.FragmentManager;  
  4. import android.support.v4.app.FragmentStatePagerAdapter;  
  5. import android.view.LayoutInflater;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.ImageView;  
  9. import android.widget.TextView;  
  10.    
  11. import com.chinaztt.fda.application.FDApplication;  
  12. import com.chinaztt.fda.ui.R;  
  13.    
  14. import java.util.List;  
  15. /** 
  16.  * 当前类注释:Fragment,Viewpager的自定义适配器 
  17.  * 项目名:FastDev4Android 
  18.  * 包名:com.chinaztt.fda.adapter 
  19.  * 作者:江清清 on 15/12/2 10:08 
  20.  * 邮箱:jiangqqlmj@163.com 
  21.  * QQ: 781931404 
  22.  * 公司:江苏中天科技软件技术有限公司 
  23.  */  
  24. public class CNKFixedPagerAdapter extends FragmentStatePagerAdapter {  
  25.     private String[] titles;  
  26.     private LayoutInflater mInflater;  
  27.     public void setTitles(String[] titles) {  
  28.         this.titles = titles;  
  29.     }  
  30.     private List<Fragment> fragments;  
  31.     public CNKFixedPagerAdapter(FragmentManager fm) {  
  32.         super(fm);  
  33.     }  
  34.    
  35.     @Override  
  36.     public Fragment getItem(int position) {  
  37.         return this.fragments.get(position);  
  38.     }  
  39.     @Override  
  40.     public int getCount() {  
  41.         return this.fragments.size();  
  42.     }  
  43.    
  44.     @Override  
  45.     public Object instantiateItem(ViewGroup container, int position) {  
  46.         Fragment fragment=null;  
  47.         try {  
  48.            fragment=(Fragment)super.instantiateItem(container,position);  
  49.         }catch (Exception e){  
  50.    
  51.         }  
  52.         return fragment;  
  53.     }  
  54.    
  55.     @Override  
  56.     public void destroyItem(ViewGroupcontainer, int position, Object object) {  
  57.    
  58.     }  
  59.     //此方法用来显示tab上的名字  
  60.     @Override  
  61.     public CharSequence getPageTitle(intposition) {  
  62.    
  63.         return titles[position %titles.length];  
  64.     }  
  65.     public List<Fragment> getFragments(){  
  66.         return fragments;  
  67.     }  
  68.     public void setFragments(List<Fragment> fragments) {  
  69.         this.fragments = fragments;  
  70.     }  
  71. }  

Adapter中我们重写了getPageTitle()方法,用来显示Tab的标题。

   3.3.下面就是具体的Fragment(TabInfoFragment)了,该Fragment中,我们初始化ViewPager,TabLayout以及自定义器适配器,Fragment页面和显示的Tab标题。

最终我们把适配器和ViewPager进行绑定,TabLayout和ViewPager进行绑定即可。

[java] view plaincopy
  1. public class TabInfoFragment extends Fragment {  
  2.     private String[]titles=new String[]{"全部","氪TV","O2O","新硬件","Fun!!","企业服务","Fit&Health","在线教育","互联网金融","大公司","专栏","新产品"};  
  3.     private View mView;  
  4.     private TabLayout tab_layout;  
  5.     private ViewPager info_viewpager;  
  6.     private List<Fragment> fragments;  
  7.     private CNKFixedPagerAdapter mPagerAdater;  
  8.     @Override  
  9.     public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {  
  10.         if(mView==null){  
  11.             mView=inflater.inflate(R.layout.tab_info_fragment_layout,container,false);  
  12.             initViews();  
  13.             initValidata();  
  14.         }  
  15.         return mView;  
  16.     }  
  17.     private void initViews(){  
  18.        tab_layout=(TabLayout)mView.findViewById(R.id.tab_layout);  
  19.        info_viewpager=(ViewPager)mView.findViewById(R.id.info_viewpager);  
  20.    
  21.     }  
  22.     private void initValidata(){  
  23.         fragments=new ArrayList<>();  
  24.         for(int i=0;i<12;i++){  
  25.             OneFragment oneFragment=new OneFragment();  
  26.             Bundle bundle=new Bundle();  
  27.            bundle.putString("extra",titles[i]);  
  28.             oneFragment.setArguments(bundle);  
  29.             fragments.add(oneFragment);  
  30.         }  
  31.         //创建Fragment的 ViewPager 自定义适配器  
  32.         mPagerAdater=new CNKFixedPagerAdapter(getChildFragmentManager());  
  33.         //设置显示的标题  
  34.         mPagerAdater.setTitles(titles);  
  35.         //设置需要进行滑动的页面Fragment  
  36.         mPagerAdater.setFragments(fragments);  
  37.    
  38.        info_viewpager.setAdapter(mPagerAdater);  
  39.        tab_layout.setupWithViewPager(info_viewpager);  
  40.    
  41.    
  42.         //设置Tablayout  
  43.         //设置TabLayout模式 -该使用Tab数量比较多的情况  
  44.        tab_layout.setTabMode(TabLayout.MODE_SCROLLABLE);  
  45.     }  
  46. }  

    相信大家已经看到该代码的最后有一句:

[html] view plaincopy
  1. tab_layout.setTabMode(TabLayout.MODE_SCROLLABLE);  

 该用来设置Tablayout的模式,除了上面的默认之外还有一个模式如下:

[html] view plaincopy
  1. tab_layout.setTabMode(TabLayout.MODE_FIXED);  

 两者的区别如下,如果Tab数量比较多的情况下,最少用上面那个,Tab标签可以左右滑动显示。

    3.4.运行效果如下:


().Tab升级版改造:   

         上面的效果是属于基础版本直接Tab显示标题就结束了,有时候不会达到我们的要求Tab标签上面显示图标。那么现在我们对其进行改造一下可以让TabLayout打造的Tab既能显示图标又能显示文字标题信息。该主要采用Tab的以下方法实现:

[html] view plaincopy
  1. tab.setCustomView(view); tab添加的自定义布局  

        4.1.首先对于Tab Item每一项我们需要定义一个布局文件:

[html] view plaincopy
  1. <?xmlversionxmlversion="1.0" encoding="utf-8"?>  
  2. <LinearLayoutxmlns:androidLinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"  
  3.    android:layout_width="wrap_content"  
  4.    android:layout_height="wrap_content"  
  5.     android:orientation="vertical"  
  6.     >  
  7.     <ImageView  
  8.        android:src="@mipmap/ic_launcher"  
  9.         android:layout_width="15dp"  
  10.         android:layout_height="15dp"  
  11.         android:id="@+id/imageView"  
  12.        android:layout_gravity="center_horizontal"  
  13.         />  
  14.     <TextView  
  15.         android:text="Item 01"  
  16.        android:layout_width="wrap_content"  
  17.        android:layout_height="wrap_content"  
  18.         android:id="@+id/textView"  
  19.        android:layout_gravity="center_horizontal"  
  20.         />  
  21. </LinearLayout>  

该布局文件很简单,上下布局图标和标题

4.2.然后我们需要在CNKFixedPagerAdapter中进行以下修改:先前我们是通过重写public CharSequence getPageTitle(int position)该方法来显示标题的,那么现在我们需要删掉或者注释掉该方法,然后新增一个getTabView()方法来实时创建Tab Item的布局然后绑定数据:

[html] view plaincopy
  1. /**  
  2.      * 添加getTabView的方法,来进行自定义Tab的布局View  
  3.      * @param position  
  4.      * @return  
  5.      */  
  6.     public View getTabView(int position){  
  7.        mInflater=LayoutInflater.from(FDApplication.getInstance());  
  8.         Viewview=mInflater.inflate(R.layout.tab_item_layout,null);  
  9.         TextView tv= (TextView)view.findViewById(R.id.textView);  
  10.         tv.setText(titles[position]);  
  11.         ImageView img = (ImageView)view.findViewById(R.id.imageView);  
  12.        img.setImageResource(R.mipmap.ic_launcher);  
  13.         return view;  
  14.     }  

4.3.这些步骤做完了之后,在主Fragment(TabInfoFragment)中对Tablayout中每一项Tab作如下设置即可:获取到每一项Tab,然后给该Tab设置自定义布局调用tab.setCustomView()方法。

[java] view plaincopy
  1. //设置自定义Tab--加入图标的demo  
  2.        for(int i=0;i<12;i++){  
  3.            TabLayout.Tab tab =tab_layout.getTabAt(i);  
  4.           tab.setCustomView(mPagerAdater.getTabView(i));  
  5.        }  

 4.4.运行结果如下:


().最后总结

           今天我们通过Android  Design支持库TabLayout组件实现了仿照网易新闻客户端首页的页面滑动和顶部Tab效果。希望对大家有所帮助使用以前的方式虽然也可以显示这样的效果,不过技术在发展嘛,紧跟时代潮流吧~嘿嘿。

           本次实例代码因为比较多,重点核心代码已经贴出来。不过实例注释过的全部代码已经上传到Github项目中了。同时欢迎大家去Github站点进行clone或者fork浏览整个开源快速开发框架项目~

https://github.com/jiangqqlmj/FastDev4Android

 

尊重原创,转载请注明:From Sky丶清(http://blog.csdn.net/developer_jiangqq) 侵权必究!

关注我的微博,可以获得更多精彩内容

0 0