我們開發(fā)中經(jīng)常會遇到一些標簽如商品的SKU等,我們可以用Wrap來擼一個同時也談?wù)剬lutter布局的自己一些理解先看效果
首先我們先看一下系統(tǒng)給我們提供的Wrap
Wrap({
Key key,
this.direction = Axis.horizontal,
this.alignment = WrapAlignment.start,
this.spacing = 0.0,
this.runAlignment = WrapAlignment.start,
this.runSpacing = 0.0,
this.crossAxisAlignment = WrapCrossAlignment.start,
this.textDirection,
this.verticalDirection = VerticalDirection.down,
List<Widget> children = const <Widget>[],
}) : super(key: key, children: children);
提供了很多屬性,介紹一下屬性都是干嘛的
- direction 擴展方式 比如橫向堆砌
- alignment 對齊方式
- spacing 主軸空隙間距
- runAlignment run的對齊方式
- runSpacing run空隙間距
- crossAxisAlignment 交叉軸對齊方式
- textDirection 文本對齊方向
- verticalDirection 確定垂直放置子元素的順序萝勤,以及如何在垂直方向上解釋開始和結(jié)束蛔外,默認down
- children 需要放置的組件列表
其實大家最好的方式就是寫一個試試然后隨意修改這些屬性這樣看起來比較直觀.
然后說一下如何實現(xiàn)標簽云
我的大致思路是用一個數(shù)組來記錄選中和非選中的狀態(tài),然后在按鈕中調(diào)用setState來修改數(shù)組中的狀態(tài),同時更新組件,那么說干就干
List<String> titles = ["張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰"];
//此處聲明一個狀態(tài)數(shù)組默認第一個是選中狀態(tài)
List<bool> colorCheck = [true, false, false, false, false, false, false ];
//定義Wrap上的子組件,樣式我們定義好,方法返回一個Widget傳入一個index索引的參數(shù)
Widget _addbtn(index)
{
Radius radius = Radius.circular(20);
return GestureDetector(
onTap: () {
setState(() {
//標記誰被選中了更改為ture其他改為false
for (int i = 0; i < colorCheck.length; i++) {
colorCheck[i] = (i == index);
}
});
},
child: Container(
height: 40,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent.withAlpha(60), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5)),
color: colorCheck[index] ? Colors.blueAccent : Colors.white,
),
child: Container(
margin: EdgeInsets.all(8),
child: Text(titles[index]),
),
),
);
}
定義好我們Wrap上的子控件,下一步我們要通過索引標記每個子控件.我們看到Wrap屬性中 List<Widget> children = const <Widget>[],有一個數(shù)組我們創(chuàng)建一個同樣的數(shù)組然后賦給Wrap.
其中用到了asMap,不熟悉的朋友可以查看一下
List<Widget> _widgets(State state) {
return titles.asMap().keys.map((index) => _addbtn(index)).toList();
}
定義好后,我們在Wrap處調(diào)用
child: new Wrap(
alignment: WrapAlignment.start,
children: _widgets(this),
),
大功告成!
附上整個Widget中完整的代碼方便大家指正
import 'package:flutter/material.dart';
class TagWidget extends StatefulWidget {
@override
_TagWidgetState createState() => _TagWidgetState();
}
class _TagWidgetState extends State<TagWidget> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar:AppBar(
title: Text("Wrap"),
),
body: Container(
margin: const EdgeInsets.only(left:20,top: 15.0, bottom: 13.0,right: 0.0),
child: SingleChildScrollView(
scrollDirection: Axis.vertical,
child: new Wrap(
alignment: WrapAlignment.start,
children: _widgets(this),
),
)
)
);
}
//初始化
List<String> titles = ["張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","張三", "張三是弟弟", "李四來了", "我","一次搞定","哈哈","你是誰","李四來了", "我","一次搞定","哈哈","你是誰","李四來了", "我","一次搞定","哈哈","你是誰","李四來了", "我","一次搞定","哈哈","你是誰","李四來了", "我","一次搞定","哈哈","你是誰"];
List<bool> colorCheck = [true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false,true, false, false, false,false,false,false, false, false, false,false,false,false, false, false, false,false,false,false, false, false, false,false,false,false, false, false, false,false,false,false];
Widget _addbtn(index)
{
Radius radius = Radius.circular(20);
return GestureDetector(
onTap: () {
setState(() {
for (int i = 0; i < colorCheck.length; i++) {
colorCheck[i] = (i == index);
}
});
},
child: Container(
height: 40,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent.withAlpha(60), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5)),
color: colorCheck[index] ? Colors.blueAccent : Colors.white,
),
child: Container(
margin: EdgeInsets.all(8),
child: Text(titles[index]),
),
),
);
}
List<Widget> _widgets(State state) {
return titles.asMap().keys.map((index) => _addbtn(index)).toList();
}
}
class TagItem extends StatelessWidget {
final String text;
TagItem(this.text);
@override
Widget build(BuildContext context) {
return Container(
height: 40,
margin: EdgeInsets.symmetric(vertical: 5, horizontal: 5),
decoration: BoxDecoration(
border: Border.all(color: Colors.blueAccent.withAlpha(60), width: 1.0),
borderRadius: BorderRadius.all(Radius.circular(5))),
child: Container(
margin: EdgeInsets.all(8),
child: Text(text),
),
);
}
}