经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 移动开发 » 微信开发 » 查看文章
Blazor如何实现类似于微信的Tab切换?
来源:cnblogs  作者:tokengo  时间:2023/1/28 8:46:12  对本文有异议

是否有小伙伴在使用tab的时候想进行滑动切换Tab?

并且有滑动左出左进,右出右进的效果 ,本文将讲解怎么在Blazor中去通过滑动切换Tab

本文中的UI组件使用的是MASA Blazor,您也可以是其他的UI框架,这个并不影响实际的运行效果,本文案例是兼容PC和Android的,演示效果是android中执行的,在PC中执行效果依然有效(亲测)

首先安装MASA Blazor 根据 MASA Blazor安装MASA Blazor

准备工作

  1. 创建 AppBar.razor文件

  2. 修改MainLayout.razor文件代码

  1. @inherits LayoutComponentBase
  2. <MApp>
  3. <AppBar>
  4. <div class="body">
  5. @Body
  6. </div>
  7. </AppBar>
  8. </MApp>
  9. <style>
  10. .body {
  11. /*设置内容高度 需要减去导航栏的高度*/
  12. height: calc(100vh - 48px);
  13. max-height: calc(100vh - 48px);
  14. }
  15. </style>
  1. 创建 AppBar.razor.css 文件并且添加相关代码 ,以下代码是为了实现切换的时候有一个出入效果,具体代码案例来自Animista - On-Demand CSS Animations Library

    1. /*左边滑动出*/
    2. .slide-out-left {
    3. -webkit-animation: slide-out-left 0.5s;
    4. animation: slide-out-left 0.5s;
    5. }
    6. /*右边滑动出*/
    7. .slide-out-right {
    8. -webkit-animation: slide-out-right 0.5s;
    9. animation: slide-out-right 0.5s;
    10. }
    11. /*右边滑动进*/
    12. .slide-in-right {
    13. -webkit-animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
    14. animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
    15. }
    16. /*左边滑动进*/
    17. .slide-in-left {
    18. -webkit-animation: slide-in-left 0.5s;
    19. animation: slide-in-left 0.5s;
    20. }
    21. @-webkit-keyframes slide-out-left {
    22. 0% {
    23. -webkit-transform: translateX(0);
    24. transform: translateX(0);
    25. opacity: 1;
    26. }
    27. 100% {
    28. -webkit-transform: translateX(-1000px);
    29. transform: translateX(-1000px);
    30. opacity: 0;
    31. }
    32. }
    33. @keyframes slide-out-left {
    34. 0% {
    35. -webkit-transform: translateX(0);
    36. transform: translateX(0);
    37. opacity: 1;
    38. }
    39. 100% {
    40. -webkit-transform: translateX(-1000px);
    41. transform: translateX(-1000px);
    42. opacity: 0;
    43. }
    44. }
    45. @-webkit-keyframes slide-out-right {
    46. 0% {
    47. -webkit-transform: translateX(0);
    48. transform: translateX(0);
    49. opacity: 1;
    50. }
    51. 100% {
    52. -webkit-transform: translateX(1000px);
    53. transform: translateX(1000px);
    54. opacity: 0;
    55. }
    56. }
    57. @keyframes slide-out-right {
    58. 0% {
    59. -webkit-transform: translateX(0);
    60. transform: translateX(0);
    61. opacity: 1;
    62. }
    63. 100% {
    64. -webkit-transform: translateX(1000px);
    65. transform: translateX(1000px);
    66. opacity: 0;
    67. }
    68. }
    69. @-webkit-keyframes slide-in-left {
    70. 0% {
    71. -webkit-transform: translateX(-1000px);
    72. transform: translateX(-1000px);
    73. opacity: 0;
    74. }
    75. 100% {
    76. -webkit-transform: translateX(0);
    77. transform: translateX(0);
    78. opacity: 1;
    79. }
    80. }
    81. @keyframes slide-in-left {
    82. 0% {
    83. -webkit-transform: translateX(-1000px);
    84. transform: translateX(-1000px);
    85. opacity: 0;
    86. }
    87. 100% {
    88. -webkit-transform: translateX(0);
    89. transform: translateX(0);
    90. opacity: 1;
    91. }
    92. }
    93. @-webkit-keyframes slide-in-right {
    94. 0% {
    95. -webkit-transform: translateX(1000px);
    96. transform: translateX(1000px);
    97. opacity: 0;
    98. }
    99. 100% {
    100. -webkit-transform: translateX(0);
    101. transform: translateX(0);
    102. opacity: 1;
    103. }
    104. }
    105. @keyframes slide-in-right {
    106. 0% {
    107. -webkit-transform: translateX(1000px);
    108. transform: translateX(1000px);
    109. opacity: 0;
    110. }
    111. 100% {
    112. -webkit-transform: translateX(0);
    113. transform: translateX(0);
    114. opacity: 1;
    115. }
    116. }
  2. 创建AppBar的模型用于动态添加导航栏, 创建AppBarDto.cs文件并添加相关代码

  1. public class AppBarDto
  2. {
  3. public string Key { get; set; }
  4. /// <summary>
  5. /// 标题
  6. /// </summary>
  7. public string Title { get; init; }
  8. /// <summary>
  9. /// 图标
  10. /// </summary>
  11. public string? Icon { get; set; }
  12. /// <summary>
  13. /// 路由
  14. /// </summary>
  15. public string Href { get; init; }
  16. public AppBarDto(string title, string href, string? icon = null)
  17. {
  18. Title = title;
  19. Icon = icon;
  20. Href = href;
  21. Key = Guid.NewGuid().ToString("N");
  22. }
  23. }
  1. 添加相关页面,在Pages文件夹下,分别创建Index.razor,Feature.razor,Friend.razor,PersonalCenter.razor

文件相关代码:
Index.razor

  1. @page "/"
  2. <h3>Index</h3>

Feature.razor

  1. @page "/feature"
  2. <h3>Feature</h3>

Friend.razor

  1. @page "/friend"
  2. <h3>Friend</h3>

PersonalCenter.razor

  1. @page "/personal-center"
  2. <h3>PersonalCenter</h3>
  1. 修改AppBar.razor代码
  1. <div class="@Class" @ontouchstart="TouchStart" @ontouchend="TouchEnd" @onmousedown="Mousedown" @onmouseup="Mouseup" style="height: 100%">
  2. @ChildContent
  3. </div>
  4. @*这里也可以是其他组件的Tab,其实只是记录当前的导航的数据*@
  5. <MTabs Centered
  6. BackgroundColor="indigo"
  7. ShowArrows="false"
  8. Value="selectModel.Key"
  9. Dark>
  10. @foreach (var i in AppBars)
  11. {
  12. <MTab Value="i.Key" OnClick="()=>GoHref(i)">
  13. @if (!string.IsNullOrEmpty(i.Icon))
  14. {
  15. <MIcon Dark>@i.Icon</MIcon>
  16. }
  17. @i.Title
  18. </MTab>
  19. }
  20. </MTabs>
  1. 创建AppBar.razor.cs 添加以下代码
  1. public partial class AppBar
  2. {
  3. #region Inject
  4. [Inject]
  5. public required NavigationManager NavigationManager { get; set; }
  6. #endregion
  7. private readonly List<AppBarDto> AppBars = new();
  8. [Parameter]
  9. public RenderFragment ChildContent { get; set; }
  10. private AppBarDto selectModel;
  11. private string Class { get; set; }
  12. protected override void OnInitialized()
  13. {
  14. AppBars.Add(new AppBarDto("首页", "/", "home"));
  15. AppBars.Add(new AppBarDto("好友", "/personal-center", "mdi-account-group-outline"));
  16. AppBars.Add(new AppBarDto("功能", "/feature", "mdi-wrench"));
  17. AppBars.Add(new AppBarDto("个人中心", "/personal-center", "mdi-badge-account-alert"));
  18. // 默认选择的导航标签
  19. selectModel = AppBars[0];
  20. base.OnInitialized();
  21. }
  22. /// <summary>
  23. /// 导航栏跳转
  24. /// </summary>
  25. /// <param name="appBar"></param>
  26. private void GoHref(AppBarDto appBar)
  27. {
  28. // 防止重复点击
  29. if(appBar == selectModel)
  30. {
  31. return;
  32. }
  33. // 当点击导航的索引大于现在导航时启动滑动效果
  34. if(AppBars.IndexOf(appBar) > AppBars.IndexOf(selectModel))
  35. {
  36. Class = "slide-out-left";
  37. Task.Run(async () =>
  38. {
  39. // 由于特效时间为0.5s 这里是等待特效完成
  40. await Task.Delay(450);
  41. NavigationManager.NavigateTo(selectModel.Href);
  42. Class = "slide-in-right";
  43. _ = InvokeAsync(StateHasChanged);
  44. });
  45. }
  46. // 当点击导航的索引小于现在导航时启动滑动效果
  47. else if (AppBars.IndexOf(appBar) < AppBars.IndexOf(selectModel))
  48. {
  49. Class = "slide-out-right";
  50. Task.Run(async () =>
  51. {
  52. // 由于特效时间为0.5s 这里是等待特效完成
  53. await Task.Delay(450);
  54. NavigationManager.NavigateTo(selectModel.Href);
  55. Class = "slide-in-left";
  56. _ = InvokeAsync(StateHasChanged);
  57. });
  58. }
  59. selectModel = appBar;
  60. NavigationManager.NavigateTo(appBar.Href);
  61. }
  62. /// <summary>
  63. /// 开始X坐标
  64. /// </summary>
  65. private double _startX;
  66. #region 移动端滑动处理
  67. /// <summary>
  68. /// 记录开始坐标
  69. /// </summary>
  70. /// <param name="args"></param>
  71. private void TouchStart(TouchEventArgs args)
  72. {
  73. var touch = args.ChangedTouches[0];
  74. _startX = touch.ScreenX;
  75. }
  76. private void TouchEnd(TouchEventArgs args)
  77. {
  78. var touch = args.ChangedTouches[0];
  79. Switchover((decimal)touch.ScreenX);
  80. }
  81. #endregion
  82. #region PC滑动处理
  83. /// <summary>
  84. /// 记录开始坐标
  85. /// </summary>
  86. /// <param name="args"></param>
  87. private void Mousedown(MouseEventArgs args)
  88. {
  89. _startX = args.ScreenX;
  90. }
  91. private void Mouseup(MouseEventArgs args)
  92. {
  93. Switchover((decimal)args.ScreenX);
  94. }
  95. #endregion
  96. private void Switchover(decimal screenX)
  97. {
  98. var index = AppBars.IndexOf(selectModel);
  99. // 限制过度滑动
  100. if (index == AppBars.Count || index > AppBars.Count)
  101. {
  102. return;
  103. }
  104. // 设置滑动最大位限制,达到这个限制才滑动生效
  105. var size = 200;
  106. // 需要滑动200才切换 如果开始坐标x大于 当前结束的x坐标往右边切换tab
  107. if ((decimal)_startX - size > screenX)
  108. {
  109. // 如果右边往左边滑动 当前索引是当前最大数量的话不需要切换
  110. if (index == AppBars.Count - 1)
  111. {
  112. return;
  113. }
  114. selectModel = AppBars[index + 1];
  115. Class = "slide-out-left";
  116. Task.Run(async () =>
  117. {
  118. // 由于特效时间为0.5s 这里是等待特效完成
  119. await Task.Delay(450);
  120. NavigationManager.NavigateTo(selectModel.Href);
  121. Class = "slide-in-right";
  122. _ = InvokeAsync(StateHasChanged);
  123. });
  124. }
  125. else if ((decimal)_startX + size < screenX)
  126. {
  127. // 如果左边往右边滑动 当前索引是0的话不需要切换
  128. if (index == 0)
  129. {
  130. return;
  131. }
  132. selectModel = AppBars[index - 1];
  133. Class = "slide-out-right";
  134. Task.Run(async () =>
  135. {
  136. // 由于特效时间为0.5s 这里是等待特效完成
  137. await Task.Delay(450);
  138. NavigationManager.NavigateTo(selectModel.Href);
  139. Class = "slide-in-left";
  140. _ = InvokeAsync(StateHasChanged);
  141. });
  142. }
  143. }
  144. }

运行效果:

一个热爱学习的token

原文链接:https://www.cnblogs.com/hejiale010426/p/17065146.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号