Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發實例 >> 帶你實現開發者頭條(四) 首頁的優化(加入design包)

帶你實現開發者頭條(四) 首頁的優化(加入design包)

編輯:Android開發實例

  一 、前言

  上次模仿開發者頭條首頁實現了一個版本,給345大神,我的產品經理一看,又被鄙視了一把,說還在用老的技術,於是乎這三天把整個design包研究了一遍,然後把首頁的代碼幾乎重寫了一遍。。。。順便用上了android studio,方便大家導入。。。

  效果圖如下:

帶你實現開發者頭條(四) 首頁的優化(加入design包)

  從gif動態效果圖中我們可以看出,跟上次沒有啥變化,唯一變化的就是列表上拉的時候會隱藏標題欄。。。其實裡面的代碼幾乎重寫了一遍,用了Android Design Support Library。

  Google在2015的IO大會上,給我們帶來了更加詳細的Material Design設計規范,同時,也給我們帶來了全新的Android Design Support Library,在這個support庫裡面,Google給我們提供了更加規范的MD設計風格的控件。最重要的是,Android Design Support Library的兼容性更廣,直接可以向下兼容到Android 2.2。這不得不說是一個良心之作。

  二、Toolbar+TabLayout 實現 標題欄+三個切換Tab

  標題欄我之前引用的一個布局文件,現在改成了Toolbar。一個控件就夠了。

  三個切換的Tab之前用的三個TextView,現在換成了TabLayout。

  換了之後有哪些優點:

  1).跟的上時代,逼格提高,更加規范的MD設計風格

  2).控件變少了,現在一個功能一個控件就夠

  3).點擊Tab文字變色,還有指示器的滑動在xml加個屬性就行。

  4).隱藏顯示標題欄很方便。只需要在布局文件中改動就行.

  1.布局文件

  最外層是CoordinatorLayout,裡面主要就分兩塊,AppBarLayout+ViewPager(AppBarLayout裡面包含標題欄的Toolbar+TabLayout,ViewPager用來切換Fragment顯示)

  為了使得Toolbar有滑動效果,必須做到如下三點:

  CoordinatorLayout作為布局的父布局容器。

  給需要滑動的組件設置 app:layout_scrollFlags=”scroll|enterAlways” 屬性。

  滑動的組件必須是AppBarLayout頂部組件。

  給滑動的組件設置app:layout_behavior屬性

  5.ViewPager顯示的Fragment裡面不能是ListView,必須是RecyclerView。

XML/HTML代碼
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     xmlns:app="http://schemas.android.com/apk/res-auto"  
  4.     android:id="@+id/coordinatorLayout"  
  5.     android:layout_width="match_parent"  
  6.     android:layout_height="match_parent">  
  7.   
  8.     <android.support.design.widget.AppBarLayout  
  9.         android:id="@+id/appBarLayout"  
  10.         android:layout_width="match_parent"  
  11.         android:layout_height="wrap_content">  
  12.   
  13.         <android.support.v7.widget.Toolbar  
  14.             android:id="@+id/toolbar"  
  15.             android:layout_width="match_parent"  
  16.             android:layout_height="wrap_content"  
  17.             android:background="@color/launcher_item_select"  
  18.             app:layout_scrollFlags="scroll|enterAlways"  
  19.             app:titleTextAppearance="@style/ansenTextTitleAppearance">  
  20.         </android.support.v7.widget.Toolbar>  
  21.         <android.support.design.widget.TabLayout  
  22.             android:id="@+id/tabLayout"  
  23.             android:layout_width="match_parent"  
  24.             android:layout_height="wrap_content"  
  25.             android:layout_gravity="center_horizontal"  
  26.             android:background="@color/main_color"  
  27.             app:tabIndicatorColor="@color/white_normal"  
  28.             app:tabIndicatorHeight="2dp"  
  29.             app:tabSelectedTextColor="@color/main_title_text_select"  
  30.             app:tabTextAppearance="@style/AnsenTabLayoutTextAppearance"  
  31.             app:tabTextColor="@color/main_title_text_normal"/>  
  32.     </android.support.design.widget.AppBarLayout>  
  33.   
  34.     <android.support.v4.view.ViewPager  
  35.         android:id="@+id/viewPager"  
  36.         android:layout_width="match_parent"  
  37.         android:layout_height="match_parent"  
  38.         app:layout_behavior="@string/appbar_scrolling_view_behavior" />  
  39. </android.support.design.widget.CoordinatorLayout>  

  2.代碼實現 MainFragment.java

  1).初始化Toolbar,加載menu布局,實現標題欄的自定義。給NavigationIcon設置點擊事件等。下面貼出代碼實現,還有menu布局文件我就不貼出來了。那個也沒啥技術含量。

Java代碼
  1. Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);  
  2.         toolbar.inflateMenu(R.menu.ansen_toolbar_menu);  
  3.         toolbar.setNavigationIcon(R.mipmap.ic_menu_white);  
  4.         toolbar.setTitle("關注公眾號[Android開發者666]");  
  5.         toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));  
  6.         toolbar.setNavigationOnClickListener(onClickListener); 

  NavigationIcon監聽函數,回調到MainActivity去。

Java代碼
  1. private View.OnClickListener onClickListener=new View.OnClickListener(){  
  2.     @Override  
  3.     public void onClick(View view) {  
  4.         if(drawerListener!=null){  
  5.             drawerListener.open();  
  6.         }  
  7.     }  
  8. };  

  MainActivity.java

  首先寫了一個用來回調的接口

Java代碼
  1. public interface MainDrawerListener{  
  2.     public void open();//打開Drawer  
  3. }  

  初始化Fragment的時候把MainDrawerListener對象傳遞過去 這樣才能實現回調

Java代碼
  1. mainFragment=new MainFragment(drawerListener);  
Java代碼
  1. private MainDrawerListener drawerListener=new MainDrawerListener() {  
  2.     @Override  
  3.     public void open() {  
  4.         mDrawerLayout.openDrawer(Gravity.LEFT);  
  5.     }  
  6. };  

  2).給ViewPager設置Fragment適配器,給TabLayout綁定ViewPager,這樣ViewPager滑動的時候或者選擇tab的時候都會切換fragment。

Java代碼
  1. vPager = (ViewPager) rootView.findViewById(R.id.viewPager);  
  2. vPager.setOffscreenPageLimit(2);//設置緩存頁數  
  3. vPager.setCurrentItem(0);  
  4.   
  5. FragmentAdapter pagerAdapter = new FragmentAdapter(getActivity().getSupportFragmentManager());  
  6. SelectedFragment selectedFragment=new SelectedFragment();  
  7. SubscribeFragment subscribeFragment=new SubscribeFragment();  
  8. FindFragment findFragment=new FindFragment();  
  9.   
  10. pagerAdapter.addFragment(selectedFragment,"精選");  
  11. pagerAdapter.addFragment(subscribeFragment,"訂閱");  
  12. pagerAdapter.addFragment(findFragment,"發現");  
  13.   
  14. vPager.setAdapter(pagerAdapter);  
  15.   
  16. TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabLayout);  
  17. tabLayout.setupWithViewPager(vPager);  

  三 、分析TabLayout切換源碼

  我們調用TabLayout的setupWithViewPager(ViewPager viewPager)方法的時候就是設置切換監聽的時候。

Java代碼
  1. public void setupWithViewPager(ViewPager viewPager) {  
  2.     PagerAdapter adapter = viewPager.getAdapter();  
  3.     if(adapter == null) {  
  4.         throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");  
  5.     } else {  
  6.         this.setTabsFromPagerAdapter(adapter);  
  7.         viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));  
  8.         this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));  
  9.     }  
  10. }  

  從上面代碼中我們可以看到主要設置了兩個監聽函數。先說第一個。

  在TabLayout裡面有一個靜態類TabLayoutOnPageChangeListener,用來處理ViewPager改變狀態(切換或者增加)監聽,看過我第三篇文章的同學對ViewPager的狀態改變監聽應該很熟悉了。

Java代碼
  1. viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));  

  TabLayoutOnPageChangeListener實現了ViewPagerde 的OnPageChangeListener接口,在onPageSelected方法中調用了當前選中的某個Tab的select方法。

Java代碼
  1. public void onPageSelected(int position) {  
  2.     TabLayout tabLayout = (TabLayout)this.mTabLayoutRef.get();  
  3.     if(tabLayout != null) {  
  4.         tabLayout.getTabAt(position).select();  
  5.     }  
  6.   
  7. }  

  然後繼續跟蹤TabLayout.Tab類的select() 看看如何實現的。我們可以看到又調用了父類(TabLayout)的selectTab。

Java代碼
  1. public void select() {  
  2.     this.mParent.selectTab(this);  
  3. }  

  然後跟蹤selectTab方法,這裡大家可以看到參數是某個具體Tab對象,首先判斷是不是當前tab,如果不是設置選擇當前的tab,開啟tab滑動動畫。

Java代碼
  1. void selectTab(TabLayout.Tab tab) {  
  2.        if(this.mSelectedTab == tab) {  
  3.            if(this.mSelectedTab != null) {  
  4.                if(this.mOnTabSelectedListener != null) {  
  5.                    this.mOnTabSelectedListener.onTabReselected(this.mSelectedTab);  
  6.                }  
  7.   
  8.                this.animateToTab(tab.getPosition());  
  9.            }  
  10.        } else {  
  11.            int newPosition = tab != null?tab.getPosition():-1;  
  12.            this.setSelectedTabView(newPosition);  
  13.            if((this.mSelectedTab == null || this.mSelectedTab.getPosition() == -1) && newPosition != -1) {  
  14.                this.setScrollPosition(newPosition, 0.0F, true);  
  15.            } else {  
  16.                this.animateToTab(newPosition);  
  17.            }  
  18.   
  19.            if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {  
  20.                this.mOnTabSelectedListener.onTabUnselected(this.mSelectedTab);  
  21.            }  
  22.   
  23.            this.mSelectedTab = tab;  
  24.            if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {  
  25.                this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab);  
  26.            }  
  27.        }  
  28.   
  29. }  

  上面的代碼我就不一一解釋了,直接看最下面那兩行代碼。調用tab的選擇方法。

Java代碼
  1. if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {  
  2.     this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab);  
  3. }  

  選擇監聽的接口

Java代碼
  1. public interface OnTabSelectedListener {  
  2.     void onTabSelected(TabLayout.Tab var1);  
  3.   
  4.     void onTabUnselected(TabLayout.Tab var1);  
  5.   
  6.     void onTabReselected(TabLayout.Tab var1);  
  7. }  

  在TabLayout內部實現了OnTabSelectedListener接口,在onTabSelected方法中調用了ViewPager的setCurrentItem(),這個方法大家應該都熟悉吧,我就不多做解釋了。

Java代碼
  1. public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {  
  2.     private final ViewPager mViewPager;  
  3.   
  4.     public ViewPagerOnTabSelectedListener(ViewPager viewPager) {  
  5.         this.mViewPager = viewPager;  
  6.     }  
  7.   
  8.     public void onTabSelected(TabLayout.Tab tab) {  
  9.         this.mViewPager.setCurrentItem(tab.getPosition());  
  10.     }  
  11.   
  12.     public void onTabUnselected(TabLayout.Tab tab) {  
  13.     }  
  14.   
  15.     public void onTabReselected(TabLayout.Tab tab) {  
  16.     }  
  17. }  

  上面說到了第一種監聽,就是ViewPager滑動的時候如何切換item,如果切換tab。現在來說第二種情況,就是點擊選擇tab的時候。如何切換的。繼續回到TabLayout的setupWithViewPager(ViewPager viewPager)方法。

Java代碼
  1. this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));  

  看到ViewPagerOnTabSelectedListener類是不是很熟悉,其實就是第一種方法最後調用的那個類。。。。。因為點擊某個tab的時候,tab切換的代碼已經運行,所以我們這裡只需要設置下ViewPager當前選中的item就行。

  從源碼分析的文章第一次寫,不知道這樣寫出來大家看的懂麼,還有不對的地方也歡迎大家提出,可以給我評論哦,我會第一時間回復大家。

  四 、劇透

  本來打算順便寫下RecyclerView的實現的,但是發現內容已經不少了,那就留著下篇文章吧,下篇文章打算左滑裡面的布局用NavigationView實現。然後加上RecyclerView吧。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved