青岛建站合作,德阳建设公司网站,网站运营计划,网站整站开发教程今天使用这个控件#xff0c;做一个模仿微信“按住-说话”的小功能#xff0c;最终效果如下#xff1a; 使用.NET MAUI实现跨平台支持#xff0c;本项目可运行于Android、iOS平台。
创建页面布局
新建.NET MAUI项目#xff0c;命名HoldAndSpeak MainPage.xaml中创建一个…今天使用这个控件做一个模仿微信“按住-说话”的小功能最终效果如下 使用.NET MAUI实现跨平台支持本项目可运行于Android、iOS平台。
创建页面布局
新建.NET MAUI项目命名HoldAndSpeak MainPage.xaml中创建一个PitContentLayoutGrid容器并对Grid容器进行如下布局
在手机屏幕的底部设置两行两列的布局
第一行第一列对应取消发送手势区域 第一行第二列对应语音转文字手势区域 第二行独占两列对应发送手势区域。
布局如下图所示 Grid x:NamePitContentLayoutOpacity1Grid.RowDefinitionsRowDefinition Height1* /RowDefinition Height1* //Grid.RowDefinitionsGrid.ColumnDefinitionsColumnDefinition Width1* /ColumnDefinition Width1* //Grid.ColumnDefinitions
/Grid创建三个PitGrid控件并对这三个功能区域的PitGrid控件命名CancelPit、TransliterationPit分别对应了取消发送、语音转文字、发送。
为每个PitGrid控件添加内容
发送区域是一个底部弧形区域我们用一个巨大的圆形Y轴方向的偏移通过只保留屏幕底部往上的一部分圆形区域来实现底部弧形区域的效果代码如下
BoxView TranslationY450x:NameSendBoxHeightRequest1000WidthRequest1000CornerRadius500
/BoxView取消发送和语音转文字区域是一个圆形区域我们用一个正常大小的圆形来实现。
PitContentLayout区域整体代码如下
Grid x:NamePitContentLayoutOpacity1Grid.RowDefinitionsRowDefinition Height1* /RowDefinition Height1* //Grid.RowDefinitionsGrid.ColumnDefinitionsColumnDefinition Width1* /ColumnDefinition Width1* //Grid.ColumnDefinitionscontrols1:PitGrid x:NameCancelPitTranslationX-40PitNameCancelPitBoxView x:NameCancelBoxHeightRequest80WidthRequest80CornerRadius50Margin7.5Color{StaticResource PhoneContrastBackgroundBrush}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpand/BoxViewLabel x:NameCancelLabelTextColor{StaticResource PhoneContrastForegroundBrush}FontFamilyFontAwesomeFontSize28Rotation-10HorizontalOptionsCenterAndExpandMargin0/Label/controls1:PitGridcontrols1:PitGrid x:NameTransliterationPitPitNameTransliterationPitTranslationX40Grid.Column1BoxView x:NameTransliterationBoxHeightRequest80WidthRequest80CornerRadius50Margin7.5Color{StaticResource PhoneContrastBackgroundBrush}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpand/BoxViewLabel x:NameTransliterationLabelTextColor{StaticResource PhoneContrastForegroundBrush}FontSize28Text文Rotation10HorizontalOptionsCenterAndExpandMargin0/Label/controls1:PitGridcontrols1:PitGrid x:NameSendPitPitNameSendPitGrid.ColumnSpan2Grid.Row1BoxView TranslationY450x:NameSendBoxHeightRequest1000WidthRequest1000CornerRadius500Margin7.5Color{StaticResource PhoneContrastBackgroundBrush}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpand/BoxViewLabel x:NameSendLabelTranslationY30FontSize28Rotation45TextColor{StaticResource PhoneContrastForegroundBrush}FontFamilyFontAwesomeHorizontalOptionsCenterAndExpandMargin0/Label/controls1:PitGrid/Grid
效果如下 创建手势控件
创建一个手势控件。他包裹的内容。是一个带有按住说话的按钮。 controls1:PanContainer BackgroundColorTransparentx:NameDefaultPanContainerOnTappedDefaultPanContainer_OnOnTappedAutoAdsorptionFalseOnfinishedChoiseDefaultPanContainer_OnOnfinishedChoiseGrid PropertyChangedBindableObject_OnPropertyChangedVerticalOptionsStartHorizontalOptionsStartBoxView HeightRequest80WidthRequest250Margin7.5Color{StaticResource PhoneContrastBackgroundBrush}/BoxViewLabel x:NamePauseLabelHorizontalOptionsCenterAndExpandFontSize28TextColor{StaticResource PhoneForegroundBrush}Text按住 说话Margin0/Label/Grid/controls1:PanContainer此时应该是可以拖动并且在拖拽开始进入pit离开pit释放时分别触发StartInOutOver四个状态。 但我们希望在拖拽时隐藏这个按钮这将在创建动画章节将介绍。
创建TalkBox
创建一个圆角矩形用来显示正在说话的动画。
Grid Grid.Row1Opacity1x:NameTalkBoxLayoutBoxView x:NameTalkBoxHeightRequest80WidthRequest200CornerRadius20Margin7.5Color{StaticResource PhoneAccentBrush}VerticalOptionsCenterAndExpandHorizontalOptionsCenterAndExpand/BoxViewcontrols:PlayingMotionView HorizontalOptionsCenterAndExpandx:NameMotionViewMargin0/controls:PlayingMotionView/Grid
/Grid效果如下 创建动画
拖拽物动画
在拖拽时我们希望可以隐藏拖拽物设置 PanScale和PanScaleAnimationLength属性为0代码如下
controls1:PanContainer BackgroundColorTransparentx:NameDefaultPanContainerOnTappedDefaultPanContainer_OnOnTappedAutoAdsorptionFalsePanScale0.0PanScaleAnimationLength0按钮激活动画
Codebeind代码中配置Active和DeActive方法用于激活和取消激活功能区域按钮的样式。
激活时对应功能区域按钮背景颜色变为白色字体颜色变为黑色并且放大到1.2倍。 取消激活时恢复到原来的样式。 代码如下
private void Active(BoxView currentContent, Label text, Color toColor, Color txtToColor, double scaleTo 1.2)
{currentContent.AbortAnimation(ActivateFunctionAnimations);var parentAnimation new Animation();var txtFromColor text.TextColor;var animation2 new Animation(t text.TextColor GetColor(t, txtFromColor, txtToColor), 0, 1, Easing.SpringOut);var fromColor currentContent.Color;var animation4 new Animation(t currentContent.Color GetColor(t, fromColor, toColor), 0, 1, Easing.SpringOut);var animation5 new Animation(v currentContent.Scale v, currentContent.Scale, scaleTo);parentAnimation.Add(0, 1, animation2);parentAnimation.Add(0, 1, animation4);parentAnimation.Add(0, 1, animation5);parentAnimation.Commit(this, ActivateFunctionAnimations, 16, 300);
}private void DeActive(BoxView currentContent, Label text)
{currentContent.AbortAnimation(DeactivateFunctionAnimations);var parentAnimation new Animation();var txtFromColor text.TextColor;var txtToColor (Color)Application.Current.Resources[PhoneContrastForegroundBrush];var animation2 new Animation(t text.TextColor GetColor(t, txtFromColor, txtToColor), 0, 1, Easing.SpringOut);var fromColor currentContent.Color;var toColor (Color)Application.Current.Resources[PhoneContrastBackgroundBrush];var animation4 new Animation(t currentContent.Color GetColor(t, fromColor, toColor), 0, 1, Easing.SpringOut);var animation5 new Animation(v currentContent.Scale v, currentContent.Scale, 1.0);parentAnimation.Add(0, 1, animation2);parentAnimation.Add(0, 1, animation4);parentAnimation.Add(0, 1, animation5);parentAnimation.Commit(this, DeactivateFunctionAnimations, 16, 300);
}在拖拽进入pit的事件中设置激活状态在拖拽离开pit的事件中设置取消激活状态。 case PanType.Out:switch (args.CurrentPit?.PitName){case CancelPit:DeActive(this.CancelBox, this.CancelLabel);break;case SendPit:DeActive(this.SendBox, this.SendLabel);break;case TransliterationPit:DeActive(this.TransliterationBox, this.TransliterationLabel);break;default:break;}break;
case PanType.In:var parentAnimation new Animation();Color toColor default;double translationX default;double width default;switch (args.CurrentPit?.PitName){case CancelPit:Active(this.CancelBox, this.CancelLabel, Colors.White, Colors.Black);this.TalkBox.AbortAnimation(TalkBoxAnimations);break;case SendPit:Active(this.SendBox, this.SendLabel, Colors.Gray, Colors.Black, 1.0);break;case TransliterationPit:Active(this.TransliterationBox, this.TransliterationLabel, Colors.White, Colors.Black);break;default:break;}TalkBox动画
创建GetColor方法使用插值法用于获取渐变过程中获取当前进度的颜色 private Color GetColor(double t, Color fromColor, Color toColor){return Color.FromRgba(fromColor.Red t * (toColor.Red - fromColor.Red),fromColor.Green t * (toColor.Green - fromColor.Green),fromColor.Blue t * (toColor.Blue - fromColor.Blue),fromColor.Alpha t * (toColor.Alpha - fromColor.Alpha));}在进入功能区域时TalkBox的颜色偏移量和宽度都会发生变化创建一个复合动画TalkBoxAnimations用于触发TalkBox的动画效果。
this.TalkBox.AbortAnimation(TalkBoxAnimations);var fromColor this.TalkBox.Color;var animation2 new Animation(t this.TalkBox.Color GetColor(t, fromColor, toColor), 0, 1, Easing.SpringOut);
var animation4 new Animation(v this.TalkBoxLayout.TranslationX v, this.TalkBoxLayout.TranslationX, translationX);
var animation5 new Animation(v this.TalkBox.WidthRequest v, this.TalkBox.Width, width);parentAnimation.Add(0, 1, animation2);
parentAnimation.Add(0, 1, animation4);
parentAnimation.Add(0, 1, animation5);parentAnimation.Commit(this, TalkBoxAnimations, 16, 300);最终效果如下 Layout动画
创建一个用于显示功能区域和TalkBox的渐变动画用于在拖拽开始和结束时显示和隐藏这两个控件。
private void ShowLayout(double opacity 1)
{this.PitContentLayout.FadeTo(opacity);this.TalkBoxLayout.FadeTo(opacity);
}case PanType.Over:ShowLayout(0);break;
case PanType.Start:ShowLayout();break;项目地址
Github:maui-samples