ToolBar、TabLayout、Fragment+ViewPager的開發實踐

此文優先發佈於個人我的博客:TB+TableLayout+Fragment+VP開發實踐html

研究ToolBar、TabLayout、Fragment+ViewPager的開發實踐覆盤以及還沒有解決的問題。歡迎評論留言。java

XML

TabLayout

添加依賴android

'android.support.design:28.0.0'

此處添加AppBarLayout做爲完整的佈局1:git

AppBarLayout是Android Design Support Library新加的控件繼承自LinearLayout,
它用來將Toolbar和TabLayout組合起來做爲一個總體。
<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
    
<android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            app:layout_scrollFlags="scroll|enterAlways" //滑動隱藏功能
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
<android.support.design.widget.TabLayout
          android:id="@+id/main_tablayout"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"         
          android:background="@color/color_title_bar"/>

<android.support.v4.view.ViewPager <!--TabLayout相關聯的ViewPager-->
        android:id="@+id/viewpager"
        android:layout_width="match_parent"
        android:layout_height="0px"
        android:layout_weight="1"
        android:background="@android:color/white" />

TabLayout可選屬性

tab
可更改屬性 屬性說明
tabBackground TabLayout的背景
tabSelectedTextColor 當前標籤的字體顏色
tabIndicator

能夠寫一個style,下文中會提到github

可更改屬性 屬性說明
tabIndicatorColor 選中線的顏色
tabIndicatorHeight 選中線的高度
tabMode
可更改屬性 屬性說明
FIXED 不可左右滑動,用於標籤較少時
SCROLLABLE 可左右滑動,用於標籤較多時

Fragment

爲何要建立Fragment:TabLayout中的ViewPager對應着相應的Fragment,因此須要建立。segmentfault

有的示例僅建立了一個Fragment,其中爲定義文字數組實現,若開發中則須要多個Fragment添加,均用Arratlist於Activity中。數組

XXXFragment.java:app

public class XXXFragment extends Fragment {
    
    private Page/View;  //建立變量
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //mPage = getArguments().getInt(ARG_PAGE);
    }
 
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_page, container, false);
        TextView textView = (TextView) view; //參考[^6]
        textView.setText("Fragment #" + mPage); 
        return view;
    }
 
}

一些暫未明確的代碼段框架

public static final String TYPE = "TYPE"; //此處未知含義

參考2ide

//此處的含義多是新增實例,存儲值?
    public static XXXFragment newInstance(int page) { 
        Bundle args = new Bundle();
        args.putInt(ARG_PAGE, page);
        PageFragment pageFragment = new PageFragment();
        pageFragment.setArguments(args);
        return pageFragment;
    }

Activity

若是須要定義TableLayout的tab文字,則在其中定義:public static final String[] titles,以後添加集合。

這裏把2定義文字放在了Adapter中,緣由未知。

關於添加圖片,下文有提到。

private Toolbar toolbar; //增長相關變量
    private TabLayout tabLayout;
    private ViewPager viewPager;

    public static final String[] titles = {"", ""};

    private List<Fragment> fragments; //定義fragment的集合縮寫
    private List<String> tabNames;
    private List<Integer> tabIcs;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.fragment_xxx);
        initView();        //各類初始化:界面、添加的fragment值、事件
        initValue();
        initEvent();
    }

    //各類初始化開始

    private void initView() { //初始化實例

        toolbar = (Toolbar) findViewById(R.id.Toolbar); 
        setSupportActionBar(toolbar); //支持actionbar,此處多種寫法
        getSupportActionBar().setDisplayHomeAsUpEnabled(true); //在首頁顯示

        viewPager = (ViewPager) findViewById(R.id.viewpager); //實例化控件
        tabLayout = (TabLayout) findViewById(R.id.tabs);
    }

    private void initValue() { 
    //初始化值,添加每個TableLayout裏的ArrayList,設置與標題欄一一對應的視圖(片斷)集合

        fragments = new ArrayList<>();
        fragments.add(new xxxFragment());
        fragments.add(new xxxFragment()); //有多少個fragment就在這裏添加多少

        tabNames = new ArrayList<>(); //添加標題集合,同上
        tabNames.add(" ");
        tabNames.add(" ");

        /*tabIcs = new ArrayList<>(); 此處尚不明確是否有,使用spanstring或其餘方法此處是否須要
        tabIcs.add(R.drawable.tab_xxx);
        tabIcs.add(R.drawable.tab_xxx);*/
        
        //給tabLayout添加選項卡
        for(int i=0;i< fragments.size();i++){
            tabLayout.addTab(tabLayout.newTab().setText((CharSequence) fragments.get(i)));
        }

        FragmentViewPagerAdapter adapter = new FragmentViewPagerAdapter
        (getSupportFragmentManager(), fragments, tabNames,tabIcs); 
        // 初始化ViewPager適配器        //此處須要增長與添加的集合以及上述定義的值匹配,若未定義則無需添加

        viewPager.setAdapter(adapter); //給ViewPager設置適配器
        tabLayout.setupWithViewPager(viewPager);  //將TabLayout和ViewPager關聯起來      
        /*setupWithViewPager這個方法會先將tab清除而後再根據ViewPager的adapter裏的count去取pagetitle,這也就是有時遇到用addTab方法添加tab不起做用的問題。*/

        //setupTabIcons();
        viewPager.setCurrentItem(1);
        viewPager.setCurrentItem(0);
    }

此處的setupTabIcons()方法,在下文添加圖片會提到。[參考連接]()

默認顯示第一個Tab3

tab.addTab(tab,i == 0, ? true:false);

FragmentPagerAdapter

須要使用Fragment的話就須要這個適配器

public class一個自定義的適配器名稱繼承自FragmentPagerAdapter。

List<Fragment> xxxfragment;
    List<String> titleList;

public MyTableViewAdapter(FragmentManager fm , List<Fragment> pagerList , List<String> titleList) {
        super(fm);
    this.pagerList = pagerList; // 此處使用this.與上述定義匹配
  
}
    
public Fragment getItem(int poition)
    super.

public int getCount(int poition) { return (tab個數) } 
   return xxxfragment.get(position); //普通狀況
   return xxxfragment != null ? pagerList.size() : 0; //設置不等於null的狀況,參考[^4]

public long getItemId(int poition)  { return super.getItemId(position) }
return xxxfragment.get(position);

此處可能還有,參考 3

public destoryItemId(View view contain,int poition,Object object)

點擊切換Tab的操做(兩種方式)

  1. .setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() 方法3

當tab頁面被選中時,會調用這個方法,當tab頁面被選中時,切換目前的fragment:

@Override
public void onTabSelected(TabLayout.Tab tab) {
int position = tab.getPosition();
    
Fragment fragment = (Fragment)adapter.instantiateItem(container, position);
    
adapter.setPrimaryItem(container, pos, fragment);
adapter.finishUpdate(container);
    
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
  1. 使用selector代替4

高級

在TabLayout中添加圖片

方法

getTabView()4

此方法爲我首先嚐試使用,能夠更改圖標顏色以及狀態。

步驟:

  1. 在Activity.java中設置圖片點擊(使用selector)數組public int[]
  2. 設置setupTabIcons();
  3. 建立getTabView()方法

這裏52把此方法放到了FragmentAdapter中,我的猜想緣由多是一同將getTabView()或imagespan使用。

SpannableString

更多支持:介紹參考連接6

SpannableString這個類實現了CharSequence這個接口,因此能夠在Adapter中的getPageTitle()中返回。

SpannableString的構造方法須要一個參數:CharSequence(超級字符串的基本顯示內容),

setSpan爲核心方法

方法值:

public void setSpan(Object what, int start, int end, int flags) {
    super.setSpan(what, start, end, flags);
          //what:向這個超級字符串中添加的內容。例如:前景色、背景色、圖片、連接、下劃線等
          //start:開始的位置(0爲開始)
          //結束的位置
          //flags:標識在span範圍內的文本先後輸入新的字符時是否也應用這個效果
}

SpanString舉例因爲衆多,表格與文末7

經搜索:

其中使用ImageSpan的兩種方法,發現如下兩種均爲僅添加圖標方法,而不適用於點擊切換顏色:

使用SpanString和Imagespan:2
  1. 在SimpleFragmentPagerAdapter中設置數組int[]
  2. 樣式文件定義
保留字符串並設置空,添加圖片方法8
  1. 修改Adapter的構造方法:設置tabName和tabIcons變量:每一個Tab上的文字和圖標的變量
  2. 修改getPageTitle()方法:if-else語句:若是不設置文字,則保留一個字符,若是設置圖標,則使用span
  3. 添加定義style(關鍵):textAllCaps、android:textAllCaps必須設置爲false,以後XML中TabLayout設置style。

SpanString舉例,示例代碼7,項目完整地址9.

可更改屬性 屬性說明
AbsoluteSizeSpan 單位爲物理像素
AlignmentSpan 支持ALIGN_NORMAL,ALIGN_OPPOSITE,ALIGN_CENTER
BackgroundColorSpan 文字背景色改變
BulletSpan 小圓圈
ClickableSpan 可點擊
DrawableMarginSpan Drawable,不佔位
DynamicDrawableSpan DynamicDrawable,佔位
ForegroundColorSpan 前景色
IconMarginSpan 圖標margin,不佔位
ImageSpan 圖片,佔位
LeadingMarginSpan 控制行前空隙
QuoteSpan 左側出現引用符號 豎線
RelativeSizeSpan 字體放大
ScaleXSpan 字體寬度放大
StrikethroughSpan 刪除線
StyleSpan 主要由正常、粗體、斜體和同時加粗傾斜四種樣式,常量值定義在Typeface類中
SubscriptSpan 下標
SuperscriptSpan 上標
TextAppearanceSpan Sets the text color, size, style, and typeface to match a TextAppearance
TypefaceSpan 字體設置
UnderlineSpan 下劃線
URLSpan URL


  1. Android Design Support Library(一)用TabLayout實現相似網易選項卡動態滑動效果
  2. android design library提供的TabLayout的用法,不少教程都參考了此文章。
  3. 利用TabLayout和fragment搭建app框架
  4. Android TabLayout setCustomView 實現帶圖標的tab
  5. 4
  6. android設計庫提供的TabLayout的簡單使用(TabLayout + ViewPager + Fragment)
  7. SpannableString
  8. TabLayout與ViewPager的聯合使用
  9. onlyloveyd/SpannableDemo
相關文章
相關標籤/搜索