You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中MainActivity的OnCreate获取Toolbar返回null问题求助

解决Xamarin.Forms中MainActivity里FindViewById返回null的问题

兄弟,我太懂刚接触Xamarin踩坑的感觉了!你遇到的这个FindViewById返回null的问题,核心原因是Xamarin.Forms的界面接管机制:

当你在OnCreate里调用LoadApplication(new App(...))之后,Xamarin.Forms会完全替换掉MainActivity的原生ContentView,把它改成Forms自己的容器视图。你之前通过ToolbarResource = Resource.Layout.Toolbar设置的工具栏,已经被整合到Forms的页面层级里了,不在Activity的原生视图树里,所以直接用FindViewById肯定找不到。

下面给你两种靠谱的解决方案,按需选择:

方法一:优先用Xamarin.Forms原生API操作工具栏

如果你的需求只是自定义工具栏样式、标题或者添加按钮,强烈推荐用Forms的跨平台API来实现,这样不用碰原生代码,还能保证多平台一致:

  • 要替换标题栏内容:在ContentPage里用NavigationPage.SetTitleView(this, 你的自定义视图)
  • 要修改全局样式:在App.xaml里定义NavigationPage的样式,比如设置背景色、字体等
  • 要添加工具栏按钮:在ContentPage的ToolbarItems集合里添加即可

方法二:一定要在MainActivity里操作原生Toolbar?试试这两个方案

如果必须要操作原生的Toolbar控件,有两种可行的思路:

方案1:调整代码顺序,在LoadApplication前获取

因为LoadApplication才会替换ContentView,所以你可以把获取Toolbar的代码放到LoadApplication之前,这样此时Activity的视图还是原生的Toolbar布局:

protected override void OnCreate(Bundle bundle)
{
    TabLayoutResource = Resource.Layout.Tabbar;
    ToolbarResource = Resource.Layout.Toolbar;

    base.OnCreate(bundle);

    // 重点:在初始化Forms和加载应用前获取Toolbar
    Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
    if (toolbar != null)
    {
        // 在这里做你的自定义操作,比如改标题、加按钮
        toolbar.Title = "我的自定义标题";
        toolbar.SetSubtitleTextColor(Android.Graphics.Color.Gray);
    }

    Xamarin.Forms.Forms.Init(this, bundle);
    LoadApplication(new App(new AndroidInitializer()));
}

注意:这种方式下,后续Forms可能会覆盖你对Toolbar的部分设置,所以如果需要持久化的自定义,还是推荐用渲染器方案。

方案2:用自定义渲染器获取Forms中的原生Toolbar

如果你的Toolbar是Forms的NavigationBar对应的原生控件,通过自定义渲染器可以精准拿到它:

  1. 先在共享项目里创建一个自定义ContentPage:
public class CustomContentPage : ContentPage
{
    // 定义事件,通知原生Toolbar已就绪
    public event EventHandler<Android.Support.V7.Widget.Toolbar> NativeToolbarReady;

    internal void RaiseToolbarReady(Android.Support.V7.Widget.Toolbar toolbar)
    {
        NativeToolbarReady?.Invoke(this, toolbar);
    }
}
  1. 在Android项目里写对应的渲染器:
[assembly: ExportRenderer(typeof(CustomContentPage), typeof(CustomContentPageRenderer))]
namespace YourAppName.Droid.Renderers
{
    public class CustomContentPageRenderer : PageRenderer
    {
        protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
        {
            base.OnElementChanged(e);

            if (e.NewElement is CustomContentPage customPage)
            {
                // 从MainActivity中获取原生Toolbar
                var toolbar = ((MainActivity)Context).FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
                if (toolbar != null)
                {
                    customPage.RaiseToolbarReady(toolbar);
                }
            }
        }
    }
}
  1. 最后在共享项目的页面里订阅事件,操作Toolbar:
public partial class MainPage : CustomContentPage
{
    public MainPage()
    {
        InitializeComponent();
        NativeToolbarReady += MainPage_NativeToolbarReady;
    }

    private void MainPage_NativeToolbarReady(object sender, Android.Support.V7.Widget.Toolbar e)
    {
        // 在这里对原生Toolbar做你需要的操作
        e.Subtitle = "这是原生副标题";
        e.MenuItemClick += (s, args) => 
        {
            // 处理菜单点击事件
        };
    }
}

最后再提醒一句:除非是平台特有的高级自定义,否则尽量用Forms的API来做界面操作,这样能减少跨平台适配的麻烦~

内容的提问来源于stack exchange,提问作者Mattias Greger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 04:11:46