Search code examples
androidxamarinxamarin.formsswipeuisegmentedcontrol

Route the swipe action inside segmentcontrol of a child page of tabbedpage


So I'm using Xamarin forms for a cross platform app, the main UI is a tabbed page, and one of the page has a segmented control in it, the segment control will switches the data of a list view control. The problem is when I swipe the screen, it switches between the different child pages of the tabbed page, but I'd like it to switch between the segment control inside the child page. Is there anyway I can let swipe not work with tabbed page, but the inner segment control?

XAML for tabbed page:

<?xml version="1.0" encoding="utf-8" ?>
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
        xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
        xmlns:local="clr-namespace:MainApp"
        x:Class="MainApp.MainPage">
  <!--Pages can be added as references or inline-->
    <local:NewsPage Title="News" Icon="icon.png"/>
    <ContentPage Title="Guides" Icon="icon.png"/>
    <ContentPage Title="Wallets" Icon="icon.png"/>
    <ContentPage Title="Me" Icon="icon.png"/>
</TabbedPage>

News page:

<controls:SegmentedControl x:Name="SegControl" TintColor="#007AFF" SelectedSegment="0"
                                       VerticalOptions="Center"
                                       Grid.Column="1" ValueChanged="SegControl_ValueChanged">
    <controls:SegmentedControl.Children>
        <controls:SegmentedControlOption Text="Type1" />
        <controls:SegmentedControlOption Text="Type2" />
    </controls:SegmentedControl.Children>
</controls:SegmentedControl>
<ListView ItemsSource="{Binding Source={StaticResource SArray}}" Grid.Row="1" Grid.Column="0" RowHeight="85">
 <ListView.ItemTemplate> ... </ListView>

effect


Solution

  • I take it this is on Android? I'm not sure is swiping works on iOS.

    One option is to disable swiping on the tab pages.

    You can do this using a custom renderer.

    [assembly: ExportRenderer(typeof(CustomTabbedPage), typeof(CustomTabbedPageRenderer))]
    namespace App1.Droid
    {
        public class CustomTabbedPageRenderer : TabbedPageRenderer
        {
    
            protected override void OnElementChanged(ElementChangedEventArgs<TabbedPage> e)
            {
    
                var info = typeof(TabbedPageRenderer).GetTypeInfo();
                var fieldInfo = info.GetField("_useAnimations", BindingFlags.Instance | BindingFlags.NonPublic);
                fieldInfo.SetValue(this, false);
                base.OnElementChanged(e);
            }
        }
    }
    

    EDIT

    Looks like this has been added to Xamarin Forms now:

    https://github.com/xamarin/Xamarin.Forms/pull/409

    ANOTHER EDIT

    And another way. I'm learning lots today!

    public partial class MainPage : Xamarin.Forms.TabbedPage
    {
        public MainPage()
        {
            InitializeComponent();
    
            this.On<Xamarin.Forms.PlatformConfiguration.Android>().SetIsSwipePagingEnabled(false);
        }
    }
    

    I'M ON A ROLL

    From XAML

    <TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
            xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
            xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
            android:TabbedPage.IsSwipePagingEnabled="False"