diff --git a/Maui.Tabs/BottomTabItem.xaml b/Maui.Tabs/BottomTabItem.xaml
index cd656ad..cbe50eb 100644
--- a/Maui.Tabs/BottomTabItem.xaml
+++ b/Maui.Tabs/BottomTabItem.xaml
@@ -1,12 +1,11 @@
-
+
@@ -24,32 +23,29 @@
-
+
-
+
-
+
diff --git a/Maui.Tabs/Effects/Commands.cs b/Maui.Tabs/Effects/Commands.cs
index 135a892..2dac6dc 100644
--- a/Maui.Tabs/Effects/Commands.cs
+++ b/Maui.Tabs/Effects/Commands.cs
@@ -76,6 +76,17 @@ public static object GetLongTapParameter(BindableObject view) {
return view.GetValue(LongTapParameterProperty);
}
+ public static void UnregisterEffect(BindableObject bindable)
+ {
+ if (!(bindable is View view))
+ return;
+
+ var eff = view.Effects.FirstOrDefault(e => e is CommandsRoutingEffect);
+
+ if (eff == null) return;
+ view.Effects.Remove(eff);
+ }
+
static void PropertyChanged(BindableObject bindable, object oldValue, object newValue) {
if (!(bindable is View view))
return;
@@ -93,7 +104,7 @@ static void PropertyChanged(BindableObject bindable, object oldValue, object new
}
}
else {
- if (eff == null || view.BindingContext == null) return;
+ if (eff == null) return;
view.Effects.Remove(eff);
if (EffectsConfig.AutoChildrenInputTransparent && bindable is Layout &&
EffectsConfig.GetChildrenInputTransparent(view)) {
diff --git a/Maui.Tabs/Effects/TouchEffect.cs b/Maui.Tabs/Effects/TouchEffect.cs
index 88568bc..8a8d6f1 100644
--- a/Maui.Tabs/Effects/TouchEffect.cs
+++ b/Maui.Tabs/Effects/TouchEffect.cs
@@ -1,4 +1,6 @@
-namespace Sharpnado.Tabs.Effects {
+using Microsoft.Maui.Controls;
+
+namespace Sharpnado.Tabs.Effects {
public static class TouchEffect {
public static readonly BindableProperty ColorProperty =
@@ -6,7 +8,7 @@ public static class TouchEffect {
"Color",
typeof(Color),
typeof(TouchEffect),
- Colors.Transparent,
+ KnownColor.Accent,
propertyChanged: PropertyChanged
);
@@ -18,6 +20,17 @@ public static Color GetColor(BindableObject view) {
return (Color)view.GetValue(ColorProperty);
}
+ public static void UnregisterEffect(BindableObject bindable)
+ {
+ if (!(bindable is View view))
+ return;
+
+ var eff = view.Effects.FirstOrDefault(e => e is TouchRoutingEffect);
+
+ if (eff == null) return;
+ view.Effects.Remove(eff);
+ }
+
static void PropertyChanged(BindableObject bindable, object oldValue, object newValue) {
if (!(bindable is View view))
return;
@@ -34,7 +47,7 @@ static void PropertyChanged(BindableObject bindable, object oldValue, object new
}
}
else {
- if (eff == null || view.BindingContext == null) return;
+ if (eff == null) return;
view.Effects.Remove(eff);
if (EffectsConfig.AutoChildrenInputTransparent && bindable is Layout &&
EffectsConfig.GetChildrenInputTransparent(view)) {
diff --git a/Maui.Tabs/MaterialUnderlinedTabItem.xaml b/Maui.Tabs/MaterialUnderlinedTabItem.xaml
index b70ec55..ed1222b 100644
--- a/Maui.Tabs/MaterialUnderlinedTabItem.xaml
+++ b/Maui.Tabs/MaterialUnderlinedTabItem.xaml
@@ -1,11 +1,10 @@
-
+
@@ -44,33 +43,28 @@
-
-
-
+
+
+
-
+
-
+
diff --git a/Maui.Tabs/Maui.Tabs.csproj b/Maui.Tabs/Maui.Tabs.csproj
index 183d4f9..d034962 100644
--- a/Maui.Tabs/Maui.Tabs.csproj
+++ b/Maui.Tabs/Maui.Tabs.csproj
@@ -22,9 +22,9 @@
$(AssemblyName) ($(TargetFramework))
- 3.0.1
- 3.0.1
- 3.0.1
+ 3.1.0
+ 3.1.0
+ 3.1.0
true
en
@@ -41,7 +41,7 @@
docs\ReadMe.md
maui dotnetmaui xamarin.forms android ios uwp netstandard tabs segmented control bottombar fixed tabs scrollable tabs badge
- First MAUI release \o/
+ Fixes for touch effects on tabs
"Pure" MAUI Tabs (no renderers)
diff --git a/Maui.Tabs/Platforms/Android/CommandsPlatform.cs b/Maui.Tabs/Platforms/Android/CommandsPlatform.cs
index e88da21..111e569 100644
--- a/Maui.Tabs/Platforms/Android/CommandsPlatform.cs
+++ b/Maui.Tabs/Platforms/Android/CommandsPlatform.cs
@@ -20,7 +20,8 @@
namespace Sharpnado.Tabs.Effects.Droid {
public class CommandsPlatform : PlatformEffect {
public View View => Control ?? Container;
- public bool IsDisposed => (Container as IVisualElementRenderer)?.Element == null;
+ public bool IsDisposed => Container is null
+ || (Container is Java.Lang.Object javaContainer) && javaContainer.Handle == IntPtr.Zero;
DateTime _tapTime;
readonly Rect _rect = new Rect();
@@ -33,7 +34,7 @@ protected override void OnAttached() {
View.Clickable = true;
View.LongClickable = true;
View.SoundEffectsEnabled = true;
- TouchCollector.Add(View, OnTouch);
+ TouchCollector.Add(View, OnTouch, ActionType.Tap);
}
void OnTouch(View.TouchEventArgs args) {
@@ -83,7 +84,7 @@ void LongClickHandler() {
protected override void OnDetached() {
if (IsDisposed) return;
- TouchCollector.Delete(View, OnTouch);
+ TouchCollector.Delete(View, OnTouch, ActionType.Tap);
}
}
}
diff --git a/Maui.Tabs/Platforms/Android/TouchCollector.cs b/Maui.Tabs/Platforms/Android/TouchCollector.cs
index b9ed4cc..4cfbb44 100644
--- a/Maui.Tabs/Platforms/Android/TouchCollector.cs
+++ b/Maui.Tabs/Platforms/Android/TouchCollector.cs
@@ -11,37 +11,52 @@
using View = Android.Views.View;
namespace Sharpnado.Tabs.Effects.Droid.GestureCollectors {
+ enum ActionType
+ {
+ Ripple = 0,
+ Tap = 1,
+ }
+
+ record ActionSource(ActionType ActionType, Action Action);
+
internal static class TouchCollector {
- static Dictionary>> Collection { get; } =
- new Dictionary>>();
+ static Dictionary> Collection { get; } =
+ new ();
static View _activeView;
- public static void Add(View view, Action action) {
+ public static void Add(View view, Action action, ActionType actionType) {
if (Collection.ContainsKey(view)) {
- Collection[view].Add(action);
+ Collection[view].Add(new ActionSource(actionType, action));
}
else {
view.Touch += ActionActivator;
- Collection.Add(view, new List> { action });
+ Collection.Add(view, [ new(actionType, action) ] );
}
}
- public static void Delete(View view, Action action) {
+ public static void Delete(View view, Action action, ActionType actionType) {
if (!Collection.ContainsKey(view)) return;
var actions = Collection[view];
- actions.Remove(action);
+ actions.Remove(new ActionSource(actionType, action));
if (actions.Count != 0) return;
view.Touch -= ActionActivator;
Collection.Remove(view);
}
- static void ActionActivator(object sender, View.TouchEventArgs e) {
+ static async void ActionActivator(object sender, View.TouchEventArgs e) {
var view = (View)sender;
if (!Collection.ContainsKey(view) || (_activeView != null && _activeView != view)) return;
+ var actions = Collection[view].ToArray();
+ bool rippleRan = false;
+ foreach (var valueAction in actions.Where(source => source.ActionType == ActionType.Ripple)) {
+ valueAction?.Action.Invoke(e);
+ rippleRan = true;
+ }
+
switch (e.Event.Action) {
case MotionEventActions.Down:
_activeView = view;
@@ -55,9 +70,13 @@ static void ActionActivator(object sender, View.TouchEventArgs e) {
break;
}
- var actions = Collection[view].ToArray();
- foreach (var valueAction in actions) {
- valueAction?.Invoke(e);
+ if (rippleRan)
+ {
+ await Task.Delay(200);
+ }
+
+ foreach (var valueAction in actions.Where(source => source.ActionType == ActionType.Tap)) {
+ valueAction?.Action.Invoke(e);
}
}
}
diff --git a/Maui.Tabs/Platforms/Android/TouchEffectPlatform.cs b/Maui.Tabs/Platforms/Android/TouchEffectPlatform.cs
index e618481..33a5249 100644
--- a/Maui.Tabs/Platforms/Android/TouchEffectPlatform.cs
+++ b/Maui.Tabs/Platforms/Android/TouchEffectPlatform.cs
@@ -55,7 +55,7 @@ protected override void OnAttached() {
_viewOverlay.Background = CreateRipple(_color);
SetEffectColor();
- TouchCollector.Add(View, OnTouch);
+ TouchCollector.Add(View, OnTouch, ActionType.Ripple);
group.AddView(_viewOverlay);
_viewOverlay.BringToFront();
@@ -78,7 +78,7 @@ protected override void OnDetached() {
if (EnableRipple)
_ripple?.Dispose();
- TouchCollector.Delete(View, OnTouch);
+ TouchCollector.Delete(View, OnTouch, ActionType.Ripple);
}
protected override void OnElementPropertyChanged(PropertyChangedEventArgs e) {
diff --git a/Maui.Tabs/Platforms/iOS/TintableImageEffect.cs b/Maui.Tabs/Platforms/iOS/TintableImageEffect.cs
index a6e3292..b12abd9 100644
--- a/Maui.Tabs/Platforms/iOS/TintableImageEffect.cs
+++ b/Maui.Tabs/Platforms/iOS/TintableImageEffect.cs
@@ -88,7 +88,7 @@ private void UpdateColor()
private async Task DelayedPost(int milliseconds, Action action)
{
await Task.Delay(milliseconds);
- Device.BeginInvokeOnMainThread(action);
+ MainThread.BeginInvokeOnMainThread(action);
}
}
}
diff --git a/Maui.Tabs/Platforms/iOS/TouchEffectPlatform.cs b/Maui.Tabs/Platforms/iOS/TouchEffectPlatform.cs
index 02397ce..e41cf2d 100644
--- a/Maui.Tabs/Platforms/iOS/TouchEffectPlatform.cs
+++ b/Maui.Tabs/Platforms/iOS/TouchEffectPlatform.cs
@@ -1,6 +1,6 @@
using System.ComponentModel;
-using Microsoft.Maui.Controls.Compatibility.Platform.iOS;
using Microsoft.Maui.Controls.Platform;
+using Microsoft.Maui.Platform;
using ObjCRuntime;
using Sharpnado.Tabs.Effects.iOS.GestureCollectors;
using Sharpnado.Tabs.Effects.iOS.GestureRecognizers;
@@ -80,7 +80,7 @@ void UpdateEffectColor() {
InternalLogger.Debug($"UpdateEffectColor");
_alpha = color.Alpha < 1.0 ? 1 : (float)0.3;
- _layer.BackgroundColor = color.ToUIColor();
+ _layer.BackgroundColor = color.ToPlatform();
}
void BringLayer() {
diff --git a/Maui.Tabs/UnderlinedTabItem.xaml b/Maui.Tabs/UnderlinedTabItem.xaml
index 5470815..d4a0a91 100644
--- a/Maui.Tabs/UnderlinedTabItem.xaml
+++ b/Maui.Tabs/UnderlinedTabItem.xaml
@@ -1,11 +1,10 @@
-
+
@@ -23,29 +22,26 @@
-
+
-
+
-
+
diff --git a/MauiSample/App.xaml.cs b/MauiSample/App.xaml.cs
index 9d81503..a0989ba 100644
--- a/MauiSample/App.xaml.cs
+++ b/MauiSample/App.xaml.cs
@@ -11,5 +11,6 @@ public App(BottomTabsPageViewModel mainViewModel)
Current!.UserAppTheme = AppTheme.Dark;
MainPage = new MainPage(mainViewModel);
+ // MainPage = new Playground();
}
}
diff --git a/MauiSample/MainPage.xaml b/MauiSample/MainPage.xaml
index 44e97e6..cfd9e30 100644
--- a/MauiSample/MainPage.xaml
+++ b/MauiSample/MainPage.xaml
@@ -29,9 +29,9 @@
-
+
-
@@ -77,7 +77,8 @@
Orientation="Horizontal"
SegmentedOutlineColor="{StaticResource Gray950}"
SelectedIndex="{Binding Source={x:Reference Switcher}, Path=SelectedIndex, Mode=TwoWay}"
- TabType="Fixed">
+ TabType="Fixed"
+ UseMauiTapGesture="True">
(BottomTabsPageViewModel)BindingContext;
diff --git a/MauiSample/MauiSample.sln b/MauiSample/MauiSample.sln
index 8f2b1f7..e94d5a6 100644
--- a/MauiSample/MauiSample.sln
+++ b/MauiSample/MauiSample.sln
@@ -15,7 +15,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "configuration", "configurat
..\Sharpnado.Tabs.nuspec = ..\Sharpnado.Tabs.nuspec
EndProjectSection
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MauiShellSample", "..\MauiShellSample\MauiShellSample.csproj", "{75F26D59-6560-4B75-94ED-7A1947BEBF9A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MauiShellSample", "..\MauiShellSample\MauiShellSample.csproj", "{75F26D59-6560-4B75-94ED-7A1947BEBF9A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -35,6 +35,7 @@ Global
{528FB5B5-CBFA-4820-B915-937F2578807C}.Release|Any CPU.Build.0 = Release|Any CPU
{75F26D59-6560-4B75-94ED-7A1947BEBF9A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{75F26D59-6560-4B75-94ED-7A1947BEBF9A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {75F26D59-6560-4B75-94ED-7A1947BEBF9A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{75F26D59-6560-4B75-94ED-7A1947BEBF9A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{75F26D59-6560-4B75-94ED-7A1947BEBF9A}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
diff --git a/MauiSample/Playground.xaml b/MauiSample/Playground.xaml
new file mode 100644
index 0000000..76b3f9d
--- /dev/null
+++ b/MauiSample/Playground.xaml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MauiSample/Playground.xaml.cs b/MauiSample/Playground.xaml.cs
new file mode 100644
index 0000000..a3d12de
--- /dev/null
+++ b/MauiSample/Playground.xaml.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace MauiSample;
+
+public partial class Playground : ContentPage
+{
+ public Playground()
+ {
+ InitializeComponent();
+ }
+}
\ No newline at end of file
diff --git a/MauiSample/Presentation/CustomViews/RichLabel.cs b/MauiSample/Presentation/CustomViews/RichLabel.cs
index ba9a56b..d345178 100644
--- a/MauiSample/Presentation/CustomViews/RichLabel.cs
+++ b/MauiSample/Presentation/CustomViews/RichLabel.cs
@@ -53,7 +53,6 @@ private static void OnMarkdownPropertyChanged(BindableObject bindable, object ol
private static void OnBoldFontFamilyPropertyChanged(BindableObject bindable, object oldValue, object newValue)
{
- throw new System.NotImplementedException();
}
private void ProcessMarkdown(string markdown)
diff --git a/MauiSample/Presentation/ViewModels/TabsLayout/BottomTabsPageViewModel.cs b/MauiSample/Presentation/ViewModels/TabsLayout/BottomTabsPageViewModel.cs
index b8ab142..cf7d355 100644
--- a/MauiSample/Presentation/ViewModels/TabsLayout/BottomTabsPageViewModel.cs
+++ b/MauiSample/Presentation/ViewModels/TabsLayout/BottomTabsPageViewModel.cs
@@ -6,7 +6,7 @@ namespace MauiSample.Presentation.ViewModels
{
public class BottomTabsPageViewModel : ANavigableViewModel
{
- private int _selectedViewModelIndex = 0;
+ private int _selectedViewModelIndex;
public BottomTabsPageViewModel(
INavigationService navigationService,
@@ -16,6 +16,9 @@ public BottomTabsPageViewModel(
{
HomePageViewModel = new HomePageViewModel(navigationService, sillyDudeService);
GridPageViewModel = new GridPageViewModel(navigationService, sillyDudeService);
+
+ // If you want to start at the 3rd page
+ // SelectedViewModelIndex = 2;
}
public int SelectedViewModelIndex
diff --git a/MauiSample/Presentation/Views/TabM.xaml b/MauiSample/Presentation/Views/TabM.xaml
index f6b96ff..b5b2786 100644
--- a/MauiSample/Presentation/Views/TabM.xaml
+++ b/MauiSample/Presentation/Views/TabM.xaml
@@ -7,7 +7,7 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MauiSample/VerticalTabItem.xaml.cs b/MauiSample/VerticalTabItem.xaml.cs
new file mode 100644
index 0000000..d492058
--- /dev/null
+++ b/MauiSample/VerticalTabItem.xaml.cs
@@ -0,0 +1,58 @@
+using Sharpnado.Tabs;
+using System.Runtime.CompilerServices;
+
+namespace MauiSample
+{
+ public partial class VerticalTabItem : TabTextItem
+ {
+ public static readonly BindableProperty SelectorColorProperty = BindableProperty.Create(
+ nameof(SelectorColor),
+ typeof(Color),
+ typeof(TabTextItem),
+ Colors.DodgerBlue);
+
+ public Color SelectorColor
+ {
+ get => (Color)GetValue(SelectorColorProperty);
+ set => SetValue(SelectorColorProperty, value);
+ }
+
+ public VerticalTabItem()
+ {
+ InitializeComponent();
+
+ }
+
+ protected override void OnBadgeChanged(BadgeView oldBadge)
+ {
+ if (oldBadge != null)
+ {
+ Grid.Children.Remove(Badge);
+ return;
+ }
+
+ Grid.Children.Add(Badge);
+ }
+
+ protected override void OnPropertyChanged([CallerMemberName] string propertyName = null)
+ {
+ base.OnPropertyChanged(propertyName);
+
+ switch (propertyName)
+ {
+ case nameof(IsSelectable):
+ case nameof(UnselectedLabelColor):
+ case nameof(SelectedTabColor):
+ case nameof(IsSelected):
+ UpdateColors();
+ break;
+ }
+ }
+
+ private void UpdateColors()
+ {
+ InnerLabel.TextColor = IsSelectable ? IsSelected ? SelectedTabColor : UnselectedLabelColor : DisabledLabelColor;
+ Selector.BackgroundColor = SelectorColor;
+ }
+ }
+}
\ No newline at end of file
diff --git a/MauiShellSample/App.xaml b/MauiShellSample/App.xaml
index 76d14bc..6a00270 100644
--- a/MauiShellSample/App.xaml
+++ b/MauiShellSample/App.xaml
@@ -1,8 +1,8 @@
-
-
+
+ xmlns:local="clr-namespace:MauiShellSample">
diff --git a/MauiShellSample/AppShell.xaml b/MauiShellSample/AppShell.xaml
index 701e557..2c333cc 100644
--- a/MauiShellSample/AppShell.xaml
+++ b/MauiShellSample/AppShell.xaml
@@ -1,24 +1,21 @@
-
+
-
+
-
+
diff --git a/MauiShellSample/MainPage.xaml b/MauiShellSample/MainPage.xaml
index d858a21..28ee679 100644
--- a/MauiShellSample/MainPage.xaml
+++ b/MauiShellSample/MainPage.xaml
@@ -1,35 +1,29 @@
-
+
-
-
+
+
-
+
-
+
-
+
diff --git a/MauiShellSample/Resources/Styles/Colors.xaml b/MauiShellSample/Resources/Styles/Colors.xaml
index 6ab4277..9f5cdd5 100644
--- a/MauiShellSample/Resources/Styles/Colors.xaml
+++ b/MauiShellSample/Resources/Styles/Colors.xaml
@@ -1,10 +1,8 @@
-
+
-
+
#512BD4
#ac99ea
@@ -28,18 +26,18 @@
#212121
#141414
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
diff --git a/MauiShellSample/Resources/Styles/Styles.xaml b/MauiShellSample/Resources/Styles/Styles.xaml
index abfc935..6cdcb36 100644
--- a/MauiShellSample/Resources/Styles/Styles.xaml
+++ b/MauiShellSample/Resources/Styles/Styles.xaml
@@ -1,22 +1,20 @@
-
+
-
-
-
-