XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

STHApplication

【MAUI】寄当家——安卓端交易管理系统

公开
关注 0 Fork 0 Star 0
UTF-8
namespace JiDangJia.Views;

// A bounded native carousel follows the finger and wraps at both ends. Each page
// owns a vertical scroller, rather than placing the carousel in an unbounded stack.
public sealed class LoopPager : ContentView
{
    private readonly CarouselView carousel;
    private readonly ScrollView tabScroll;
    private readonly Label[] labels;
    private readonly BoxView[] lines;
    private readonly View[] tabViews;
    public LoopPager(string[] names,int selected,Func<int,View> create,Action<int> changed)
    {
        labels=new Label[names.Length];lines=new BoxView[names.Length];tabViews=new View[names.Length];
        carousel=new CarouselView{Loop=true,IsSwipeEnabled=true,HorizontalScrollBarVisibility=ScrollBarVisibility.Never,VerticalScrollBarVisibility=ScrollBarVisibility.Never,PeekAreaInsets=0};
        carousel.ItemTemplate=new DataTemplate(()=>
        {
            var host=new ContentView{HorizontalOptions=LayoutOptions.Fill,VerticalOptions=LayoutOptions.Fill};
            host.BindingContextChanged+=(_,_)=>{if(host.Content is IDisposable old)old.Dispose();host.Content=null;if(host.BindingContext is int index)host.Content=create(index);};return host;
        });
        var tabs=new HorizontalStackLayout{Spacing=20,Padding=new Thickness(18,7,18,7)};
        for(int i=0;i<names.Length;i++)
        {
            int index=i;labels[i]=Ui.Text(names[i],15);lines[i]=new BoxView{HeightRequest=3,CornerRadius=2};
            var label=labels[i];label.HorizontalTextAlignment=TextAlignment.Center;var item=Ui.Stack(label,lines[i]);item.Spacing=5;item.MinimumHeightRequest=44;item.VerticalOptions=LayoutOptions.Center;
            tabViews[i]=Ui.Tap(item,()=>{if(carousel.IsLoaded)carousel.ScrollTo(index,position:ScrollToPosition.Center,animate:false);else carousel.Position=index;return Task.CompletedTask;},names[i]);tabs.Add(tabViews[i]);
        }
        tabScroll=new ScrollView{Content=tabs,Orientation=ScrollOrientation.Horizontal,HorizontalScrollBarVisibility=ScrollBarVisibility.Never};
        var grid=new Grid{RowDefinitions=[new(GridLength.Auto),new(GridLength.Star)]};grid.Add(tabScroll);grid.Add(carousel,0,1);Content=grid;
        UpdateTabs(selected);carousel.ItemsSource=Enumerable.Range(0,names.Length).ToList();carousel.Position=selected;
        carousel.PositionChanged+=(_,e)=>{if(e.CurrentPosition<0||e.CurrentPosition>=names.Length)return;changed(e.CurrentPosition);UpdateTabs(e.CurrentPosition);};
    }
    private void UpdateTabs(int selected)
    {
        for(int i=0;i<labels.Length;i++){bool active=i==selected;labels[i].TextColor=active?Ui.Ink:Ui.Muted;labels[i].FontAttributes=active?FontAttributes.Bold:FontAttributes.None;lines[i].Color=active?Ui.Gold:Colors.Transparent;}
        if(tabScroll.IsLoaded)_=tabScroll.ScrollToAsync(tabViews[selected],ScrollToPosition.MakeVisible,true);
    }
}

internal sealed class PageScroller : RefreshView,IDisposable
{
    private Action? release;
    public PageScroller(Action? release=null){this.release=release;}
    public void Dispose(){var action=release;release=null;action?.Invoke();}
}