Unity_UIWidgets学习笔记02_轮播图实现

主要思路:利用Ticker定时切换TabBarView

1,搭建界面

public class MovePictore : StatefulWidget
{
    public List<Widget> AllImage;
    public MovePictore(List<Widget> allImage)
    {
        AllImage = allImage;
    }
    public override State createState()
    {
        return new MovePictoreState(AllImage);
    }
}
class MovePictoreState : SingleTickerProviderStateMixin<MovePictore>
{
    public List<Widget> AllImage;
    TabController tabController;

    public MovePictoreState(List<Widget> allImage)
    {
        AllImage = allImage;
    }
    public override Widget build(BuildContext context)
    {
        return new Scaffold(
           appBar: new AppBar(title: new Container(
              child: new Text("轮播图实现"),
              alignment: Alignment.center
               )
           ),
           body: new Stack(
           children: new List<Widget>()
           {
                new TabBarView(
                    controller: tabController,
                    children: AllImage
                ),
              new Align(
              alignment:new Alignment(0, 1),
              child:new  TabPageSelector(
              color: Colors.white,
              selectedColor: Colors.black,
              controller: tabController,
              indicatorSize:30
                    )
                )
             }
            )


           );
    }
    public override void initState()
    {
        base.initState();
        tabController = new TabController(length: 10, vsync: this);
    }
    public override void dispose()
    {
        tabController.dispose();
        base.dispose();
    }
}
View Code

2.添加 Ticker定时器

class MovePictoreState : SingleTickerProviderStateMixin<MovePictore>
{
    public List<Widget> AllImage;
    TabController tabController;
    private TimeSpan lastTime;//上次切换时间
    Ticker ticker;//定时器
    int index = 0;//当前Tag索引
    int timeout;//间隔时间
    public MovePictoreState(List<Widget> allImage)
    {
        AllImage = allImage;
    }
    public override Widget build(BuildContext context)
    {
        return new Scaffold(
           appBar: new AppBar(title: new Container(
              child: new Text("轮播图实现"),
              alignment: Alignment.center
               )
           ),
           body: new Stack(
           children: new List<Widget>()
           {
                new TabBarView(
                    controller: tabController,
                    children: AllImage
                ),
              new Align(
              alignment:new Alignment(0, 1),
              child:new  TabPageSelector(
              color: Colors.white,
              selectedColor: Colors.black,
              controller: tabController,
              indicatorSize:30
          )
        )
           }
               )


           );
    }
    public override void initState()
    {
        base.initState();
        tabController = new TabController(length: 10, vsync: this);
        ticker = new Ticker(tickCallback);
        ticker.start();
    }
       /// <summary>
       /// 每帧都调用
       /// </summary>
       /// <param name="elapsed">距离开始的时间</param>
    private void tickCallback(TimeSpan elapsed)
    {
        if (null != lastTime && elapsed.Seconds >= lastTime.Seconds)
        {
            if (elapsed.Seconds - lastTime.Seconds > timeout)
            {
                lastTime = elapsed;
                index++;
                tabController.animateTo(index % 10);
            }
        }
        else
        {
            lastTime = elapsed;
        }
    }
    public override void dispose()
    {
        tabController.dispose();
        base.dispose();
    }
}
View Code

3、点击切换

修改 TabPageSelectorIndicator类和TabPageSelector部分方法,添加了点击回调

public class TabPageSelectorIndicator : StatelessWidget
    {
        public TabPageSelectorIndicator(
           System.Action<int> gestureTapCallback,
            int index,
            Key key = null,
            Color backgroundColor = null,
            Color borderColor = null,
            float? size = null


        ) : base(key: key)
        {
            D.assert(backgroundColor != null);
            D.assert(borderColor != null);
            D.assert(size != null);

            this.backgroundColor = backgroundColor;
            this.borderColor = borderColor;
            this.size = size.Value;
            this.gestureTapCallback = gestureTapCallback;
            this.Index = index;
        }

        public readonly Color backgroundColor;

        public readonly int Index;
        public readonly Color borderColor;

        public readonly float size;
        System.Action<int> gestureTapCallback;
        public override Widget build(BuildContext context)
        {
            return new GestureDetector(
                child: new Container(
                width: this.size,
                height: this.size,
                margin: EdgeInsets.all(4.0f),
                decoration: new BoxDecoration(
                    color: this.backgroundColor,
                    border: Border.all(color: this.borderColor),
                    shape: BoxShape.circle
                )
            ),
                onTap: () =>
                {
                    if (null != gestureTapCallback)
                    {
                        gestureTapCallback.Invoke(Index);
                    }
                }
             );
        }
    }


    public class TabPageSelector : StatelessWidget
    {
        private System.Action<int> iconClick;
        public TabPageSelector(
            System.Action<int> iconClick = null,
            Key key = null,
            TabController controller = null,
            float indicatorSize = 12.0f,
            Color color = null,
            Color selectedColor = null
        ) : base(key: key)
        {
            D.assert(indicatorSize > 0.0f);
            this.controller = controller;
            this.indicatorSize = indicatorSize;
            this.color = color;
            this.selectedColor = selectedColor;
            this.iconClick = iconClick;
        }

        public readonly TabController controller;

        public readonly float indicatorSize;

        public readonly Color color;

        public readonly Color selectedColor;

        Widget _buildTabIndicator(
            int tabIndex,
            TabController tabController,
            ColorTween selectedColorTween,
            ColorTween previousColorTween)
        {
            Color background = null;
            if (tabController.indexIsChanging)
            {
                float t = 1.0f - TabsUtils._indexChangeProgress(tabController);
                if (tabController.index == tabIndex)
                {
                    background = selectedColorTween.lerp(t);
                }
                else if (tabController.previousIndex == tabIndex)
                {
                    background = previousColorTween.lerp(t);
                }
                else
                {
                    background = selectedColorTween.begin;
                }
            }
            else
            {
                float offset = tabController.offset;
                if (tabController.index == tabIndex)
                {
                    background = selectedColorTween.lerp(1.0f - offset.abs());
                }
                else if (tabController.index == tabIndex - 1 && offset > 0.0)
                {
                    background = selectedColorTween.lerp(offset);
                }
                else if (tabController.index == tabIndex + 1 && offset < 0.0)
                {
                    background = selectedColorTween.lerp(-offset);
                }
                else
                {
                    background = selectedColorTween.begin;
                }
            }

            return new TabPageSelectorIndicator(iconClick, tabIndex,
                backgroundColor: background,
                borderColor: selectedColorTween.end,
                size: this.indicatorSize
            );
        }

        public override Widget build(BuildContext context)
        {
            Color fixColor = this.color ?? Colors.transparent;
            Color fixSelectedColor = this.selectedColor ?? Theme.of(context).accentColor;
            ColorTween selectedColorTween = new ColorTween(begin: fixColor, end: fixSelectedColor);
            ColorTween previousColorTween = new ColorTween(begin: fixSelectedColor, end: fixColor);
            TabController tabController = this.controller ?? DefaultTabController.of(context);
            D.assert(() =>
            {
                if (tabController == null)
                {
                    throw new UIWidgetsError(
                        "No TabController for " + this.GetType() + ".\n" +
                        "When creating a " + this.GetType() + ", you must either provide an explicit TabController " +
                        "using the \"controller\" property, or you must ensure that there is a " +
                        "DefaultTabController above the " + this.GetType() + ".\n" +
                        "In this case, there was neither an explicit controller nor a default controller."
                    );
                }

                return true;
            });

            Animation<float> animation = new CurvedAnimation(
                parent: tabController.animation,
                curve: Curves.fastOutSlowIn
            );

            return new AnimatedBuilder(
                animation: animation,
                builder: (BuildContext subContext, Widget child) =>
                {
                    List<Widget> children = new List<Widget>();

                    for (int tabIndex = 0; tabIndex < tabController.length; tabIndex++)
                    {
                        children.Add(this._buildTabIndicator(
                            tabIndex,
                            tabController,
                            selectedColorTween,
                            previousColorTween)
                        );
                    }

                    return new Row(
                        mainAxisSize: MainAxisSize.min,
                        children: children
                    );
                }
            );
        }
    }
View Code
class MovePictoreState : SingleTickerProviderStateMixin<MovePictore>
{
    public List<Widget> AllImage;
    TabController tabController;
    private TimeSpan lastTime;//上次切换时间
    Ticker ticker;//定时器
    int index = 0;//当前Tag索引
    int timeout=2;//间隔时间
    bool isClick;//是否点击
    public MovePictoreState(List<Widget> allImage)
    {
        AllImage = allImage;
    }
    void click(int i)
    {
        isClick = true;
        index = i;
        tabController.animateTo(index);
    }
    public override Widget build(BuildContext context)
    {
        return new Scaffold(
           appBar: new AppBar(title: new Container(
              child: new Text("轮播图实现"),
              alignment: Alignment.center
               )
           ),
           body: new Stack(
           children: new List<Widget>()
           {
                new TabBarView(
                    controller: tabController,
                    children: AllImage
                ),
              new Align(
              alignment:new Alignment(0, 1),
              child:new  TabPageSelector(
              iconClick:click,
              color: Colors.white,
              selectedColor: Colors.black,
              controller: tabController,
              indicatorSize:30
          )
        )
           }
               )


           );
    }
    public override void initState()
    {
        base.initState();
        tabController = new TabController(length: AllImage.Count, vsync: this);
        ticker = new Ticker(tickCallback);
        ticker.start();
    }
    /// <summary>
    /// 每帧都调用
    /// </summary>
    /// <param name="elapsed">距离开始的时间</param>
    private void tickCallback(TimeSpan elapsed)
    {
        if (isClick)
        {
            //如何如果点击就跳过本次计时
            lastTime = elapsed;
            isClick = false;
        }
        else {
            if (null != lastTime && elapsed.Seconds >= lastTime.Seconds)
            {
                if (elapsed.Seconds - lastTime.Seconds > timeout)
                {
                    lastTime = elapsed;
                    index++;
                    tabController.animateTo(index % AllImage.Count);
                }
            }
            else
            {
                lastTime = elapsed;
            }
        }
        
    }
    public override void dispose()
    {
        tabController.dispose();
        base.dispose();
    }
}
View Code

 

猜你喜欢

转载自www.cnblogs.com/PandaHome/p/11103614.html
今日推荐