ToolBar牍疏、TabLayout、Fragment+ViewPager的開(kāi)發(fā)實(shí)踐

研究ToolBar拨齐、TabLayout鳞陨、Fragment+ViewPager的開(kāi)發(fā)實(shí)踐復(fù)盤(pán)以及尚未解決的問(wèn)題。歡迎評(píng)論留言瞻惋。

XML

TabLayout

添加依賴(lài)

'android.support.design:28.0.0'

此處添加AppBarLayout作為完整的布局[1]:

AppBarLayout是Android Design Support Library新加的控件繼承自LinearLayout厦滤,
它用來(lái)將Toolbar和TabLayout組合起來(lái)作為一個(gè)整體。

<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" //滑動(dòng)隱藏功能
            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相關(guān)聯(lián)的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
可更改屬性 屬性說(shuō)明
tabBackground TabLayout的背景
tabSelectedTextColor 當(dāng)前標(biāo)簽的字體顏色
tabIndicator

可以寫(xiě)一個(gè)style熟史,下文中會(huì)提到

可更改屬性 屬性說(shuō)明
tabIndicatorColor 選中線的顏色
tabIndicatorHeight 選中線的高度
tabMode
可更改屬性 屬性說(shuō)明
FIXED 不可左右滑動(dòng)馁害,用于標(biāo)簽較少時(shí)
SCROLLABLE 可左右滑動(dòng)窄俏,用于標(biāo)簽較多時(shí)

Fragment

為什么要?jiǎng)?chuàng)建Fragment:TabLayout中的ViewPager對(duì)應(yīng)著相應(yīng)的Fragment蹂匹,所以需要?jiǎng)?chuàng)建。

有的示例僅創(chuàng)建了一個(gè)Fragment凹蜈,其中為定義文字?jǐn)?shù)組實(shí)現(xiàn)限寞,若開(kāi)發(fā)中則需要多個(gè)Fragment添加,均用Arratlist于Activity中仰坦。

XXXFragment.java:

public class XXXFragment extends Fragment {
    
    private Page/View;  //創(chuàng)建變量
 
    @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"; //此處未知含義

參考[2]

//此處的含義可能是新增實(shí)例履植,存儲(chǔ)值?
    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中,原因未知庶近。

關(guān)于添加圖片翁脆,下文有提到。

    private Toolbar toolbar; //增加相關(guān)變量
    private TabLayout tabLayout;
    private ViewPager viewPager;

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

    private List<Fragment> fragments; //定義fragment的集合縮寫(xiě)
    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();
    }

    //各種初始化開(kāi)始

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

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

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

    private void initValue() { 
    //初始化值,添加每一個(gè)TableLayout里的ArrayList叉钥,設(shè)置與標(biāo)題欄一一對(duì)應(yīng)的視圖(片段)集合

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

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

        /*tabIcs = new ArrayList<>(); 此處尚不明確是否有罢缸,使用spanstring或其他方法此處是否需要
        tabIcs.add(R.drawable.tab_xxx);
        tabIcs.add(R.drawable.tab_xxx);*/
        
        //給tabLayout添加選項(xiàng)卡
        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適配器        //此處需要增加與添加的集合以及上述定義的值匹配,若未定義則無(wú)需添加

        viewPager.setAdapter(adapter); //給ViewPager設(shè)置適配器
        tabLayout.setupWithViewPager(viewPager);  //將TabLayout和ViewPager關(guān)聯(lián)起來(lái)      
        /*setupWithViewPager這個(gè)方法會(huì)先將tab清除然后再根據(jù)ViewPager的adapter里的count去取pagetitle投队,這也就是有時(shí)遇到用addTab方法添加tab不起作用的問(wèn)題枫疆。*/

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

此處的setupTabIcons()方法,在下文添加圖片會(huì)提到敷鸦。參考鏈接

默認(rèn)顯示第一個(gè)Tab[3]

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

FragmentPagerAdapter

需要使用Fragment的話就需要這個(gè)適配器

public class一個(gè)自定義的適配器名稱(chēng)繼承自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個(gè)數(shù)) } 
   return xxxfragment.get(position); //普通情況
   return xxxfragment != null ? pagerList.size() : 0; //設(shè)置不等于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)

點(diǎn)擊切換Tab的操作(兩種方式)

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

當(dāng)tab頁(yè)面被選中時(shí),會(huì)調(diào)用這個(gè)方法谎碍,當(dāng)tab頁(yè)面被選中時(shí)鳞滨,切換目前的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]

高級(jí)

在TabLayout中添加圖片

方法

getTabView()[4]

此方法為我首先嘗試使用,可以更改圖標(biāo)顏色以及狀態(tài)蟆淀。

步驟:

  1. 在Activity.java中設(shè)置圖片點(diǎn)擊(使用selector)數(shù)組public int[]
  2. 設(shè)置setupTabIcons();
  3. 創(chuàng)建getTabView()方法

這里[^4 ][2]把此方法放到了FragmentAdapter中拯啦,個(gè)人猜測(cè)原因可能是一同將getTabView()或imagespan使用。

SpannableString

更多支持:介紹參考鏈接[5]

SpannableString這個(gè)類(lèi)實(shí)現(xiàn)了CharSequence這個(gè)接口熔任,所以可以在Adapter中的getPageTitle()中返回褒链。

SpannableString的構(gòu)造方法需要一個(gè)參數(shù):CharSequence(超級(jí)字符串的基本顯示內(nèi)容),

setSpan為核心方法

方法值:

public void setSpan(Object what, int start, int end, int flags) {
    super.setSpan(what, start, end, flags);
          //what:向這個(gè)超級(jí)字符串中添加的內(nèi)容。例如:前景色疑苔、背景色甫匹、圖片、鏈接惦费、下劃線等
          //start:開(kāi)始的位置(0為開(kāi)始)
          //結(jié)束的位置
          //flags:標(biāo)識(shí)在span范圍內(nèi)的文本前后輸入新的字符時(shí)是否也應(yīng)用這個(gè)效果
}

SpanString舉例由于眾多兵迅,表格與文末[6]

經(jīng)搜索:

其中使用ImageSpan的兩種方法薪贫,發(fā)現(xiàn)以下兩種均為僅添加圖標(biāo)方法恍箭,而不適用于點(diǎn)擊切換顏色:

使用SpanString和Imagespan:[2]
  1. 在SimpleFragmentPagerAdapter中設(shè)置數(shù)組int[]
  2. 樣式文件定義
保留字符串并設(shè)置空,添加圖片方法[7]
  1. 修改Adapter的構(gòu)造方法:設(shè)置tabName和tabIcons變量:每個(gè)Tab上的文字和圖標(biāo)的變量
  2. 修改getPageTitle()方法:if-else語(yǔ)句:如果不設(shè)置文字瞧省,則保留一個(gè)字符扯夭,如果設(shè)置圖標(biāo)鳍贾,則使用span
  3. 添加定義style(關(guān)鍵):textAllCaps、android:textAllCaps必須設(shè)置為false交洗,之后XML中TabLayout設(shè)置style贾漏。

SpanString舉例,示例代碼[6],項(xiàng)目完整地址[8].

可更改屬性 屬性說(shuō)明
AbsoluteSizeSpan 單位為物理像素
AlignmentSpan 支持ALIGN_NORMAL藕筋,ALIGN_OPPOSITE纵散,ALIGN_CENTER
BackgroundColorSpan 文字背景色改變
BulletSpan 小圓圈
ClickableSpan 可點(diǎn)擊
DrawableMarginSpan Drawable,不占位
DynamicDrawableSpan DynamicDrawable,占位
ForegroundColorSpan 前景色
IconMarginSpan 圖標(biāo)margin隐圾,不占位
ImageSpan 圖片伍掀,占位
LeadingMarginSpan 控制行前空隙
QuoteSpan 左側(cè)出現(xiàn)引用符號(hào) 豎線
RelativeSizeSpan 字體放大
ScaleXSpan 字體寬度放大
StrikethroughSpan 刪除線
StyleSpan 主要由正常、粗體暇藏、斜體和同時(shí)加粗傾斜四種樣式蜜笤,常量值定義在Typeface類(lèi)中
SubscriptSpan 下標(biāo)
SuperscriptSpan 上標(biāo)
TextAppearanceSpan Sets the text color, size, style, and typeface to match a TextAppearance
TypefaceSpan 字體設(shè)置
UnderlineSpan 下劃線
URLSpan URL


此文優(yōu)先發(fā)布于我的個(gè)人博客:TB+TableLayout+Fragment+VP開(kāi)發(fā)實(shí)踐


  1. Android Design Support Library(一)用TabLayout實(shí)現(xiàn)類(lèi)似網(wǎng)易選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果 ?

  2. android design library提供的TabLayout的用法,很多教程都參考了此文章盐碱。 ? ? ? ?

  3. 利用TabLayout和fragment搭建app框架 ? ? ?

  4. Android TabLayout setCustomView 實(shí)現(xiàn)帶圖標(biāo)的tab ? ?

  5. android設(shè)計(jì)庫(kù)提供的TabLayout的簡(jiǎn)單使用(TabLayout + ViewPager + Fragment) ?

  6. SpannableString ? ?

  7. TabLayout與ViewPager的聯(lián)合使用 ?

  8. onlyloveyd/SpannableDemo ?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末把兔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瓮顽,更是在濱河造成了極大的恐慌县好,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件暖混,死亡現(xiàn)場(chǎng)離奇詭異缕贡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拣播,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén)晾咪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人贮配,你說(shuō)我怎么就攤上這事谍倦。” “怎么了泪勒?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵昼蛀,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我酣藻,道長(zhǎng)曹洽,這世上最難降的妖魔是什么鳍置? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任辽剧,我火速辦了婚禮,結(jié)果婚禮上税产,老公的妹妹穿的比我還像新娘怕轿。我一直安慰自己偷崩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布撞羽。 她就那樣靜靜地躺著阐斜,像睡著了一般。 火紅的嫁衣襯著肌膚如雪诀紊。 梳的紋絲不亂的頭發(fā)上谒出,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音邻奠,去河邊找鬼笤喳。 笑死,一個(gè)胖子當(dāng)著我的面吹牛碌宴,可吹牛的內(nèi)容都是我干的杀狡。 我是一名探鬼主播,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼贰镣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼呜象!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起碑隆,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤恭陡,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后上煤,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體子姜,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年楼入,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了哥捕。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡嘉熊,死狀恐怖遥赚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情阐肤,我是刑警寧澤凫佛,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布,位于F島的核電站孕惜,受9級(jí)特大地震影響愧薛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜衫画,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一毫炉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧削罩,春花似錦瞄勾、人聲如沸费奸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)愿阐。三九已至,卻和暖如春趾疚,著一層夾襖步出監(jiān)牢的瞬間缨历,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工糙麦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留戈二,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓喳资,卻偏偏與公主長(zhǎng)得像觉吭,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子仆邓,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容