介紹過Fragment與ViewPage後,本篇來結合Tablayout。Tablayout可以與ViewPage連動,當ViewPage滑動切換時,Tablayout的標籤也會跟著變動。
這邊提兩個常用的屬性:
app:tabGravity="fill" //填充顯示
app:tabGravity="center" //居中顯示
app:tabMode="fixed" //當Tab較多時壓縮顯示
app:tabMode="scrollable" //當Tab較多超出屏幕邊界時,可以滑動顯示
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="409dp"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentA"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentB"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentC"
/>
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPage"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
建立以下三個Fragment:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentA">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="50dp"
android:text="FragmentA" />
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentB">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="50dp"
android:text="FragmentB" />
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FragmentC">
<!-- TODO: Update blank fragment layout -->
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textSize="50dp"
android:text="FragmentC" />
</FrameLayout>
建立一個class繼承FragmentStateAdapter
public class PageAdapter extends FragmentStateAdapter {
FragmentA fragmentA;
FragmentB fragmentB;
FragmentC fragmentC;
public PageAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
//position當前ViewPage編號
switch (position) {
case 0:
fragmentA = new FragmentA();
return fragmentA;
case 1:
fragmentB = new FragmentB();
return fragmentB;
case 2:
fragmentC = new FragmentC();
return fragmentC;
default:
return null;
}
}
@Override
public int getItemCount() {
return 3;
}
}
viewPager.setAdapter(new PageAdapter(getSupportFragmentManager(),getLifecycle()));
把TabLayout與ViewPager2連動:
new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
viewPager.setCurrentItem(tab.getPosition());
}
}).attach();
基本上做到這邊差不多結束,但attach()會造成Tab文字消失,較簡單的解決方式是直接重新賦值給Tablayout:
private String[] tab_title = {"FragmentA","FragmentB","FragmentC"};
...
for(int i = 0 ; i < tabLayout.getTabCount() ; i++){
tabLayout.getTabAt(i).setText(tab_title[i]);
}
建立style檔案,並加入:
<style name="TabLayoutTextStyle" parent="TextAppearance.Design.Tab">
<item name="android:textAllCaps">false</item>
<item name="textAllCaps">false</item>
</style>
於Tablayout控件中綁定:
app:tabTextAppearance="@style/TabLayoutTextStyle"
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.tabs.TabLayout
android:id="@+id/tabLayout"
android:layout_width="409dp"
app:tabTextAppearance="@style/TabLayoutTextStyle"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentA"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentB"
/>
<com.google.android.material.tabs.TabItem
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="FragmentC"
/>
</com.google.android.material.tabs.TabLayout>
<androidx.viewpager2.widget.ViewPager2
android:id="@+id/viewPage"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/tabLayout" />
</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity {
private TabLayout tabLayout;
private ViewPager2 viewPager;
private String[] tab_title = {"FragmentA","FragmentB","FragmentC"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tabLayout = findViewById(R.id.tabLayout);
viewPager = findViewById(R.id.viewPage);
viewPager.setAdapter(new PageAdapter(getSupportFragmentManager(),getLifecycle()));
new TabLayoutMediator(tabLayout, viewPager, true, new TabLayoutMediator.TabConfigurationStrategy() {
@Override
public void onConfigureTab(@NonNull TabLayout.Tab tab, int position) {
viewPager.setCurrentItem(tab.getPosition());
}
}).attach();
//設定Tab標籤文字
for(int i = 0 ; i < tabLayout.getTabCount() ; i++){
tabLayout.getTabAt(i).setText(tab_title[i]);
}
}
}
public class PageAdapter extends FragmentStateAdapter {
FragmentA fragmentA;
FragmentB fragmentB;
FragmentC fragmentC;
public PageAdapter(@NonNull FragmentManager fragmentManager, @NonNull Lifecycle lifecycle) {
super(fragmentManager, lifecycle);
}
@NonNull
@Override
public Fragment createFragment(int position) {
//position當前ViewPage編號
switch (position) {
case 0:
fragmentA = new FragmentA();
return fragmentA;
case 1:
fragmentB = new FragmentB();
return fragmentB;
case 2:
fragmentC = new FragmentC();
return fragmentC;
default:
return null;
}
}
@Override
public int getItemCount() {
return 3;
}
}