研究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的操作(兩種方式)
- .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) {
- 使用selector代替[4]
高級(jí)
在TabLayout中添加圖片
方法
getTabView()[4]
此方法為我首先嘗試使用,可以更改圖標(biāo)顏色以及狀態(tài)蟆淀。
步驟:
- 在Activity.java中設(shè)置圖片點(diǎn)擊(使用selector)數(shù)組public int[]
- 設(shè)置setupTabIcons();
- 創(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]
- 在SimpleFragmentPagerAdapter中設(shè)置數(shù)組int[]
- 樣式文件定義
保留字符串并設(shè)置空,添加圖片方法[7]
- 修改Adapter的構(gòu)造方法:設(shè)置tabName和tabIcons變量:每個(gè)Tab上的文字和圖標(biāo)的變量
- 修改getPageTitle()方法:if-else語(yǔ)句:如果不設(shè)置文字瞧省,則保留一個(gè)字符扯夭,如果設(shè)置圖標(biāo)鳍贾,則使用span
- 添加定義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í)踐
-
Android Design Support Library(一)用TabLayout實(shí)現(xiàn)類(lèi)似網(wǎng)易選項(xiàng)卡動(dòng)態(tài)滑動(dòng)效果 ?
-
android design library提供的TabLayout的用法,很多教程都參考了此文章盐碱。 ? ? ? ?
-
Android TabLayout setCustomView 實(shí)現(xiàn)帶圖標(biāo)的tab ? ?
-
android設(shè)計(jì)庫(kù)提供的TabLayout的簡(jiǎn)單使用(TabLayout + ViewPager + Fragment) ?