Xamarin Android:如何隐藏ActionBar但不隐藏Tabs布局?
嘿,这个问题我之前也踩过坑!你原来用的是系统ActionBar自带的Tabs,这种方式下Tabs和ActionBar是绑定死的,根本没法单独藏起ActionBar却留着Tabs。要实现需求,得换个思路——用**TabLayout+ViewPager**的组合替代原生ActionBar的Tabs,这样Tabs就是独立的布局组件,和ActionBar彻底解绑,就能轻松隐藏ActionBar啦。
下面是具体的实现步骤,一步步来:
1. 先设置无ActionBar的主题
首先在Resources/values/styles.xml里定义一个无ActionBar的主题,让整个Activity默认不显示ActionBar:
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar"> <!-- 你可以在这里添加其他主题属性,比如颜色、字体等 --> </style>
记得在AndroidManifest.xml里给你的MainActivity指定这个主题,或者在代码里动态设置。
2. 修改布局文件(Main.axml)
把原来依赖ActionBar的布局换成TabLayout+ViewPager的结构,Tabs会放在独立的TabLayout容器里:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <!-- 这就是我们要保留的Tabs容器 --> <com.google.android.material.tabs.TabLayout android:id="@+id/tabLayout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabMode="fixed" app:tabGravity="fill"/> <!-- ViewPager用来切换对应的Fragment页面 --> <androidx.viewpager.widget.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="match_parent"/> </LinearLayout>
3. 修改MainActivity.cs代码
把原来的FragmentActivity换成AppCompatActivity(更推荐,支持Material Design组件),然后初始化TabLayout和ViewPager的关联:
using Android.App; using Android.OS; using AndroidX.AppCompat.App; using Google.Android.Material.Tabs; using AndroidX.ViewPager.Widget; using AndroidX.Fragment.App; public class MainActivity : AppCompatActivity { protected override void OnCreate(Bundle savedInstanceState) { base.OnCreate(savedInstanceState); // 应用无ActionBar主题(如果已经在Manifest里设置过,这行可省略) SetTheme(Resource.Style.AppTheme); SetContentView(Resource.Layout.Main); // 定义Tabs的标题文本 string[] allTabs = { "First Tab", "Second Tab" }; // 获取布局中的TabLayout和ViewPager实例 var tabLayout = FindViewById<TabLayout>(Resource.Id.tabLayout); var pager = FindViewById<ViewPager>(Resource.Id.pager); // 给ViewPager设置自定义适配器 pager.Adapter = new MyPagerAdapter(SupportFragmentManager, allTabs); // 绑定TabLayout和ViewPager,实现点击Tabs切换页面、滑动页面同步Tabs状态 tabLayout.SetupWithViewPager(pager); } } // 自定义Pager适配器,管理Fragment和Tab标题 public class MyPagerAdapter : FragmentPagerAdapter { private readonly string[] _tabTitles; public MyPagerAdapter(FragmentManager fm, string[] tabTitles) : base(fm, BehaviorResumeOnlyCurrentFragment) { _tabTitles = tabTitles; } // 返回Fragment的总数量 public override int Count => _tabTitles.Length; // 根据位置返回对应的Fragment public override AndroidX.Fragment.App.Fragment GetItem(int position) { // 这里替换成你自己的业务Fragment,也可以根据position返回不同Fragment return new MySampleFragment(); } // 返回对应Tab的标题文本 public override Java.Lang.ICharSequence GetPageTitleFormatted(int position) { return new Java.Lang.String(_tabTitles[position]); } } // 示例Fragment,替换成你自己的Fragment即可 public class MySampleFragment : AndroidX.Fragment.App.Fragment { public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // 加载你的Fragment布局文件 return inflater.Inflate(Resource.Layout.SampleFragmentLayout, container, false); } }
为什么原来的方法不行?
你之前用的ActionBar.NavigationMode = ActionBarNavigationMode.Tabs是把Tabs嵌入在ActionBar内部的,ActionBar是Tabs的父容器,所以一旦隐藏ActionBar(比如调用ActionBar.Hide()或用无ActionBar主题),Tabs必然会跟着消失。而TabLayout是独立的Material Design组件,完全脱离了ActionBar的约束,自然能实现“藏ActionBar留Tabs”的需求。
如果你的项目必须使用FragmentActivity而非AppCompatActivity,只需要换成Support库的TabLayout和ViewPager,主题改用Theme.AppCompat.Light.NoActionBar,代码里的FragmentManager换成SupportFragmentManager就可以啦。
内容的提问来源于stack exchange,提问作者Fatihi Youssef

