Android仿今日頭條滑動頁面導航效果_Android

來源:互聯網
上載者:User

最近項目中用到了滑動頁面,也就是和目前市場上很火的"今日頭條"頁面滑動類似,在網上找了一下,大部分都是用ViewPager來實現的,剛開始我用的是ViewPager+ViewGroup,上面的標題按鈕用的是HorizontalScrollView,寫完之後感覺效果比較生硬,果斷換掉,發現了一個效果比較好的第三方,也就是今天的主題:PagerSlidingTabStrip.好了,下面來具體介紹一下PagerSlidingTabStrip,進行一下源碼解析.

一、看一下demo的樣子吧

二、把PagerSlidingTabStrip匯入我們的項目中
然後在我們的布局檔案中進行聲明:

<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:app="http://schemas.android.com/apk/res/com.hankkin.PagerSlidingTabStrip"        android:orientation="vertical"        android:layout_width="fill_parent"        android:layout_height="fill_parent"     >    <com.hankkin.PagerSlidingTabStrip.view.PagerSlidingTabStrip       android:id="@+id/tab"       app:pstsShouldExpand="false"       app:pstsUnderlineHeight="2dp"       app:pstsIndicatorHeight="2dp"       app:pstsIndicatorColor="@android:color/holo_blue_light"       app:selectedTabTextColor="@android:color/holo_blue_light"       app:pstsDividerColor="@android:color/transparent"       app:pstsTabBackground="@drawable/background"       android:background="@android:color/white"       android:layout_width="match_parent"       android:layout_height="55dp"/>    <android.support.v4.view.ViewPager       android:id="@+id/pager"       android:layout_width="match_parent"       android:layout_height="match_parent"/>  </LinearLayout></span><span style="font-size:18px;"> </span> 

上面的也就是我們的標題滑動按鈕,下面的ViewPager用來存放我們的內容
三、建立Adapter

<span style="font-size:14px;">package com.hankkin.PagerSlidingTabStrip.adapter;  import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import com.hankkin.PagerSlidingTabStrip.fragment.AndroidFragment; import com.hankkin.PagerSlidingTabStrip.fragment.JavaFragment; import com.hankkin.PagerSlidingTabStrip.fragment.ObjectCFragment;  import java.util.List;  public class MyAdapter extends FragmentPagerAdapter {   private AndroidFragment androidFragment;   private JavaFragment javaFragment;   private ObjectCFragment objectCFragment;   private String[] titles;   public MyAdapter(FragmentManager fm,String[] titles) {     super(fm);     this.titles = titles;   }    @Override   public Fragment getItem(int position) {     switch (position) {       case 0:         if (androidFragment == null) {           androidFragment = new AndroidFragment();         }         return androidFragment;       case 1:         if (javaFragment == null) {           javaFragment = new JavaFragment();         }         return javaFragment;       case 2:         if (objectCFragment == null) {           objectCFragment = new ObjectCFragment();         }         return objectCFragment;       default:         return null;     }   }    @Override   public int getCount() {     return titles.length;   }    public String getPageTitle(int i){     return titles[i];   }  } </span> 

我這裡用的是片段Fragment,最下面的getPageTitle()是我們的PagerSlidingTabStrip中的方法,用來擷取標題
接下來我們初始化PagerSlidingTabStrip和ViewPager還有我們的片段

<span style="font-size:14px;"> private void initViews(){     fragments = new ArrayList<>();     pagerTab = (PagerSlidingTabStrip) findViewById(R.id.tab);     pager = (ViewPager) findViewById(R.id.pager);      for (int i=0;i<titles.length;i++){       Fragment fragment = new Fragment();       fragments.add(fragment);     }      adapter = new MyAdapter(getSupportFragmentManager(),titles);     pager.setAdapter(adapter);     pagerTab.setViewPager(pager);   }</span> 

在Adapter中利用片段管理器擷取我們的片段和標題相對應上.這裡面需要注意提一下,如果片段的個數比較少我們可以手動建立片段,如果像今日頭條很多的話也沒關係,動態建立Fragment,因為我們可以看到頭條的每個片段中的內容都是類似的,所以說動態建立也未嘗不可,只有個別特殊的我們也可以特殊處理.

就這麼簡單就可以實作類別似頭條的頁面滑動效果,下面我們來看一下PagerSlidingTabStrip的源碼吧,看懂了之後也方便我們進行改進.
四、PagerSlidingTabStrip源碼解析
首先我們看幾個比較重要的屬性

private int indicatorColor = 0xFF666666;// 滑動指標顏色 private int underlineColor = 0x1A000000;//在視圖的底部的全寬度的線pstsunderlinecolor顏色 private int dividerColor = 0x1A000000;//選項卡之間的分隔pstsdividercolor顏色  private boolean shouldExpand = false;//pstsshouldexpand如果設定為TRUE,每個標籤都給予同樣的重量,預設為false private boolean textAllCaps = true;//pststextallcaps如果為真,所有選項卡標題都是大寫,預設為true  private int scrollOffset = 52;//pstsscrolloffset捲軸被選擇的標籤的位移 private int indicatorHeight = 8;//滑動指標pstsindicatorheight private int underlineHeight = 2;//在視圖的底部的全寬度的線pstsunderlineheight高度 private int dividerPadding = 12;//pstsdividerpadding頂部和底部填充的分頻器 private int tabPadding = 24;//pststabpaddingleftright左、右填充每個選項卡 private int dividerWidth = 1;//選項卡分割線寬度  private int tabTextSize = 12;//選項卡字型大小 private int tabTextColor = 0xFF666666;//選項卡字型顏色 private int selectedTabTextColor = 0xFF666666;//當前選中字型顏色 private Typeface tabTypeface = null; private int tabTypefaceStyle = Typeface.NORMAL;  private int lastScrollX = 0;  private int tabBackgroundResId = R.drawable.background;//pststabbackground背景繪製的每個標籤,應該是一個statelistdrawable 

我們可以自己定義這些屬性的值,因為可能預設的不太好看
1.首先看一下我們的構造會初始化一些什麼屬性

<span style="font-size:14px;">public PagerSlidingTabStrip(Context context, AttributeSet attrs, int defStyle) {     super(context, attrs, defStyle);      setFillViewport(true);//預設使子view可以展開來填滿整個螢幕     setWillNotDraw(false);//預設不執行OnDraw()方法     //初始化盛放按鈕標題的線性布局     tabsContainer = new LinearLayout(context);     tabsContainer.setOrientation(LinearLayout.HORIZONTAL);     tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));     addView(tabsContainer);      DisplayMetrics dm = getResources().getDisplayMetrics();     //匯入相應資源檔     scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);     indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);     underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);     dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);     tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);     dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);     tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);      // get system attrs (android:textSize and android:textColor)      TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);      tabTextSize = a.getDimensionPixelSize(0, tabTextSize);     tabTextColor = a.getColor(1, tabTextColor);      a.recycle();      // get custom attrs      a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);      indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);      //tab文字選中時的顏色,預設和滑動指標的顏色一致      selectedTabTextColor=a.getColor(R.styleable.PagerSlidingTabStrip_selectedTabTextColor, indicatorColor);     //初始化屬性樣式     underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);     dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);     indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);     underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);     dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);     tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);     tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);     shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);     scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);     textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);      a.recycle();      rectPaint = new Paint();     rectPaint.setAntiAlias(true);     rectPaint.setStyle(Style.FILL);      dividerPaint = new Paint();     dividerPaint.setAntiAlias(true);     dividerPaint.setStrokeWidth(dividerWidth);      defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);     expandedTabLayoutParams = new LinearLayout.LayoutParams(0, LayoutParams.MATCH_PARENT, 1.0f);      if (locale == null) {       locale = getResources().getConfiguration().locale;     }   }</span> 

這些基本都能看懂,主要都是初始化一些屬性,代碼中也有相應的注釋,就不一一介紹了

2.定義ViewPager滑動監聽器,設定當前pager的位置

<span style="font-size:14px;">private class PageListener implements OnPageChangeListener {      @Override     public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {       currentPosition = position;       currentPositionOffset = positionOffset;        scrollToChild(position, (int) (positionOffset * tabsContainer.getChildAt(position).getWidth()));        invalidate();        if (delegatePageListener != null) {         delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);       }     }      @Override     public void onPageScrollStateChanged(int state) {       if (state == ViewPager.SCROLL_STATE_IDLE) {         scrollToChild(pager.getCurrentItem(), 0);       }        if (delegatePageListener != null) {         delegatePageListener.onPageScrollStateChanged(state);       }     }      @Override     public void onPageSelected(int position) {       selectedPosition = position;       updateTabStyles();       if (delegatePageListener != null) {         delegatePageListener.onPageSelected(position);       }     }    }</span> 

3.更新標題樣式,也就是滑動到當前標題下設定標題狀態

<span style="font-size:14px;">private void updateTabStyles() {      for (int i = 0; i < tabCount; i++) {        View v = tabsContainer.getChildAt(i);        v.setBackgroundResource(tabBackgroundResId);        if (v instanceof TextView) {          TextView tab = (TextView) v;         tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, tabTextSize);         tab.setTypeface(tabTypeface, tabTypefaceStyle);         tab.setTextColor(tabTextColor);          // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a         // pre-ICS-build         if (textAllCaps) {           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {             tab.setAllCaps(true);           } else {             tab.setText(tab.getText().toString().toUpperCase(locale));           }         }         if (i == selectedPosition) {           tab.setTextColor(selectedTabTextColor);         }       }     }    }</span> 

大體就差不多這些了,好了,給大家看一下我自己完善後的樣子吧

沒有做太多調整,只是稍微的改了一下樣式,裡面還有一些比較細節的東西沒有介紹,比如標題的寬度是平均分配還是分體字型長度進行設定,我們可以修改shouldExpand屬性,大家有興趣的自己仔細研究一下吧.

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.