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

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

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

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

准备工作

  1. 创建 AppBar.razor文件

  2. 修改MainLayout.razor文件代码

@inherits LayoutComponentBase

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


    /*左边滑动出*/
    .slide-out-left {
    -webkit-animation: slide-out-left 0.5s;
    animation: slide-out-left 0.5s;
    } /*右边滑动出*/
    .slide-out-right {
    -webkit-animation: slide-out-right 0.5s;
    animation: slide-out-right 0.5s;
    } /*右边滑动进*/
    .slide-in-right {
    -webkit-animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
    animation: slide-in-right 0.5s cubic-bezier(0.250, 0.460, 0.450, 0.940) both;
    } /*左边滑动进*/
    .slide-in-left {
    -webkit-animation: slide-in-left 0.5s;
    animation: slide-in-left 0.5s;
    } @-webkit-keyframes slide-out-left {
    0% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    } 100% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
    }
    } @keyframes slide-out-left {
    0% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    } 100% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
    }
    } @-webkit-keyframes slide-out-right {
    0% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    } 100% {
    -webkit-transform: translateX(1000px);
    transform: translateX(1000px);
    opacity: 0;
    }
    } @keyframes slide-out-right {
    0% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    } 100% {
    -webkit-transform: translateX(1000px);
    transform: translateX(1000px);
    opacity: 0;
    }
    } @-webkit-keyframes slide-in-left {
    0% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
    } 100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    }
    } @keyframes slide-in-left {
    0% {
    -webkit-transform: translateX(-1000px);
    transform: translateX(-1000px);
    opacity: 0;
    } 100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    }
    }
    @-webkit-keyframes slide-in-right {
    0% {
    -webkit-transform: translateX(1000px);
    transform: translateX(1000px);
    opacity: 0;
    } 100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    }
    } @keyframes slide-in-right {
    0% {
    -webkit-transform: translateX(1000px);
    transform: translateX(1000px);
    opacity: 0;
    } 100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
    opacity: 1;
    }
    }
  2. 创建AppBar的模型用于动态添加导航栏, 创建AppBarDto.cs文件并添加相关代码

public class AppBarDto
{
public string Key { get; set; } /// <summary>
/// 标题
/// </summary>
public string Title { get; init; } /// <summary>
/// 图标
/// </summary>
public string? Icon { get; set; } /// <summary>
/// 路由
/// </summary>
public string Href { get; init; } public AppBarDto(string title, string href, string? icon = null)
{
Title = title;
Icon = icon;
Href = href;
Key = Guid.NewGuid().ToString("N");
}
}
  1. 添加相关页面,在Pages文件夹下,分别创建Index.razor,Feature.razor,Friend.razor,PersonalCenter.razor

文件相关代码:

Index.razor

@page "/"
<h3>Index</h3>

Feature.razor

@page "/feature"
<h3>Feature</h3>

Friend.razor

@page "/friend"
<h3>Friend</h3>

PersonalCenter.razor

@page "/personal-center"
<h3>PersonalCenter</h3>
  1. 修改AppBar.razor代码


<div class="@Class" @ontouchstart="TouchStart" @ontouchend="TouchEnd" @onmousedown="Mousedown" @onmouseup="Mouseup" style="height: 100%">
@ChildContent
</div> @*这里也可以是其他组件的Tab,其实只是记录当前的导航的数据*@
<MTabs Centered
BackgroundColor="indigo"
ShowArrows="false"
Value="selectModel.Key"
Dark>
@foreach (var i in AppBars)
{
<MTab Value="i.Key" OnClick="()=>GoHref(i)">
@if (!string.IsNullOrEmpty(i.Icon))
{
<MIcon Dark>@i.Icon</MIcon>
}
@i.Title
</MTab>
}
</MTabs>
  1. 创建AppBar.razor.cs 添加以下代码

public partial class AppBar
{
#region Inject [Inject]
public required NavigationManager NavigationManager { get; set; } #endregion private readonly List<AppBarDto> AppBars = new(); [Parameter]
public RenderFragment ChildContent { get; set; } private AppBarDto selectModel; private string Class { get; set; } protected override void OnInitialized()
{
AppBars.Add(new AppBarDto("首页", "/", "home"));
AppBars.Add(new AppBarDto("好友", "/personal-center", "mdi-account-group-outline"));
AppBars.Add(new AppBarDto("功能", "/feature", "mdi-wrench"));
AppBars.Add(new AppBarDto("个人中心", "/personal-center", "mdi-badge-account-alert")); // 默认选择的导航标签
selectModel = AppBars[0]; base.OnInitialized();
} /// <summary>
/// 导航栏跳转
/// </summary>
/// <param name="appBar"></param>
private void GoHref(AppBarDto appBar)
{
// 防止重复点击
if(appBar == selectModel)
{
return;
} // 当点击导航的索引大于现在导航时启动滑动效果
if(AppBars.IndexOf(appBar) > AppBars.IndexOf(selectModel))
{
Class = "slide-out-left";
Task.Run(async () =>
{
// 由于特效时间为0.5s 这里是等待特效完成
await Task.Delay(450);
NavigationManager.NavigateTo(selectModel.Href);
Class = "slide-in-right";
_ = InvokeAsync(StateHasChanged);
});
}
// 当点击导航的索引小于现在导航时启动滑动效果
else if (AppBars.IndexOf(appBar) < AppBars.IndexOf(selectModel))
{
Class = "slide-out-right";
Task.Run(async () =>
{
// 由于特效时间为0.5s 这里是等待特效完成
await Task.Delay(450);
NavigationManager.NavigateTo(selectModel.Href);
Class = "slide-in-left";
_ = InvokeAsync(StateHasChanged);
});
}
selectModel = appBar;
NavigationManager.NavigateTo(appBar.Href);
} /// <summary>
/// 开始X坐标
/// </summary>
private double _startX; #region 移动端滑动处理 /// <summary>
/// 记录开始坐标
/// </summary>
/// <param name="args"></param>
private void TouchStart(TouchEventArgs args)
{
var touch = args.ChangedTouches[0];
_startX = touch.ScreenX;
} private void TouchEnd(TouchEventArgs args)
{
var touch = args.ChangedTouches[0];
Switchover((decimal)touch.ScreenX);
} #endregion #region PC滑动处理 /// <summary>
/// 记录开始坐标
/// </summary>
/// <param name="args"></param>
private void Mousedown(MouseEventArgs args)
{
_startX = args.ScreenX;
} private void Mouseup(MouseEventArgs args)
{
Switchover((decimal)args.ScreenX);
} #endregion private void Switchover(decimal screenX)
{
var index = AppBars.IndexOf(selectModel);
// 限制过度滑动
if (index == AppBars.Count || index > AppBars.Count)
{
return;
} // 设置滑动最大位限制,达到这个限制才滑动生效
var size = 200; // 需要滑动200才切换 如果开始坐标x大于 当前结束的x坐标往右边切换tab
if ((decimal)_startX - size > screenX)
{
// 如果右边往左边滑动 当前索引是当前最大数量的话不需要切换
if (index == AppBars.Count - 1)
{
return;
}
selectModel = AppBars[index + 1];
Class = "slide-out-left"; Task.Run(async () =>
{
// 由于特效时间为0.5s 这里是等待特效完成
await Task.Delay(450);
NavigationManager.NavigateTo(selectModel.Href);
Class = "slide-in-right";
_ = InvokeAsync(StateHasChanged);
});
}
else if ((decimal)_startX + size < screenX)
{
// 如果左边往右边滑动 当前索引是0的话不需要切换
if (index == 0)
{
return;
}
selectModel = AppBars[index - 1];
Class = "slide-out-right";
Task.Run(async () =>
{
// 由于特效时间为0.5s 这里是等待特效完成
await Task.Delay(450);
NavigationManager.NavigateTo(selectModel.Href);
Class = "slide-in-left";
_ = InvokeAsync(StateHasChanged);
});
}
}
}

运行效果:

一个热爱学习的token

qq交流群:737776595

微信交流群:

最新文章

  1. 快手 KSCAD 5.0 矢量图形设计软件
  2. Cubieboard2裸机开发之(一)点亮板载LED
  3. Unity3D 纹理偏移(TextureOffset)浅析
  4. DP三角形
  5. Polyline转Polygon
  6. C#this的五种用法
  7. Bitly缩短网址服务 - Blog透视镜
  8. Android图片与旋转
  9. box-sizing 属性应用
  10. 502 VS 504
  11. @ExceptionHandler异常统一处理
  12. LeetCode 15 3Sum [sort] &lt;c++&gt;
  13. [Swift]LeetCode766. 托普利茨矩阵 | Toeplitz Matrix
  14. 个人技术博客--团队Git规范(参考西瓜学长)
  15. P4246 [SHOI2008]堵塞的交通
  16. [转]C和C++运行时库
  17. TZOJ 2018 SPF(连通图割点和分成的连通块)
  18. 为什么要用Markov chain Monte Carlo (MCMC)
  19. 20165207 2017-2018-2《Java程序设计》课程总结
  20. 开源大数据技术专场(上午):Spark、HBase、JStorm应用与实践

热门文章

  1. 【MySQL】03_数据类型
  2. Dapr实现.Net Grpc服务之间的发布和订阅,并采用WebApi类似的事件订阅方式
  3. html+css 面试题总结附答案
  4. day03-CSS
  5. 安装 TypeScript 并编译成JS
  6. 根据经纬度算UTM带号
  7. 数电第三周周结_by_yc
  8. 用excel表画一个乐高
  9. 编程思想的转变 软件开发目录规范 collections、time、datetime、 random模块
  10. ORM常用字段与参数(自定义字段)