是否有小伙伴在使用tab的時候想進行滑動切換Tab? 並且有滑動左出左進,右出右進的效果 ,本文將講解怎麼在Blazor中去通過滑動切換Tab 本文中的UI組件使用的是MASA Blazor,您也可以是其他的UI框架,這個並不影響實際的運行效果,本文案例是相容PC和Android的,演示效果是and ...
是否有小伙伴在使用tab的時候想進行滑動切換Tab?
並且有滑動左出左進,右出右進的效果 ,本文將講解怎麼在Blazor
中去通過滑動切換Tab
本文中的UI組件使用的是MASA Blazor
,您也可以是其他的UI框架,這個並不影響實際的運行效果,本文案例是相容PC和Android的,演示效果是android中執行的,在PC中執行效果依然有效(親測)
首先安裝MASA Blazor
根據 MASA Blazor安裝MASA Blazor
準備工作
-
創建
AppBar.razor
文件 -
修改
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>
-
創建
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; } }
-
創建
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");
}
}
- 添加相關頁面,在
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>
- 修改
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>
- 創建
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
微信交流群: