【问题标题】:Scrollview control not working properly in .Net MAUI (Android)滚动视图控件在 .Net MAUI (Android) 中无法正常工作
【发布时间】:2022-06-30 00:03:33
【问题描述】:

我已经使用 ScrollView 控件和 Bindable StackLayout 控件创建了自定义选项卡控件。

我首先在 Xamarin.Forms(VS for Mac 2019)中创建了这个解决方案,它在两个平台上都可以正常工作,但是在 .Net MAUI(VS for Mac 2022 Prev)中开发的相同解决方案在 Android 中无法正常工作.

这是我到目前为止所做的:

MainPage.xaml

<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:vm="clr-namespace:poc_maui.ViewModels"
             x:Class="poc_maui.Views.HomePage"
             xmlns:tabs="clr-namespace:poc_maui.Views.SubViews"
             Title="HomePage">

    <ContentPage.BindingContext>
        <vm:MainPageViewModel />
    </ContentPage.BindingContext>

    <Grid RowDefinitions="50, *" RowSpacing="0">
        <ScrollView Grid.Row="0" Orientation="Horizontal" VerticalOptions="Start" HorizontalScrollBarVisibility="Never"
                    Scrolled="ScrollView_Scrolled">
            <StackLayout x:Name="TabsView"
                        Orientation="Horizontal"
                        BindableLayout.ItemsSource="{Binding Tabs}" Spacing="0">
                <BindableLayout.ItemTemplate>
                    <DataTemplate>
                        <Grid RowDefinitions="*, 4" RowSpacing="0">
                            <Label Grid.Row="0"
                                   Text="{Binding TabTitle}"
                                   TextColor="White"
                                   BackgroundColor="navy"
                                   Padding="20,0"
                                   VerticalTextAlignment="Center"
                                   HorizontalTextAlignment="Center"
                                   FontSize="12"
                                   HeightRequest="40"/>
                            <BoxView Grid.Row="1"
                                     Color="Yellow"
                                     IsVisible="{Binding IsSelected}"/>

                            <Grid.GestureRecognizers>
                                <TapGestureRecognizer Command="{Binding Path=BindingContext.TabChangedCommand,
                                                                        Source={x:Reference TabsView}}"
                                                      CommandParameter="{Binding .}"/>
                            </Grid.GestureRecognizers>
                        </Grid>

                    </DataTemplate>
                </BindableLayout.ItemTemplate>
            </StackLayout>

        </ScrollView>

        <tabs:ParentRecordTabView Grid.Row="1" IsVisible="{Binding IsParentRecordTabVisible}"
                                          VerticalOptions="FillAndExpand"/>
        <tabs:AdditionalInfoTabView Grid.Row="1" IsVisible="{Binding IsAdditionalInfoTabVisible}"
                                            VerticalOptions="FillAndExpand" />
    </Grid>

</ContentPage>

MainPageViewModel

using System;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows.Input;
using poc_maui.Models;

namespace poc_maui.ViewModels
{
    public class MainPageViewModel : BaseViewModel
    {
        #region Constructor
        public MainPageViewModel()
        {
            GetTabs();
        }

        #endregion

        #region Private Properties

        private bool _isParentRecordTabVisible = true;
        private bool _isAdditionalInfoTabVisible;

        private ObservableCollection<TabViewModel> _tabs { get; set; }
        
        #endregion

        #region Public Properties

        public bool IsParentRecordTabVisible
        {
            get => _isParentRecordTabVisible;
            set { _isParentRecordTabVisible = value; OnPropertyChanged(nameof(IsParentRecordTabVisible)); }
        }

        public bool IsAdditionalInfoTabVisible
        {
            get => _isAdditionalInfoTabVisible;
            set { _isAdditionalInfoTabVisible = value; OnPropertyChanged(nameof(IsAdditionalInfoTabVisible)); }
        }

        public ObservableCollection<TabViewModel> Tabs
        {
            get => _tabs;
            set { _tabs = value; OnPropertyChanged(nameof(Tabs)); }
        }

        #endregion

        #region Commands

        public ICommand TabChangedCommand { get { return new Command<TabViewModel>(ChangeTabClick); } }

        #endregion

        #region Private Methods

        private void GetTabs()
        {
            Tabs = new ObservableCollection<TabViewModel>();
            Tabs.Add(new TabViewModel { TabId = 1, IsSelected = true, TabTitle = "Parent record" });
            Tabs.Add(new TabViewModel { TabId = 2, TabTitle = "Additional Info" });
            Tabs.Add(new TabViewModel { TabId = 3, TabTitle = "Contacts" });
            Tabs.Add(new TabViewModel { TabId = 4, TabTitle = "Previous inspections" });
            Tabs.Add(new TabViewModel { TabId = 5, TabTitle = "Attachments" });

            SelectedTab = Tabs.FirstOrDefault();
        }

        private void ChangeTabClick(TabViewModel tab)
        {
            try
            {
                var tabs = new ObservableCollection<TabViewModel>(Tabs);

                foreach (var item in tabs)
                {
                    if (item.TabId == tab.TabId)
                    {
                        item.IsSelected = true;
                    }
                    else
                    {
                        item.IsSelected = false;
                    }
                }

                Tabs.Clear();
                Tabs = new ObservableCollection<TabViewModel>(tabs);

                switch (tab.TabId)
                {
                    case 1:
                        IsParentRecordTabVisible = true;
                        IsAdditionalInfoTabVisible = false;
                        break;
                    case 2:
                        IsParentRecordTabVisible = false;
                        IsAdditionalInfoTabVisible = true;
                        break;
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        #endregion
    }
}

#ParentTabView.xaml

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="poc_maui.Views.SubViews.ParentTabView">
    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" >
        <Label 
            Text="Welcome to Parent tab!"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </StackLayout>
</ContentView>


#AdditionalInfoTabView.xaml

<ContentView xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="poc_maui.Views.SubViews.AdditionalInfoTabView">
    <StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand" >
        <Label 
            Text="Welcome to Additiona info tab!"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />
    </StackLayout>
</ContentView>

所以在 Android 中发生的情况是,当我单击 AdditionalInfo 选项卡时,它会显示一个空白的白色屏幕,如果您按下硬件后退按钮并再次打开应用程序,它将显示 AdditionalTab 已被选中,并且它的视图内容也会显示.

如果我从 ViewModel 中删除 switch() 代码部分,它会正常工作,但选项卡不会改变。有人知道 MAUI 中滚动视图的这种行为吗?

完整的源代码在这里:maui_sample

【问题讨论】:

  • 这可能是两个选项卡通用的 ScrollView 的问题,您是否尝试将其保留在选项卡内容视图中?
  • 不,滚动视图对于两个选项卡都不常见,如果您检查代码就会明白。同样的事情在 iOS 中运行良好,所以这很奇怪吧?
  • 快速提问,如果你只有两个选项卡,为什么需要那个 ScrollView?另外,我猜问题是您的可绑定布局不确定谁应该响应 android 上的调用,我建议您将事件放在布局级别并让您的孩子将 InputTransparent 视为 true
  • 不明白你的意思,但它不仅仅是两个标签,还有五个标签。我只对 2 个标签进行了隐藏/显示。如果您可以下载代码并运行,您将能够看到有 5 个选项卡。

标签: c# xamarin xamarin.forms maui .net-maui


【解决方案1】:

这个变通办法能解决它吗?

MainPage.xaml:

<ScrollView x:Name "theScrollView" ... >

MainPage.xaml.cs:

public MainPage()
{
    InitializeComponent();

    MessagingCenter.Subscribe<MainPageViewModel>(this, "update", (sender) =>
    {
        // Tell theScrollView to re-layout its contents.
        (theScrollView as IView).InvalidateArrange();
    });
}    

MainPageViewModel:

private void ChangeTabClick(TabViewModel tab)
{
    ... make changes ...

    MessagingCenter.Send<MainPageViewModel>(this, "update");
}

【讨论】:

    猜你喜欢
    • 2022-07-04
    • 1970-01-01
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    • 2022-12-11
    相关资源
    最近更新 更多