我跟着涼鞋大大的教程學習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();
}
}
}
}
現在這樣的代碼就能做出剛纔的效果, 我會接着持續更新