Unity基於UIWidgets的UI入門(二簡單的入門)

我跟着涼鞋大大的教程學習widgets更新的優點慢,但是知識點很多,

這個是初步教程  做一個 輸入框存儲標籤和刪除標籤

這個例子他們官方有, 跟着涼大敲下來 加深我的理解

這一小節課中有一個很嚴重的bug 就是

屏幕分辨率達不到的話設置Container的寬度,和他的Margin值同時做的話 他們兩個的長度加起來超過當前屏幕的話就會報錯 這種錯誤是溢出錯誤。

他這種報錯有點難解決, 這個bug坑了我一個多小時。原因之一是英語差和沒看報錯信息

每次打開都有記錄的功能,用的unity自帶的PlayerPrefs類做的存儲和讀取。

我先錄製一個GIF

接下來我會粘貼上來代碼

這個類是對UIWidgets的常用類做的一些擴展

using System;
using System.Globalization;
using System.Collections;
using System.Collections.Generic;
using Unity.UIWidgets.gestures;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
using Unity.UIWidgets.foundation;

namespace MyTestUIWidgets.UIWidgets
{
    public class FQ
    {
        public static ContainerBuild Container => new ContainerBuild();
        public static TextBuilder Text => new TextBuilder();
        public static ListViewBuilder ListView => new ListViewBuilder();
        public static EditableTextBuilder EditableText => new EditableTextBuilder();
    }

    public class ContainerBuild
    {
        private Widget mChild { get; set; }
        private Alignment mAlignment { get; set; }
        private Color mColor { get; set; }
        private EdgeInsets mMargin = EdgeInsets.zero;
        //可控參數
        private float? mWidth = null;
        public static ContainerBuild GetBuilder()
        {
            return new ContainerBuild();
        }
        public ContainerBuild Child(Widget _child)
        {
            mChild = _child;
            return this;
        }
        public ContainerBuild Color(Color _color)
        {
            mColor = _color;
            return this;
        }
        public ContainerBuild Margin(EdgeInsets _edgInsets)
        {
            mMargin = _edgInsets;
            return this;
        }
        public ContainerBuild Width(float _width)
        {
            mWidth = _width;
            return this;
        }
        public ContainerBuild Alignment(Alignment _alignment)
        {
            mAlignment = _alignment;
            return this;
        }
        public Container EndContainer()
        {
            return new Container(child: mChild, alignment: mAlignment, color: mColor, width: mWidth, margin: mMargin);
        }
    }
    public class TextBuilder
    {
        private string mData { get; set; }
        private TextStyle mStyle { get; set; } = new TextStyle();
        private int mFontSize { get; set; }
        public static TextBuilder GetBuilder()
        {
            return new TextBuilder();
        }
        public TextBuilder Data(string _data)
        {
            mData = _data;
            return this;
        }
        public TextBuilder SetTextStyle(TextStyle _style)
        {
            mStyle = _style;
            return this;
        }
        public TextBuilder SetSize(int _fountSize)
        {
            mFontSize = _fountSize;
            return this;
        }
        public Text EndText()
        {
            if (mFontSize == 0)
            {
                return new Text(data: mData);
            }
            else
            {
                return new Text(data: mData, style: new TextStyle(fontSize: mFontSize));
            }
        }
    }
    public class ListViewBuilder
    {
        List<Widget> mChildren = new List<Widget>();
        EdgeInsets mPadding = null;
        public static ListViewBuilder GetBuilder()
        {
            return new ListViewBuilder();
        }
        public ListViewBuilder Padding(EdgeInsets _madding)
        {
            mPadding = _madding;
            return this;
        }
        public ListViewBuilder Child(List<Widget> _children)
        {
            mChildren = _children;
            return this;
        }
        public ListViewBuilder Child(Widget _child)
        {
            mChildren.Add(_child);
            return this;
        }
        public ListViewBuilder Child(params Widget[] _childeen)
        {
            mChildren.AddRange(_childeen);
            return this;
        }
        public ListView EndListView()
        {
            return new ListView(children: mChildren, padding: mPadding);
        }
    }
    public static class GestureDetectorExtension
    {
        public static GestureDetector OnTap(this Widget _widget, GestureTapCallback onTap)
        {
            return new GestureDetector(child: _widget, onTap: onTap);
        }
    }
    public class EditableTextBuilder
    {
        private TextEditingController mInputController = new TextEditingController(text: "");
        private FocusNode mFocusNode = new FocusNode();
        public TextStyle mStyle = new TextStyle();
        public Color mCursorColor = Color.black;
        public float mFontSize;
        ValueChanged<string> mOnValueChanged = null;
        ValueChanged<string> mOnSubmit = null;
        public EditableTextBuilder OnValueChanged(ValueChanged<string> _onValueChanged)
        {
            mOnValueChanged = _onValueChanged;
            return this;
        }
        public EditableTextBuilder OnSubmit(ValueChanged<string> _onSubmit)
        {
            mOnSubmit = _onSubmit;
            return this;
        }
        public EditableTextBuilder SetInputController(TextEditingController _inputController, FocusNode _focusNode, TextStyle _style, Color _cursorColor)
        {
            mInputController = _inputController;
            mFocusNode = _focusNode;
            mStyle = _style;
            mCursorColor = _cursorColor;
            return this;
        }
        public EditableTextBuilder FontSize(float size)
        {
            mFontSize = size;
            return this;
        }
        public EditableTextBuilder GetBuilder()
        {
            return new EditableTextBuilder();
        }
        public EditableText EndEditableTextBuilder()
        {
            return new EditableText(
                controller: mInputController,
                 focusNode: mFocusNode,
                 style: mFontSize == 0 ? mStyle : new TextStyle(fontSize: mFontSize),
                 cursorColor: mCursorColor,
                 onChanged: mOnValueChanged,
                 onSubmitted: mOnSubmit);
        }
    }

}

 

這個類是用來幫助TodoListApp類構建


using Color = Unity.UIWidgets.ui.Color;
using Unity.UIWidgets.foundation;
using System;
using System.Collections.Generic;
using MyTestUIWidgets.UIWidgets;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
using UnityEngine;

namespace MyTestUIWidgets.UIWidgets
{

    public class TodoView : StatelessWidget
    {
        private readonly string mData;
        private readonly Action mOnFinish;
        public TodoView(string data, Action onFinish)
        {
            mData = data;
            mOnFinish = onFinish;
        }
        public override Widget build(BuildContext context)
        {
            return FQ.Container
                    .Alignment(Alignment.center)
                    .Child(
                        FQ.Text
                        .Data(mData)
                        .SetSize(20).EndText()
                    )
                .EndContainer().OnTap(() =>
                {
                    mOnFinish();
                });
        }
    }
    public class TodoInputView : StatelessWidget
    {
        private string mInputContent = string.Empty;

        private Action<string> mOnAdd;
        public TodoInputView(Action<string> onAdd)
        {
            mOnAdd = onAdd;
        }
        public void AddTodo()
        {
            if (!string.IsNullOrWhiteSpace(mInputContent))
            {
                mOnAdd(mInputContent);
            }
        }
        public override Widget build(BuildContext context)
        {
            return
            new Container(child:
                new Row(children: new List<Widget>(){
                    FQ.Container.Width(190).Color(Color.white).Margin(EdgeInsets.only(left :15))
                    .Child(FQ.EditableText.FontSize(30)
                            .OnValueChanged(mInputContent => { this.mInputContent = mInputContent; } )
                            .OnSubmit(inputvalue => AddTodo())
                            .EndEditableTextBuilder()  )
                            .EndContainer(),
                            FQ.Container.Child(
                    FQ.Text.Data("+")
                    .SetSize(30)
                    .EndText()
                    .OnTap(() => {
                        AddTodo();
                     Debug.Log("On Tap");})
                            ).Margin(EdgeInsets.only(left:12)).EndContainer()
                    }//, mainAxisAlignment: Unity.UIWidgets.rendering.MainAxisAlignment.spaceBetween
            ));

        }
    }
}

這個TodoListApp類是用來構建APP界面

using System.Xml.Linq;
using System;
using System.Text;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using Unity.UIWidgets.engine;
using Unity.UIWidgets.painting;
using Unity.UIWidgets.widgets;
using UnityEngine;
using Color = Unity.UIWidgets.ui.Color;
using MyTestUIWidgets.UIWidgets;
using Unity.UIWidgets.foundation;

namespace MyTestUIWidgets
{
    public class TodoListApp : UIWidgetsPanel
    {
        protected override Widget createWidget()
        {
            return new TodoListPage();
        }
    }
    class TodoListPage : StatefulWidget
    {
        public override State createState()
        {
            return new TodoListState();
        }
    }
    class TodoListState : State<TodoListPage>
    {
        public override void initState()
        {
            //PlayerPrefs.DeleteAll();
            var toDoListContent = PlayerPrefs.GetString("TODO_LIST_KEY", string.Empty);
            var splitDatas = toDoListContent.Split(new[] { "@@@@" }, StringSplitOptions.None);
            mTodoDatas = splitDatas.Where(data => !string.IsNullOrEmpty(data)).ToList();
        }
        private List<string> mTodoDatas = null;
        public override Widget build(BuildContext context)
        {
            return FQ.ListView 
            .Child(new TodoInputView( data  => { AddState(data); }))
            .Child(TodoViews)
            .Padding(EdgeInsets.only(0, 50))
            .EndListView();
        }

        private void AddState( string data)
        {
            this.setState(() =>
            {
                mTodoDatas.Add(data);
                Save();
            });
        }
        void Save()
        {
            StringBuilder stringBuilder = new StringBuilder();
            mTodoDatas.ForEach(
                data =>
                {
                    stringBuilder.Append(data);
                    stringBuilder.Append("@@@@");

                }
            );
            PlayerPrefs.SetString("TODO_LIST_KEY", stringBuilder.ToString());
        }
        Widget[] TodoViews
        {
            get
            {
                return mTodoDatas.Select(data => new TodoView(data, () =>
                {
                    this.setState(() =>
                     {
                         mTodoDatas.Remove(data);
                         Save();
                     });
                })).ToArray();
            }
        }
    }
}

現在這樣的代碼就能做出剛纔的效果, 我會接着持續更新

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章