<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      帶你實(shí)現(xiàn)開(kāi)發(fā)者頭條APP(四)---首頁(yè)優(yōu)化(加入design包)

      一 、前言

      上次模仿開(kāi)發(fā)者頭條首頁(yè)實(shí)現(xiàn)了一個(gè)版本,給345大神,我的產(chǎn)品經(jīng)理一看,又被鄙視了一把,說(shuō)還在用老的技術(shù),于是乎這三天把整個(gè)design包研究了一遍,然后把首頁(yè)的代碼幾乎重寫(xiě)了一遍。。。。順便用上了android studio,方便大家導(dǎo)入。。。

      效果圖如下:
      效果圖
      從gif動(dòng)態(tài)效果圖中我們可以看出,跟上次沒(méi)有啥變化,唯一變化的就是列表上拉的時(shí)候會(huì)隱藏標(biāo)題欄。。。其實(shí)里面的代碼幾乎重寫(xiě)了一遍,用了Android Design Support Library。

      Google在2015的IO大會(huì)上,給我們帶來(lái)了更加詳細(xì)的Material Design設(shè)計(jì)規(guī)范,同時(shí),也給我們帶來(lái)了全新的Android Design Support Library,在這個(gè)support庫(kù)里面,Google給我們提供了更加規(guī)范的MD設(shè)計(jì)風(fēng)格的控件。最重要的是,Android Design Support Library的兼容性更廣,直接可以向下兼容到Android 2.2。這不得不說(shuō)是一個(gè)良心之作。

      二、Toolbar+TabLayout 實(shí)現(xiàn) 標(biāo)題欄+三個(gè)切換Tab

      標(biāo)題欄我之前引用的一個(gè)布局文件,現(xiàn)在改成了Toolbar。一個(gè)控件就夠了。
      三個(gè)切換的Tab之前用的三個(gè)TextView,現(xiàn)在換成了TabLayout。
      換了之后有哪些優(yōu)點(diǎn):

      1).跟的上時(shí)代,逼格提高,更加規(guī)范的MD設(shè)計(jì)風(fēng)格
      2).控件變少了,現(xiàn)在一個(gè)功能一個(gè)控件就夠
      3).點(diǎn)擊Tab文字變色,還有指示器的滑動(dòng)在xml加個(gè)屬性就行。
      4).隱藏顯示標(biāo)題欄很方便。只需要在布局文件中改動(dòng)就行.

      1.布局文件

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

      為了使得Toolbar有滑動(dòng)效果,必須做到如下三點(diǎn):

      1. CoordinatorLayout作為布局的父布局容器。
      2. 給需要滑動(dòng)的組件設(shè)置 app:layout_scrollFlags=”scroll|enterAlways” 屬性。
      3. 滑動(dòng)的組件必須是AppBarLayout頂部組件。
      4. 給滑動(dòng)的組件設(shè)置app:layout_behavior屬性
        5.ViewPager顯示的Fragment里面不能是ListView,必須是RecyclerView。
      <?xml version="1.0" encoding="utf-8"?>
      <android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          android:id="@+id/coordinatorLayout"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
          <android.support.design.widget.AppBarLayout
              android:id="@+id/appBarLayout"
              android:layout_width="match_parent"
              android:layout_height="wrap_content">
      
              <android.support.v7.widget.Toolbar
                  android:id="@+id/toolbar"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:background="@color/launcher_item_select"
                  app:layout_scrollFlags="scroll|enterAlways"
                  app:titleTextAppearance="@style/ansenTextTitleAppearance">
              </android.support.v7.widget.Toolbar>
              <android.support.design.widget.TabLayout
                  android:id="@+id/tabLayout"
                  android:layout_width="match_parent"
                  android:layout_height="wrap_content"
                  android:layout_gravity="center_horizontal"
                  android:background="@color/main_color"
                  app:tabIndicatorColor="@color/white_normal"
                  app:tabIndicatorHeight="2dp"
                  app:tabSelectedTextColor="@color/main_title_text_select"
                  app:tabTextAppearance="@style/AnsenTabLayoutTextAppearance"
                  app:tabTextColor="@color/main_title_text_normal"/>
          </android.support.design.widget.AppBarLayout>
      
          <android.support.v4.view.ViewPager
              android:id="@+id/viewPager"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              app:layout_behavior="@string/appbar_scrolling_view_behavior" />
      </android.support.design.widget.CoordinatorLayout>
      
      2.代碼實(shí)現(xiàn) MainFragment.java

      1).初始化Toolbar,加載menu布局,實(shí)現(xiàn)標(biāo)題欄的自定義。給NavigationIcon設(shè)置點(diǎn)擊事件等。下面貼出代碼實(shí)現(xiàn),還有menu布局文件我就不貼出來(lái)了。那個(gè)也沒(méi)啥技術(shù)含量。

      Toolbar toolbar = (Toolbar) rootView.findViewById(R.id.toolbar);
      		toolbar.inflateMenu(R.menu.ansen_toolbar_menu);
      		toolbar.setNavigationIcon(R.mipmap.ic_menu_white);
      		toolbar.setTitle("關(guān)注公眾號(hào)[Android開(kāi)發(fā)者666]");
      		toolbar.setTitleTextColor(getResources().getColor(android.R.color.white));
      		toolbar.setNavigationOnClickListener(onClickListener);
      

      NavigationIcon監(jiān)聽(tīng)函數(shù),回調(diào)到MainActivity去。

      	private View.OnClickListener onClickListener=new View.OnClickListener(){
      		@Override
      		public void onClick(View view) {
      			if(drawerListener!=null){
      				drawerListener.open();
      			}
      		}
      	};
      

      MainActivity.java
      首先寫(xiě)了一個(gè)用來(lái)回調(diào)的接口

      	public interface MainDrawerListener{
      		public void open();//打開(kāi)Drawer
      	}
      

      初始化Fragment的時(shí)候把MainDrawerListener對(duì)象傳遞過(guò)去 這樣才能實(shí)現(xiàn)回調(diào)

      mainFragment=new MainFragment(drawerListener);
      
      	private MainDrawerListener drawerListener=new MainDrawerListener() {
      		@Override
      		public void open() {
      			mDrawerLayout.openDrawer(Gravity.LEFT);
      		}
      	};
      

      2).給ViewPager設(shè)置Fragment適配器,給TabLayout綁定ViewPager,這樣ViewPager滑動(dòng)的時(shí)候或者選擇tab的時(shí)候都會(huì)切換fragment。

      		vPager = (ViewPager) rootView.findViewById(R.id.viewPager);
      		vPager.setOffscreenPageLimit(2);//設(shè)置緩存頁(yè)數(shù)
      		vPager.setCurrentItem(0);
      
      		FragmentAdapter pagerAdapter = new FragmentAdapter(getActivity().getSupportFragmentManager());
      		SelectedFragment selectedFragment=new SelectedFragment();
      		SubscribeFragment subscribeFragment=new SubscribeFragment();
      		FindFragment findFragment=new FindFragment();
      
      		pagerAdapter.addFragment(selectedFragment,"精選");
      		pagerAdapter.addFragment(subscribeFragment,"訂閱");
      		pagerAdapter.addFragment(findFragment,"發(fā)現(xiàn)");
      
      		vPager.setAdapter(pagerAdapter);
      
      		TabLayout tabLayout = (TabLayout) rootView.findViewById(R.id.tabLayout);
      		tabLayout.setupWithViewPager(vPager);
      

      三 、分析TabLayout切換源碼

      我們調(diào)用TabLayout的setupWithViewPager(ViewPager viewPager)方法的時(shí)候就是設(shè)置切換監(jiān)聽(tīng)的時(shí)候。

          public void setupWithViewPager(ViewPager viewPager) {
              PagerAdapter adapter = viewPager.getAdapter();
              if(adapter == null) {
                  throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
              } else {
                  this.setTabsFromPagerAdapter(adapter);
                  viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
                  this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
              }
          }
      

      從上面代碼中我們可以看到主要設(shè)置了兩個(gè)監(jiān)聽(tīng)函數(shù)。先說(shuō)第一個(gè)。
      在TabLayout里面有一個(gè)靜態(tài)類(lèi)TabLayoutOnPageChangeListener,用來(lái)處理ViewPager改變狀態(tài)(切換或者增加)監(jiān)聽(tīng),看過(guò)我第三篇文章的同學(xué)對(duì)ViewPager的狀態(tài)改變監(jiān)聽(tīng)?wèi)?yīng)該很熟悉了。

       viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(this));
      

      TabLayoutOnPageChangeListener實(shí)現(xiàn)了ViewPagerde 的OnPageChangeListener接口,在onPageSelected方法中調(diào)用了當(dāng)前選中的某個(gè)Tab的select方法。

              public void onPageSelected(int position) {
                  TabLayout tabLayout = (TabLayout)this.mTabLayoutRef.get();
                  if(tabLayout != null) {
                      tabLayout.getTabAt(position).select();
                  }
      
              }
      

      然后繼續(xù)跟蹤TabLayout.Tab類(lèi)的select() 看看如何實(shí)現(xiàn)的。我們可以看到又調(diào)用了父類(lèi)(TabLayout)的selectTab。

              public void select() {
                  this.mParent.selectTab(this);
              }
      

      然后跟蹤selectTab方法,這里大家可以看到參數(shù)是某個(gè)具體Tab對(duì)象,首先判斷是不是當(dāng)前tab,如果不是設(shè)置選擇當(dāng)前的tab,開(kāi)啟tab滑動(dòng)動(dòng)畫(huà)。

       void selectTab(TabLayout.Tab tab) {
              if(this.mSelectedTab == tab) {
                  if(this.mSelectedTab != null) {
                      if(this.mOnTabSelectedListener != null) {
                          this.mOnTabSelectedListener.onTabReselected(this.mSelectedTab);
                      }
      
                      this.animateToTab(tab.getPosition());
                  }
              } else {
                  int newPosition = tab != null?tab.getPosition():-1;
                  this.setSelectedTabView(newPosition);
                  if((this.mSelectedTab == null || this.mSelectedTab.getPosition() == -1) && newPosition != -1) {
                      this.setScrollPosition(newPosition, 0.0F, true);
                  } else {
                      this.animateToTab(newPosition);
                  }
      
                  if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {
                      this.mOnTabSelectedListener.onTabUnselected(this.mSelectedTab);
                  }
      
                  this.mSelectedTab = tab;
                  if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {
                      this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab);
                  }
              }
      
          }
      

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

                  if(this.mSelectedTab != null && this.mOnTabSelectedListener != null) {
                      this.mOnTabSelectedListener.onTabSelected(this.mSelectedTab);
                  }
      

      選擇監(jiān)聽(tīng)的接口

          public interface OnTabSelectedListener {
              void onTabSelected(TabLayout.Tab var1);
      
              void onTabUnselected(TabLayout.Tab var1);
      
              void onTabReselected(TabLayout.Tab var1);
          }
      

      在TabLayout內(nèi)部實(shí)現(xiàn)了OnTabSelectedListener接口,在onTabSelected方法中調(diào)用了ViewPager的setCurrentItem(),這個(gè)方法大家應(yīng)該都熟悉吧,我就不多做解釋了。

          public static class ViewPagerOnTabSelectedListener implements TabLayout.OnTabSelectedListener {
              private final ViewPager mViewPager;
      
              public ViewPagerOnTabSelectedListener(ViewPager viewPager) {
                  this.mViewPager = viewPager;
              }
      
              public void onTabSelected(TabLayout.Tab tab) {
                  this.mViewPager.setCurrentItem(tab.getPosition());
              }
      
              public void onTabUnselected(TabLayout.Tab tab) {
              }
      
              public void onTabReselected(TabLayout.Tab tab) {
              }
          }
      

      上面說(shuō)到了第一種監(jiān)聽(tīng),就是ViewPager滑動(dòng)的時(shí)候如何切換item,如果切換tab。現(xiàn)在來(lái)說(shuō)第二種情況,就是點(diǎn)擊選擇tab的時(shí)候。如何切換的。繼續(xù)回到TabLayout的setupWithViewPager(ViewPager viewPager)方法。

       this.setOnTabSelectedListener(new TabLayout.ViewPagerOnTabSelectedListener(viewPager));
      

      看到ViewPagerOnTabSelectedListener類(lèi)是不是很熟悉,其實(shí)就是第一種方法最后調(diào)用的那個(gè)類(lèi)。。。。。因?yàn)辄c(diǎn)擊某個(gè)tab的時(shí)候,tab切換的代碼已經(jīng)運(yùn)行,所以我們這里只需要設(shè)置下ViewPager當(dāng)前選中的item就行。

      從源碼分析的文章第一次寫(xiě),不知道這樣寫(xiě)出來(lái)大家看的懂么,還有不對(duì)的地方也歡迎大家提出,可以給我評(píng)論哦,我會(huì)第一時(shí)間回復(fù)大家。

      四 、透劇

      本來(lái)打算順便寫(xiě)下RecyclerView的實(shí)現(xiàn)的,但是發(fā)現(xiàn)內(nèi)容已經(jīng)不少了,那就留著下篇文章吧,下篇文章打算左滑里面的布局用NavigationView實(shí)現(xiàn)。然后加上RecyclerView吧。

      五 、源碼下載

      點(diǎn)擊下載源碼

      六 、相關(guān)文章閱讀

      帶你實(shí)現(xiàn)開(kāi)發(fā)者頭條(一) 啟動(dòng)頁(yè)實(shí)現(xiàn)
      帶你實(shí)現(xiàn)開(kāi)發(fā)者頭條(二) 實(shí)現(xiàn)左滑菜單
      帶你實(shí)現(xiàn)開(kāi)發(fā)者頭條APP(三) 首頁(yè)實(shí)現(xiàn)

      各位看官如果覺(jué)得文章不錯(cuò),幫忙點(diǎn)個(gè)贊吧,對(duì)于你來(lái)說(shuō)是舉手之勞,但對(duì)于我來(lái)說(shuō)這就是堅(jiān)持下去的動(dòng)力。

      **推薦下自己創(chuàng)建的Android開(kāi)發(fā) QQ群: 202928390歡迎大家的加入. **

      如果你想第一時(shí)間看我們的后期文章,掃碼關(guān)注公眾號(hào),每周不定期推送Android開(kāi)發(fā)實(shí)戰(zhàn)教程文章,你還等什么,趕快關(guān)注吧,學(xué)好技術(shù),出任ceo,贏取白富美。。。。

            Android開(kāi)發(fā)666 - 安卓開(kāi)發(fā)技術(shù)分享
                  掃描二維碼加關(guān)注
      

      Android開(kāi)發(fā)666

      posted @ 2016-04-24 22:49  安輝  閱讀(1802)  評(píng)論(4)    收藏  舉報(bào)
      主站蜘蛛池模板: 又大又紧又粉嫩18p少妇| 亚洲人成网站色www| 最近中文字幕国产精选| 2020精品自拍视频曝光| 国产精品一区中文字幕| 欧美色综合天天久久综合精品| 无套内谢少妇毛片aaaa片免费| 日本不卡码一区二区三区| 福利无遮挡喷水高潮| 欧美野外伦姧在线观看| 97久久超碰精品视觉盛宴| 国模雨珍浓密毛大尺度150p| 国产熟睡乱子伦视频在线播放| 成人中文在线| 日本乱码在线看亚洲乱码| 制服丝袜长腿无码专区第一页| 吴桥县| 亚洲国产精品线观看不卡| 国产精品综合av一区二区| 精精国产xxx在线观看| 国产一区二区在线有码| www国产精品内射熟女| 亚洲精品午夜国产VA久久成人| 余干县| 精品偷拍被偷拍在线观看| 亚洲天堂在线观看完整版| 静宁县| 亚洲宅男精品一区在线观看| 亚洲成A人片在线观看的电影| 精品国产乱码久久久久久口爆网站| 精品一区二区三区蜜桃久| gogogo高清在线观看视频中文| 一区二区三区无码免费看| 最新亚洲人成网站在线观看| 国产av综合一区二区三区| 久久精品国产亚洲精品色婷婷 | 久久日产一线二线三线| 国产成人无码区免费内射一片色欲| 亚洲精品第一页中文字幕| 亚洲欧美人成人综合在线播放| 久久日韩在线观看视频|