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

如何在Xamarin Forms中创建带左右滑动动画的简易工具栏

实现Xamarin.Forms可左右滑动的顶部工具栏

嗨,作为有iOS原生开发背景的Xamarin.Forms新手,你提到的可左右滑动的工具栏需求,原生的ToolbarItems确实满足不了——因为它在iOS和Android上的原生实现都是固定布局,不支持横向滑动。不过我们可以自定义一个顶部的滑动栏来实现这个效果,下面给你两种实用的方案:

方案一:基础滑动工具栏(切换内容)

这个方案用ScrollView包裹HorizontalStackLayout来实现横向滑动,搭配点击事件切换主内容,完全兼容iOS和Android。

XAML代码

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ToolBarDemo.Views.CustomToolBar">
    
    <Grid>
        <!-- 顶部可滑动工具栏 -->
        <ScrollView Orientation="Horizontal" 
                    BackgroundColor="#f8f8f8"
                    Padding="10,5">
            <HorizontalStackLayout Spacing="20">
                <Label Text="ONE" 
                       FontSize="16" 
                       TextColor="#333"
                       Padding="10,5"
                       x:Name="OneLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="ONE"/>
                </Label>
                <Label Text="TWO" 
                       FontSize="16" 
                       TextColor="#333"
                       Padding="10,5"
                       x:Name="TwoLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="TWO"/>
                </Label>
                <Label Text="THREE" 
                       FontSize="16" 
                       TextColor="#333"
                       Padding="10,5"
                       x:Name="ThreeLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="THREE"/>
                </Label>
                <!-- 可添加更多选项 -->
                <Label Text="FOUR" 
                       FontSize="16" 
                       TextColor="#333"
                       Padding="10,5">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="FOUR"/>
                </Label>
            </HorizontalStackLayout>
        </ScrollView>

        <!-- 主内容区域 -->
        <Frame Margin="0,60,0,0" Padding="10">
            <Label x:Name="ContentLabel" Text="当前选中:ONE" FontSize="18"/>
        </Frame>
    </Grid>
</ContentPage>

后台C#代码

using Xamarin.Forms;

namespace ToolBarDemo.Views
{
    public partial class CustomToolBar : ContentPage
    {
        public CustomToolBar()
        {
            InitializeComponent();
            // 默认选中第一个选项
            UpdateSelectedStyle(OneLabel);
        }

        private void OnToolbarItemTapped(object sender, EventArgs e)
        {
            if (sender is Label tappedLabel && e is TappedEventArgs tappedArgs)
            {
                var selectedItem = tappedArgs.Parameter as string;
                
                // 重置所有选项的样式
                ResetAllLabelStyles();
                // 设置当前选中项的高亮样式
                UpdateSelectedStyle(tappedLabel);
                
                // 更新主内容显示
                ContentLabel.Text = $"当前选中:{selectedItem}";
            }
        }

        private void ResetAllLabelStyles()
        {
            // 统一重置所有标签的样式
            foreach (var child in (ToolbarStack.Parent as ScrollView).Content as HorizontalStackLayout)
            {
                if (child is Label label)
                {
                    label.TextColor = Color.FromHex("#333");
                    label.FontAttributes = FontAttributes.None;
                    label.BackgroundColor = Color.Transparent;
                }
            }
        }

        private void UpdateSelectedStyle(Label label)
        {
            // 设置选中项的高亮样式(可根据需求调整)
            label.TextColor = Color.FromHex("#007AFF");
            label.FontAttributes = FontAttributes.Bold;
            label.BackgroundColor = Color.FromHex("#E5F2FF");
        }
    }
}

方案二:联动内容轮播的滑动工具栏

如果需要点击工具栏选项时切换整个页面内容,可以搭配CarouselView实现工具栏和内容区的联动,体验更流畅。

XAML代码

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ToolBarDemo.Views.CarouselToolBarPage">
    
    <Grid>
        <!-- 顶部滑动工具栏 -->
        <ScrollView Orientation="Horizontal" 
                    BackgroundColor="#f8f8f8"
                    Padding="10,5">
            <HorizontalStackLayout Spacing="20" x:Name="ToolbarStack">
                <Label Text="ONE" FontSize="16" Padding="10,5" x:Name="OneLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="0"/>
                </Label>
                <Label Text="TWO" FontSize="16" Padding="10,5" x:Name="TwoLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="1"/>
                </Label>
                <Label Text="THREE" FontSize="16" Padding="10,5" x:Name="ThreeLabel">
                    <TapGestureRecognizer Tapped="OnToolbarItemTapped" CommandParameter="2"/>
                </Label>
            </HorizontalStackLayout>
        </ScrollView>

        <!-- 内容轮播区域 -->
        <CarouselView x:Name="ContentCarousel" 
                      Margin="0,60,0,0"
                      CurrentItemChanged="OnCarouselCurrentItemChanged">
            <CarouselView.ItemsSource>
                <x:Array Type="{x:Type ContentView}">
                    <ContentView>
                        <Label Text="ONE页面专属内容" FontSize="20" HorizontalOptions="Center" VerticalOptions="Center"/>
                    </ContentView>
                    <ContentView>
                        <Label Text="TWO页面专属内容" FontSize="20" HorizontalOptions="Center" VerticalOptions="Center"/>
                    </ContentView>
                    <ContentView>
                        <Label Text="THREE页面专属内容" FontSize="20" HorizontalOptions="Center" VerticalOptions="Center"/>
                    </ContentView>
                </x:Array>
            </CarouselView.ItemsSource>
        </CarouselView>
    </Grid>
</ContentPage>

后台C#代码

using Xamarin.Forms;

namespace ToolBarDemo.Views
{
    public partial class CarouselToolBarPage : ContentPage
    {
        public CarouselToolBarPage()
        {
            InitializeComponent();
            // 默认选中第一个选项
            UpdateSelectedToolbarItem(0);
        }

        private void OnToolbarItemTapped(object sender, EventArgs e)
        {
            if (e is TappedEventArgs tappedArgs && int.TryParse(tappedArgs.Parameter.ToString(), out int index))
            {
                // 切换轮播内容到对应索引
                ContentCarousel.ScrollTo(index, position: ScrollToPosition.Center, animate: true);
            }
        }

        private void OnCarouselCurrentItemChanged(object sender, CurrentItemChangedEventArgs e)
        {
            // 当轮播内容切换时,同步更新工具栏选中状态
            var currentIndex = ContentCarousel.ItemsSource.IndexOf(e.CurrentItem);
            UpdateSelectedToolbarItem(currentIndex);
        }

        private void UpdateSelectedToolbarItem(int index)
        {
            ResetAllLabelStyles();
            // 根据索引设置对应标签的高亮样式
            switch(index)
            {
                case 0:
                    UpdateSelectedStyle(OneLabel);
                    break;
                case 1:
                    UpdateSelectedStyle(TwoLabel);
                    break;
                case 2:
                    UpdateSelectedStyle(ThreeLabel);
                    break;
            }
        }

        private void ResetAllLabelStyles()
        {
            OneLabel.TextColor = Color.FromHex("#333");
            OneLabel.FontAttributes = FontAttributes.None;
            OneLabel.BackgroundColor = Color.Transparent;

            TwoLabel.TextColor = Color.FromHex("#333");
            TwoLabel.FontAttributes = FontAttributes.None;
            TwoLabel.BackgroundColor = Color.Transparent;

            ThreeLabel.TextColor = Color.FromHex("#333");
            ThreeLabel.FontAttributes = FontAttributes.None;
            ThreeLabel.BackgroundColor = Color.Transparent;
        }

        private void UpdateSelectedStyle(Label label)
        {
            label.TextColor = Color.FromHex("#007AFF");
            label.FontAttributes = FontAttributes.Bold;
            label.BackgroundColor = Color.FromHex("#E5F2FF");
        }
    }
}

额外优化建议

  • 如果想让自定义工具栏和原生导航栏融合,可以设置NavigationPage.HasNavigationBar="False",然后把滑动工具栏放在页面最顶部,模拟原生导航栏的视觉效果。
  • 样式可以完全自定义,比如添加底部下划线、调整圆角等,适配你的App设计风格。
  • 选项较多时,ScrollView会自动在iOS和Android上启用横向滑动,无需额外处理平台差异。

内容的提问来源于stack exchange,提问作者Srikanth venigalla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:51:19