TabLayout是 Android 中用來建立標籤式介面(分頁)的 UI 元件,通常和 ViewPager2 搭配使用,讓使用者可以在多個頁面之間滑動切換。
元件 | 說明 |
---|---|
TabLayout |
提供上方的分頁(tabs)按鈕。 |
ViewPager2 |
管理每個分頁要顯示的內容(Fragment)。 |
TabLayoutMediator |
將 TabLayout 和 ViewPager2 綁定。 |
tabGravity
center
:所有 TabItem 會集中排列在 TabLayout 的中間。fill
:TabItem 會平均分配整個 TabLayout 的寬度。tabIndicatorColor
tabIndicatorFullWidth
true
:底線會完全填滿 TabItem 寬度。false
:底線會依據內容文字寬度顯示。tabMaxWidth
tabMode
fixed
:所有 TabItem 都塞進 TabLayout(預設),若空間不夠會壓縮每個 Tab。scrollable
:TabItem 太多時可以橫向滑動,多出來的 Tab 就用滑動檢視。tabSelectedTextColor
tabTextColor
tabBackground
tabIndicatorHeight
首先要在build.gradle (Module app)中加入下列這一行:implementation'com.google.android.material:material:1.11.0'
版面配置,記得放入TabLayout和ViewPager2
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tab"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Monday" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Tuesday" />
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Wednesday" />
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
最上面記得加,否則會報錯
import androidx.viewpager2.widget.ViewPager2;
import com.google.android.material.tabs.TabLayout;
import com.google.android.material.tabs.TabLayoutMediator;
在MainActivity中宣告
private ViewPager2 viewPager;
private TabLayout tab;
private FragmentViewPagerAdapter adapter;
建立一個 FragmentViewPagerAdapter 實例,並將當前的 Activity(用 this 表示)傳入建構子
之後這個 adapter 會被用來設定給 ViewPager2,以實現分頁切換功能。
另外,ViewPager2 預設就是從第 0 頁開始,所以如果沒有特別需求,最後一行可以省略,此處寫出來只是為了告知可從這行設定。
adapter = new FragmentViewPagerAdapter(this);
viewPager.setAdapter(adapter);// 設定 ViewPager 的 adapter
viewPager.setCurrentItem(0);// 設定一開始顯示第0頁
因為我的有三個,所以創了FragmentA FragmentB和FragmentC
new TabLayoutMediator(tab, viewPager, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
//Tab顯示的字
if (position == 0) tab.setText("首頁");
if (position == 1) tab.setText("最新消息");
if (position == 2) tab.setText("介紹");
}
}).attach();
點擊事件
ps.如要使用Toast請記得在最上方加入import android.widget.Toast;
tab.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
//Tab被選中時 發出提示訊息
Toast.makeText(MainActivity.this, tab.getText(), Toast.LENGTH_SHORT).show();
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
// Tab取消選中時
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
// Tab被再次選中時
}
});
這頁是我們自訂的ViewPager2 的 Fragment 適配器,用來讓 App 可以滑動切換不同頁面,可以看程式碼內的備註了解每行意思
public class FragmentViewPagerAdapter extends FragmentStateAdapter {
//初始化
public FragmentViewPagerAdapter(@NonNull FragmentActivity fragmentActivity) {
super(fragmentActivity);
}
@NonNull
@Override
public Fragment createFragment(int position) {
//0表示最左邊的Tab 當我們滑動或點擊時就會顯示FragmentA
if (position == 0){
return new FragmentA();
}
//中間/第二個Tab
else if (position == 1){
return new FragmentB();
}
else {
//最後一個 因為只有3個所以直接寫else就好了
return new FragmentC();
}
}
@Override
//代表這個 ViewPager 一共有 3 頁(對應 3 個 Fragment)。
public int getItemCount() {
return 3;
}
}
每頁自然是可以單獨做版面設計,但是用到的語法可能會不太一樣,像我的是單獨放一張圖片作展示
Fragment 必須要有一個公開無參數的建構子,否則系統在重建 Fragment 時會報錯
public class FragmentA extends Fragment {
public FragmentA() {
// 必須的空建構子
}
private ImageView imageView;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater,
@Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
// 膨脹 fragment 的佈局檔,並存成 view
//R.layout.activity_fragmenta 是這個 Fragment 使用的 XML 佈局。
//用 inflater 把 XML 轉成 Java 中的 View 物件。
View view = inflater.inflate(R.layout.activity_fragmenta, container, false);
// 用 view.findViewById() 找出元件
imageView = view.findViewById(R.id.imageView);
// 回傳 view
return view;
}
}
成果展示:
在 Android 中,我們設計畫面通常會先寫好 XML 檔,但這只是一段靜態的 XML 檔,還不是程式中可操作的畫面元件。
當你在程式中執行這段:
View view = inflater.inflate(R.layout.activity_fragmenta, container, false);
就代表你在把 XML 畫面檔「膨脹」(inflate)成 Java 中可以操作的 View 物件。也就是把activity_fragmenta.xml → 轉換 → View 物件(Java 裡可以 .findViewById() 的)
而在綁定元件時必須寫成view.findViewById(R.id.imageView),也就是要在前面多加一個view. ,其他的都跟平時寫程式沒有差別,寫完後記得要return view,不然畫面不會顯示喔