@@ -32,6 +32,8 @@ internal partial class SfHorizontalContent : SfTabViewExt, ITouchListener, ITapG
32
32
bool ? _isTowardsRight ;
33
33
int _visibleItemCount ;
34
34
int _currentIndex ;
35
+ int _previousVisibleIndex ;
36
+ int _nextVisibleIndex ;
35
37
bool _isPreviousItemVisible ;
36
38
bool _isNextItemVisible ;
37
39
SelectionChangingEventArgs ? _selectionChangingEventArgs ;
@@ -103,6 +105,19 @@ internal partial class SfHorizontalContent : SfTabViewExt, ITouchListener, ITapG
103
105
typeof ( double ) ,
104
106
typeof ( SfHorizontalContent ) ,
105
107
100d ) ;
108
+
109
+ /// <summary>
110
+ /// Identifies the <see cref="EnableVirtualization"/> bindable property.
111
+ /// </summary>
112
+ /// <value>
113
+ /// The identifier for <see cref="EnableVirtualization"/> bindable property.
114
+ /// </value>
115
+ internal static readonly BindableProperty EnableVirtualizationProperty =
116
+ BindableProperty . Create (
117
+ nameof ( EnableVirtualization ) ,
118
+ typeof ( bool ) ,
119
+ typeof ( SfHorizontalContent ) ,
120
+ false ) ;
106
121
#endregion
107
122
108
123
#region Properties
@@ -155,6 +170,18 @@ internal IList? ItemsSource
155
170
set => SetValue ( ItemsSourceProperty , value ) ;
156
171
}
157
172
173
+ /// <summary>
174
+ /// Gets or sets a value indicating whether lazy loading is enabled during the initial load.
175
+ /// </summary>
176
+ /// <value>
177
+ /// It accepts the bool values and the default value is false.
178
+ /// </value>
179
+ internal bool EnableVirtualization
180
+ {
181
+ get => ( bool ) GetValue ( EnableVirtualizationProperty ) ;
182
+ set => SetValue ( EnableVirtualizationProperty , value ) ;
183
+ }
184
+
158
185
/// <summary>
159
186
/// Gets or sets the value that defines the content width of each tab header item.
160
187
/// </summary>
@@ -373,6 +400,11 @@ void ClearTabContent(SfTabItem tabItem, int index)
373
400
void UpdateSelectedIndex ( )
374
401
{
375
402
_isSelectionProcessed = true ;
403
+ if ( EnableVirtualization )
404
+ {
405
+ LoadItemsContent ( SelectedIndex ) ;
406
+ }
407
+
376
408
UpdateTabItemContentPosition ( ) ;
377
409
}
378
410
@@ -439,10 +471,29 @@ void AddTabContentItems(SfTabItem item, int index = -1)
439
471
{
440
472
if ( item . Content != null )
441
473
{
442
- SfGrid parentGrid = CreateParentGrid ( item ) ;
474
+ SfGrid parentGrid = new ( ) ;
475
+
476
+ if ( ! EnableVirtualization || ( EnableVirtualization && ! ( index != SelectedIndex && item . IsVisible ) ) )
477
+ {
478
+ parentGrid = CreateParentGrid ( item ) ;
479
+ }
480
+
443
481
if ( index >= 0 )
444
482
{
445
- _horizontalStackLayout ? . Children . Insert ( index , parentGrid ) ;
483
+ if ( EnableVirtualization && index != SelectedIndex && item . IsVisible )
484
+ {
485
+ var content = new BoxView
486
+ {
487
+ WidthRequest = 0 ,
488
+ HeightRequest = 0 ,
489
+ Opacity = 0
490
+ } ;
491
+ _horizontalStackLayout ? . Children . Insert ( index , content ) ;
492
+ }
493
+ else
494
+ {
495
+ _horizontalStackLayout ? . Children . Insert ( index , parentGrid ) ;
496
+ }
446
497
}
447
498
else
448
499
{
@@ -849,6 +900,12 @@ void AdjustForFirstIndex(double difference)
849
900
{
850
901
if ( _horizontalStackLayout != null && IsTowardsRight == true )
851
902
{
903
+ if ( EnableVirtualization )
904
+ {
905
+ var index = _nextVisibleIndex ;
906
+ LoadItemsContent ( index ) ;
907
+ }
908
+
852
909
#if ! WINDOWS
853
910
if ( ( ( this as IVisualElementController ) . EffectiveFlowDirection & EffectiveFlowDirection . RightToLeft ) != EffectiveFlowDirection . RightToLeft )
854
911
_horizontalStackLayout . TranslationX = Math . Clamp ( _horizontalStackLayout . TranslationX + difference , - ContentWidth , 0 ) ;
@@ -866,6 +923,17 @@ void AdjustForMiddleIndices(double difference)
866
923
{
867
924
if ( _isPreviousItemVisible && _isNextItemVisible )
868
925
{
926
+ if ( EnableVirtualization )
927
+ {
928
+ int index = - 1 ;
929
+ if ( IsTowardsRight is not null )
930
+ {
931
+ index = IsTowardsRight == true ? _nextVisibleIndex : _previousVisibleIndex ;
932
+ }
933
+
934
+ LoadItemsContent ( index ) ;
935
+ }
936
+
869
937
#if ! WINDOWS
870
938
if ( ( ( this as IVisualElementController ) . EffectiveFlowDirection & EffectiveFlowDirection . RightToLeft ) != EffectiveFlowDirection . RightToLeft )
871
939
_horizontalStackLayout . TranslationX = Math . Clamp ( _horizontalStackLayout . TranslationX + difference , - ContentWidth * ( _currentIndex + 1 ) , - ContentWidth * ( _currentIndex - 1 ) ) ;
@@ -877,6 +945,12 @@ void AdjustForMiddleIndices(double difference)
877
945
}
878
946
else if ( _isPreviousItemVisible )
879
947
{
948
+ if ( EnableVirtualization )
949
+ {
950
+ var index = _previousVisibleIndex ;
951
+ LoadItemsContent ( index ) ;
952
+ }
953
+
880
954
#if ! WINDOWS
881
955
if ( ( ( this as IVisualElementController ) . EffectiveFlowDirection & EffectiveFlowDirection . RightToLeft ) != EffectiveFlowDirection . RightToLeft )
882
956
_horizontalStackLayout . TranslationX = Math . Clamp ( _horizontalStackLayout . TranslationX + difference , - ContentWidth * _currentIndex , - ContentWidth * ( _currentIndex - 1 ) ) ;
@@ -888,6 +962,12 @@ void AdjustForMiddleIndices(double difference)
888
962
}
889
963
else if ( _isNextItemVisible )
890
964
{
965
+ if ( EnableVirtualization )
966
+ {
967
+ var index = _nextVisibleIndex ;
968
+ LoadItemsContent ( index ) ;
969
+ }
970
+
891
971
#if ! WINDOWS
892
972
if ( ( ( this as IVisualElementController ) . EffectiveFlowDirection & EffectiveFlowDirection . RightToLeft ) != EffectiveFlowDirection . RightToLeft )
893
973
_horizontalStackLayout . TranslationX = Math . Clamp ( _horizontalStackLayout . TranslationX + difference , - ContentWidth * ( _currentIndex + 1 ) , - ContentWidth * _currentIndex ) ;
@@ -904,6 +984,15 @@ void AdjustForLastIndex(double difference)
904
984
{
905
985
if ( _horizontalStackLayout != null )
906
986
{
987
+ if ( EnableVirtualization )
988
+ {
989
+ var index = _previousVisibleIndex ;
990
+ if ( IsTowardsRight is false )
991
+ {
992
+ LoadItemsContent ( index ) ;
993
+ }
994
+ }
995
+
907
996
#if ! WINDOWS
908
997
if ( ( ( this as IVisualElementController ) . EffectiveFlowDirection & EffectiveFlowDirection . RightToLeft ) != EffectiveFlowDirection . RightToLeft )
909
998
_horizontalStackLayout . TranslationX = Math . Clamp ( _horizontalStackLayout . TranslationX + difference , - ContentWidth * ( _visibleItemCount - 1 ) , - ContentWidth * ( _visibleItemCount - 2 ) ) ;
@@ -915,6 +1004,24 @@ void AdjustForLastIndex(double difference)
915
1004
}
916
1005
}
917
1006
1007
+ /// <summary>
1008
+ /// This method is used to replace the placeholder view with a tab item when the EnableVirtualization is true.
1009
+ /// </summary>
1010
+ /// <param name="index">This index position of the child in the HorizontalStackLayout to replaced with a tab item.</param>
1011
+ void LoadItemsContent ( int index )
1012
+ {
1013
+ if ( _horizontalStackLayout != null )
1014
+ {
1015
+ if ( Items is not null && index >= 0 && index < _horizontalStackLayout . Children . Count && _horizontalStackLayout . Children [ index ] is BoxView )
1016
+ {
1017
+ SfGrid parentGrid = CreateParentGrid ( Items [ index ] ) ;
1018
+ _horizontalStackLayout ? . Children . RemoveAt ( index ) ;
1019
+ _horizontalStackLayout ? . Children . Insert ( index , parentGrid ) ;
1020
+ UpdateDynamicChanges ( ) ;
1021
+ }
1022
+ }
1023
+ }
1024
+
918
1025
/// <summary>
919
1026
/// This method is used to update the tab item position after swipe complete.
920
1027
/// </summary>
@@ -1377,6 +1484,7 @@ void UpdateVisibilityWithoutTemplate()
1377
1484
if ( Items [ i ] . IsVisible == true )
1378
1485
{
1379
1486
_isNextItemVisible = true ;
1487
+ _nextVisibleIndex = i ;
1380
1488
break ;
1381
1489
}
1382
1490
}
@@ -1386,6 +1494,7 @@ void UpdateVisibilityWithoutTemplate()
1386
1494
if ( Items [ i ] . IsVisible == true )
1387
1495
{
1388
1496
_isPreviousItemVisible = true ;
1497
+ _previousVisibleIndex = i ;
1389
1498
break ;
1390
1499
}
1391
1500
}
0 commit comments