Use NUI CollectionsView. (#41)
authorPiotr Czaja/Tizen Services & IoT (PLT) /SRPOL/Engineer/Samsung Electronics <p.czaja@samsung.com>
Sun, 9 May 2021 13:54:03 +0000 (15:54 +0200)
committerPiotr Czaja <p.czaja@samsung.com>
Tue, 14 Sep 2021 11:01:34 +0000 (13:01 +0200)
* Use NUI CollectionsView.
* Add review based fixes.
* Add review based fixes.
* Fix issues from CI.

Fitness/Controls/BindableCollectionView.cs [new file with mode: 0644]
Fitness/Controls/ISelectionController.cs [deleted file]
Fitness/Views/FitnessItemView.xaml.cs [new file with mode: 0644]
Fitness/Views/MainView.xaml.cs
Fitness/res/layout/FitnessItemView.xaml [new file with mode: 0644]
Fitness/res/layout/MainView.xaml

diff --git a/Fitness/Controls/BindableCollectionView.cs b/Fitness/Controls/BindableCollectionView.cs
new file mode 100644 (file)
index 0000000..2443a2d
--- /dev/null
@@ -0,0 +1,55 @@
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using Fitness.Views;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
+
+namespace Fitness.Controls
+{
+    /// <summary>
+    /// Collection View with bindable item source property.
+    /// </summary>
+    public class BindableCollectionView : CollectionView
+    {
+        /// <summary>
+        /// ItemsSource property.
+        /// </summary>
+        public static readonly BindableProperty ItemsSourceProperty =
+            BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(BindableCollectionView), null, propertyChanged: OnItemsSourceChanged);
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="BindableCollectionView"/> class.
+        /// </summary>
+        public BindableCollectionView()
+        {
+            this.SelectionChanged += BindableCollectionView_SelectionChanged;
+        }
+
+        /// <summary>
+        /// A delegate to be run when ItemsSource property has changed.
+        /// </summary>
+        /// <param name="bindable">The bindable object that contains the property.</param>
+        /// <param name="oldValue">The old property value.</param>
+        /// <param name="newValue">The new property value.</param>
+        public static void OnItemsSourceChanged(BindableObject bindable, object oldValue, object newValue)
+        {
+            if (bindable is BindableCollectionView collectionView && newValue is IEnumerable itemsSource)
+            {
+                collectionView.ItemsSource = itemsSource;
+            }
+        }
+
+        private void BindableCollectionView_SelectionChanged(object sender, SelectionChangedEventArgs e)
+        {
+            List<object> oldSel = new List<object>(e.PreviousSelection);
+            List<object> newSel = new List<object>(e.CurrentSelection);
+
+            if (oldSel.Count == 1 && newSel.Count == 0 && oldSel[0] != null)
+            {
+                SelectedItem = oldSel[0];
+            }
+        }
+    }
+}
diff --git a/Fitness/Controls/ISelectionController.cs b/Fitness/Controls/ISelectionController.cs
deleted file mode 100644 (file)
index 8050add..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-using System;
-using Tizen.NUI;
-using Tizen.NUI.Components;
-
-namespace Fitness.Controls
-{
-    public interface ISelectionController
-    {
-        bool IsSelected { get; set; }
-    }
-}
diff --git a/Fitness/Views/FitnessItemView.xaml.cs b/Fitness/Views/FitnessItemView.xaml.cs
new file mode 100644 (file)
index 0000000..69e8fe2
--- /dev/null
@@ -0,0 +1,22 @@
+using Fitness.Controls;
+using Fitness.Services;
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace Fitness.Views
+{
+    /// <summary>
+    /// Fitness workout collection View item.
+    /// </summary>
+    public partial class FitnessItemView : RecyclerViewItem
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="FitnessItemView"/> class.
+        /// </summary>
+        public FitnessItemView()
+        {
+            InitializeComponent();
+        }
+    }
+}
index 49240d8fe877ae04dec5dd56b90d41adf6e7e88c..ef5c0a2fe1020a5d951e58b2f4f119d5303893c5 100644 (file)
@@ -16,14 +16,7 @@ namespace Fitness.Views
 
             InitializeComponent();
 
-            // TODO : Change RecyclerView to Collection View
-            // this.scroller.SelectionMode = BindableRecyclerView.RecyclerViewSelectionMode.Single;
-
-            // this.scroller.LayoutManager = new LinearRecycleLayoutManager()
-            // {
-            //     LayoutOrientation = RecycleLayoutManager.Orientation.Horizontal,
-            // };
-            // this.scroller.ScrollingDirection = ScrollableBase.Direction.Horizontal;
+            scroller.ScrollingDirection = ScrollableBase.Direction.Horizontal;
         }
 
         private void CheckPrivilege()
diff --git a/Fitness/res/layout/FitnessItemView.xaml b/Fitness/res/layout/FitnessItemView.xaml
new file mode 100644 (file)
index 0000000..f0de55c
--- /dev/null
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<nui:RecyclerViewItem x:Class="Fitness.Views.FitnessItemView"
+  xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+  xmlns:nui="clr-namespace:Tizen.NUI.Components"
+  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+  xmlns:views="clr-namespace:Fitness.Views"
+  xmlns:converters="clr-namespace:Fitness.Views.Converters"
+  xmlns:ctrl="clr-namespace:Fitness.Controls"
+  Size="{views:SizeInUnits Width=82,Height=44}"
+  BackgroundColor="Transparent"
+  x:Name="Root">
+    <View Size="{views:SizeInUnits Width=78,Height=44}" >
+        <ImageView x:Name="image"
+                   BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
+                   HeightResizePolicy="FillToParent"
+                   WidthResizePolicy="FillToParent"
+                   ResourceUrl="{Binding ThumbnailUrl}"/>
+        <TextLabel x:Name="label"
+                   BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
+                   PositionUsesPivotPoint="true"
+                   PivotPoint="0.0,1.0"
+                   ParentOrigin="0.0,1.0"
+                   PixelSize="24"
+                   Text="{Binding Title}"/>
+        <ImageView x:Name="favourite"
+                   BindingContext="{Binding Source={x:Reference Root}, Path=BindingContext}"
+                   Size="40,40"
+                   PositionUsesPivotPoint="true"
+                   PivotPoint="1.0,0.0"
+                   ParentOrigin="1.0,0.0"
+                   ResourceUrl="{Binding Favourite, Converter={Static converters:FavouriteToIconConverter.Converter}}"/>
+    </View>
+</nui:RecyclerViewItem>
index e35489ed3aacda0be433a77da9bbc8735dda63a0..e139815b250651fd893e8858e756708920a5d444 100644 (file)
           <ImageView PositionUsesPivotPoint="true" PivotPoint="1.0,0.0" ParentOrigin="1.0, 0.0" Size="30,30" BindingContext="{Binding Source={x:Reference context}, Path=SelectedWorkout}" ResourceUrl="{Binding Favourite, Converter={Static converters:FavouriteToIconConverter.Converter}}"/>
       </View>
   </View>
-  <nui:CollectionView Size="{views:SizeInUnits Height=44}" Margin="{views:ExtentsInUnits Top=10, Bottom=10}" WidthResizePolicy="FillToParent" ItemsSource="{Binding Workouts}" x:Name="scroller" Padding="{views:ExtentsInUnits Start=16, End=16}">
-  </nui:CollectionView>
+    <ctrl:BindableCollectionView Size="{views:SizeInUnits Height=44}" Margin="{views:ExtentsInUnits Top=10, Bottom=10, Start=16, End=16}" WidthResizePolicy="FillToParent" ItemsSource="{Binding Workouts}" x:Name="scroller" SelectedItem="{Binding Path=SelectedWorkout, Mode=TwoWay}" SelectionMode="SingleSelection">
+        <ctrl:BindableCollectionView.ItemTemplate>
+            <DataTemplate>
+                <views:FitnessItemView />
+            </DataTemplate>
+        </ctrl:BindableCollectionView.ItemTemplate>
+        <ctrl:BindableCollectionView.ItemsLayouter>
+            <nui:GridLayouter />
+        </ctrl:BindableCollectionView.ItemsLayouter>
+    </ctrl:BindableCollectionView>
 </ctrl:Page>