浏览代码

Renamed MobileList to MobileCollectionView and added MobileListView to work around Android CollectionView Issues

Frank van den Bos 1 年之前
父节点
当前提交
48fab68aeb

+ 2 - 2
InABox.Mobile/InABox.Mobile.Shared/Components/MobileList/MobileList.xaml → InABox.Mobile/InABox.Mobile.Shared/Components/MobileCollectionView/MobileCollectionView.xaml

@@ -6,9 +6,9 @@
     xmlns:ui="clr-namespace:XF.Material.Forms.UI;assembly=XF.Material"
     xmlns:local="clr-namespace:InABox.Mobile"
     xmlns:system="clr-namespace:System;assembly=netstandard"
-    x:Class="InABox.Mobile.MobileList"
+    x:Class="InABox.Mobile.MobileCollectionView"
     BackgroundColor="Transparent"
-    x:DataType="local:MobileList">
+    x:DataType="local:MobileCollectionView">
     <ContentView.Content>
         <Grid>
             <Grid.RowDefinitions>

+ 6 - 6
InABox.Mobile/InABox.Mobile.Shared/Components/MobileList/MobileList.xaml.cs → InABox.Mobile/InABox.Mobile.Shared/Components/MobileCollectionView/MobileCollectionView.xaml.cs

@@ -15,13 +15,13 @@ namespace InABox.Mobile
     public delegate void MobileListRefreshEvent(object sender, MobileListRefreshEventArgs args);
     
     [XamlCompilation(XamlCompilationOptions.Compile)]
-    public partial class MobileList
+    public partial class MobileCollectionView
     {
         
         public static readonly BindableProperty PullToRefreshProperty = BindableProperty.Create(
             nameof(PullToRefresh), 
             typeof(bool), 
-            typeof(MobileList),
+            typeof(MobileCollectionView),
             false);
 
         public bool PullToRefresh
@@ -59,7 +59,7 @@ namespace InABox.Mobile
         public static readonly BindableProperty LastUpdatedProperty = BindableProperty.Create(
             nameof(LastUpdated), 
             typeof(DateTime), 
-            typeof(MobileList));
+            typeof(MobileCollectionView));
         
         public DateTime LastUpdated
         {
@@ -74,7 +74,7 @@ namespace InABox.Mobile
         public static readonly BindableProperty ShowRecordCountProperty = BindableProperty.Create(
             nameof(ShowRecordCount), 
             typeof(bool), 
-            typeof(MobileList), 
+            typeof(MobileCollectionView), 
             false);
 
         public bool ShowRecordCount
@@ -90,7 +90,7 @@ namespace InABox.Mobile
         public static readonly BindableProperty EmptyTextProperty = BindableProperty.Create(
             nameof(EmptyText), 
             typeof(string), 
-            typeof(MobileList), 
+            typeof(MobileCollectionView), 
             "No Data Available");
 
         public string EmptyText
@@ -157,7 +157,7 @@ namespace InABox.Mobile
         
         public event MobileListRefreshEvent RefreshRequested;
 
-        public MobileList()
+        public MobileCollectionView()
         {
             InitializeComponent();
             _refresher.Command = new Command(DoRefresh);

+ 87 - 0
InABox.Mobile/InABox.Mobile.Shared/Components/MobileListView/MobileListView.xaml

@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<ContentView
+    xmlns="http://xamarin.com/schemas/2014/forms"
+    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+    xmlns:ui="clr-namespace:XF.Material.Forms.UI;assembly=XF.Material"
+    xmlns:local="clr-namespace:InABox.Mobile"
+    xmlns:system="clr-namespace:System;assembly=netstandard"
+    x:Class="InABox.Mobile.MobileListView"
+    BackgroundColor="Transparent"
+    x:DataType="local:MobileCollectionView">
+    <ContentView.Content>
+        <Grid>
+            <Grid.RowDefinitions>
+                <RowDefinition Height="*"/>
+                <RowDefinition Height="Auto"/>
+            </Grid.RowDefinitions>
+            <RefreshView 
+                x:Name="_refresher"
+                BackgroundColor="Transparent"
+                Grid.Row="0"
+                IsEnabled="False">
+
+                <!-- ItemSizingStrategy="{Binding HasUnevenRows}" -->
+                <ListView  
+                    x:Name="_list"
+                    BackgroundColor="Transparent" 
+                    SelectionMode="None"
+                    SeparatorVisibility="Default"
+                    SeparatorColor="Transparent">
+                    <!-- <CollectionView.EmptyView> -->
+                    <!--     <ui:MaterialLabel  -->
+                    <!--         x:Name="_emptylist" -->
+                    <!--         Text="{Binding EmptyText}"  -->
+                    <!--         VerticalOptions="CenterAndExpand"  -->
+                    <!--         VerticalTextAlignment="Center" -->
+                    <!--         HorizontalOptions="CenterAndExpand" -->
+                    <!--         HorizontalTextAlignment="Center"  -->
+                    <!--         TypeScale="H6" -->
+                    <!--         TextColor="Gray"/>  -->
+                    <!-- </CollectionView.EmptyView> -->
+                    <!-- <CollectionView.ItemsLayout> -->
+                    <!--     <LinearItemsLayout ItemSpacing="{Binding Spacing}" Orientation="Vertical" /> -->
+                    <!-- </CollectionView.ItemsLayout> -->
+                </ListView>
+                
+            </RefreshView>
+            
+            <local:MobileCard
+                Grid.Row="1"
+                x:Name="_refreshcard"
+                Padding="5">
+                <Grid>
+                    <Grid.ColumnDefinitions>
+                        <ColumnDefinition Width="*"/>
+                        <ColumnDefinition Width="Auto"/>
+                        <ColumnDefinition Width="*"/>
+                    </Grid.ColumnDefinitions>
+                
+                    <Label 
+                        x:Name="_lastupdate"
+                        Grid.Column="0" 
+                        HorizontalTextAlignment="Start"
+                        FontSize="Micro"
+                        TextColor="Black"/>
+                
+                    <Label
+                        x:Name="_numrecords"
+                        Grid.Column="1"
+                        HorizontalTextAlignment="Center"
+                        FontSize="Micro"
+                        TextColor="Black"/>
+                
+                    <Label 
+                        x:Name="_pulltorefresh"
+                        Grid.Column="2" 
+                        HorizontalTextAlignment="End"
+                        FontSize="Micro"
+                        Text="Pull To Refresh"
+                        TextColor="Black"/>
+            
+                </Grid>    
+            </local:MobileCard>
+            
+        </Grid>
+    </ContentView.Content>
+</ContentView>

+ 184 - 0
InABox.Mobile/InABox.Mobile.Shared/Components/MobileListView/MobileListView.xaml.cs

@@ -0,0 +1,184 @@
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using InABox.Core;
+using Xamarin.Forms;
+using Xamarin.Forms.Xaml;
+
+namespace InABox.Mobile
+{
+
+    
+    [XamlCompilation(XamlCompilationOptions.Compile)]
+    public partial class MobileListView
+    {
+        
+        public static readonly BindableProperty PullToRefreshProperty = BindableProperty.Create(
+            nameof(PullToRefresh), 
+            typeof(bool), 
+            typeof(MobileCollectionView),
+            false);
+
+        public bool PullToRefresh
+        {
+            get => (bool)GetValue(PullToRefreshProperty);
+            set
+            {
+                SetValue(PullToRefreshProperty,value);
+                _refresher.IsEnabled = value;
+                UpdateSummaryRow();
+            }
+        }
+
+        private DataTemplate _itemTemplate;
+        public DataTemplate ItemTemplate
+        {
+            get => _itemTemplate;
+            set
+            {
+                _itemTemplate = value;
+                _list.ItemTemplate = value;
+            }
+        }
+        
+        public IEnumerable ItemsSource
+        {
+            get => _list.ItemsSource;
+            set
+            {
+                if (_list.ItemsSource is INotifyCollectionChanged old)
+                    old.CollectionChanged -= ItemsSourceChanged;
+                _list.ItemsSource = value;
+                CheckChanged();
+                if (value is INotifyCollectionChanged observable)
+                    observable.CollectionChanged += ItemsSourceChanged;
+                UpdateSummaryRow();
+            }
+        }
+
+        public static readonly BindableProperty LastUpdatedProperty = BindableProperty.Create(
+            nameof(LastUpdated), 
+            typeof(DateTime), 
+            typeof(MobileCollectionView));
+        
+        public DateTime LastUpdated
+        {
+            get => (DateTime)GetValue(LastUpdatedProperty);
+            set
+            {
+                SetValue(LastUpdatedProperty,value);
+                UpdateSummaryRow();
+            }
+        }
+        
+        public static readonly BindableProperty ShowRecordCountProperty = BindableProperty.Create(
+            nameof(ShowRecordCount), 
+            typeof(bool), 
+            typeof(MobileCollectionView), 
+            false);
+
+        public bool ShowRecordCount
+        {
+            get => (bool)GetValue(ShowRecordCountProperty);
+            set
+            {
+                SetValue(ShowRecordCountProperty,value);
+                UpdateSummaryRow();
+            }
+        }
+        
+        public static readonly BindableProperty EmptyTextProperty = BindableProperty.Create(
+            nameof(EmptyText), 
+            typeof(string), 
+            typeof(MobileCollectionView), 
+            "No Data Available");
+
+        public string EmptyText
+        {
+            get => (string)GetValue(EmptyTextProperty);
+            set => SetValue(EmptyTextProperty,value);
+        }
+        
+        private void UpdateSummaryRow()
+        {
+            Device.BeginInvokeOnMainThread(() =>
+            {
+                _lastupdate.IsVisible = !LastUpdated.IsEmpty();
+                _lastupdate.Text = $"{DateTimeToAgeConverter.FormatTime(LastUpdated)}";
+                _pulltorefresh.IsVisible = PullToRefresh;
+                int count = (ItemsSource as IList)?.Count ?? 0;
+                _numrecords.Text = $"{count} record{(count == 1 ? "" : "s")}";
+                _numrecords.IsVisible = ShowRecordCount && ItemsSource is IList;
+                _refreshcard.IsVisible = /*_lastupdate.IsVisible || */ _pulltorefresh.IsVisible || _numrecords.IsVisible;
+                //_emptylist.IsVisible = !ShowRecordCount;
+            });
+        }
+
+        private void ItemsSourceChanged(object sender, NotifyCollectionChangedEventArgs e)
+        {
+            CheckChanged();
+            UpdateSummaryRow();
+        }
+
+        private void CheckChanged()
+        {
+            //_list.IsVisible = ItemsSource?.GetEnumerator().MoveNext() == true;
+            //_nodata.IsVisible = !_list.IsVisible;
+        }
+
+        private double _spacing;
+        public double Spacing
+        {
+            get => _spacing;
+            set
+            {
+                _spacing = value;
+                //var layout = _list?.ItemsLayout as LinearItemsLayout;
+                //if (layout != null)
+                //    layout.ItemSpacing = _spacing;
+            }
+        }
+
+
+        private bool _unevenrows;
+        public bool HasUnevenRows
+        {
+            get => _unevenrows;
+            set
+            {
+                _unevenrows = value;
+                if (_list != null)
+                    // _list.ItemSizingStrategy =
+                    //     value 
+                    //         ? ItemSizingStrategy.MeasureAllItems 
+                    //         : ItemSizingStrategy.MeasureFirstItem;
+                    _list.HasUnevenRows = value;
+                    //_list.AutoFitMode = value ? AutoFitMode.DynamicHeight : AutoFitMode.None;
+            }
+        }
+        
+        public event MobileListRefreshEvent RefreshRequested;
+
+        public MobileListView()
+        {
+            InitializeComponent();
+            _refresher.Command = new Command(DoRefresh);
+            Spacing = 5;
+            HasUnevenRows = true;
+        }
+        
+        private void DoRefresh(object sender)
+        {
+            if (_refresher != null)
+            {
+                //var src = _list.ItemsSource;
+                _list.ItemsSource = null;
+                _refresher.IsRefreshing = true;
+                RefreshRequested?.Invoke(sender, new MobileListRefreshEventArgs());
+                _refresher.IsRefreshing = false;
+                //_list.ItemsSource = src;
+            }
+        }
+        
+    }
+}

+ 4 - 4
InABox.Mobile/InABox.Mobile.Shared/Components/MobileModuleList/MobileModuleList.xaml

@@ -11,12 +11,12 @@
     <!-- </ContentView.Resources> -->
     
     <ContentView.Content>
-        <mobile:MobileList 
+        <mobile:MobileCollectionView 
             x:Name="Modules" 
             BackgroundColor="Transparent"
             PullToRefresh="False"
             ShowRecordCount="False">
-            <mobile:MobileList.ItemTemplate>
+            <mobile:MobileCollectionView.ItemTemplate>
                 <DataTemplate x:DataType="mobile:MobileModuleItem">
                     
                     <mobile:MobileCard
@@ -131,8 +131,8 @@
 
                 </DataTemplate>
                 
-            </mobile:MobileList.ItemTemplate>
+            </mobile:MobileCollectionView.ItemTemplate>
             
-        </mobile:MobileList>
+        </mobile:MobileCollectionView>
     </ContentView.Content>
 </ContentView>

+ 7 - 0
InABox.Mobile/InABox.Mobile.Shared/InABox.Mobile.Shared.csproj

@@ -57,4 +57,11 @@
       <None Remove="Images\cross.svg" />
       <SharedImage Include="Images\sharedcross.svg" BaseSize="30, 30" />
     </ItemGroup>
+
+    <ItemGroup>
+      <Compile Update="Components\MobileCollectionView\MobileCollectionView.xaml.cs">
+        <DependentUpon>MobileCollection.xaml</DependentUpon>
+        <SubType>Code</SubType>
+      </Compile>
+    </ItemGroup>
 </Project>