Small dishes continue to supplement the practical technical points encountered in daily learning;

LayoutBuilder

In some scenarios, small dishes need to display different subclass widgets according to the size of the parent class layout. For example, LayoutBuilder is used when small dishes are adapted to large-size flat panels or vertical and horizontal screen switches. LayoutBuilder is understood as the size layout constructor.

Source code analysis

Simple analysis of source code can be obtained, LayoutBuilder is an inherited from ConstrainedLayoutBuilder constructor; Get a BoxConstraints object from the Builder, and then check constraints to determine what to show;

class LayoutBuilder extends ConstrainedLayoutBuilder<BoxConstraints> {
  const LayoutBuilder({
    Key key,
    LayoutWidgetBuilder builder,
  }) : super(key: key, builder: builder);
}
Copy the code

Case try

A small dish displays a single line of ICONS by default on the GridView. The expectation is to display 4 items on most devices. As the screen grows, display as many items as possible, up to the maximum when the screen allows display of all items. Therefore, the width base of a single item is set to 90 for small dishes, which is judged by size. MaxWidth.

LayoutBuilder(builder: (context, size) { if (size.maxWidth ~/ 90 >= 4 && size.maxWidth ~/ 90 <= _dataList.length) { _length = size.maxWidth ~/ 90; } else if (size.maxWidth ~/ 90 > _dataList.length) { _length = _dataList.length; } else { _length = 4; } return _gridWid(); } _gridWid() { return GridView.builder( physics: ScrollPhysics(), primary: false, shrinkWrap: true, gridDelegate: SliverGridDelegateWithFixedCrossAxisCount (crossAxisCount: _length, mainAxisSpacing: 8.0, crossAxisSpacing: 8.0, childAspectRatio: 1), itemCount: _showMore? _dataList.length : _length, itemBuilder: (context, index) { var dataItem = _dataList[index]; if (index < _length - 1 || _showMore) { dataItem = _dataList[index]; } else { dataItem = _dataList[_dataList.length - 1]; } return GestureDetector( child: Container( color: Colors.white70, child: Column(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Icon(dataItem.icon), SizedBox(height: 4), Text(dataItem.text) ])), onTap: () {if (_length < _dataList. Length && dataitem. text == 'more ') {_showMore =! _showMore; setState(() {}); } toast. show(dataitem. text == 'more'? 'more' : _dataList[index]. Text, context, duration: toast.length_short, gravity: toast.bottom); }); }); }Copy the code

ReorderableListView

Draggable + DragTarget Draggable + DragTarget Draggable + DragTarget Draggable + DragTarget DragTarget

Source code analysis

ReorderableListView implements the children subclass item loading and onReorder drags the subitem to a new location.

ReorderableListView({Key Key, this.header, // list header title @required this.children, // list subclass item @required this.onReorder, // This. ScrollDirection = Axis. Vertical, horizontal or vertical this. Use only with children this.reverse = false, // whether to reverse})Copy the code

Case try

1. onReorder

OnReorder is the ReorderCallback callback when the item is dragged to a new location, in which the new and old array subscripts are returned for marking;

@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text('ReorderableListView Page'), body: ReorderableListView(header: Container(height: 200.0, child: ACEWave(waveWidth, waveHeight, 200.0, startOffsetXList: startOffsetX, startOffsetYList: startOffsetY, waveHeight: waveHeight, 200.0, startOffsetXList: startOffsetY, durationList: duration, waveColorList: colorList)), reverse: false, children: _listWid(), onReorder: (oldIndex, newIndex) { if (newIndex == _dataList.length) --newIndex; final temp = _dataList.removeAt(oldIndex); _dataList.insert(newIndex, temp); setState(() {}); })); } _listData(index) {return Padding(key: ValueKey(_dataList[index]), Padding: EdgeInsets. All (20.0), child: Row(children: <Widget>[Icon(_dataList[index]. Icon, color: color.black38), SizedBox(width: 10.0), Expanded(child: Text(_dataList[index].text)), Icon(Icons.arrow_right, color: Colors.black38) ])); } _listWid() => <Widget>[for (int i = 0; i < _dataList.length; i++) _listData(i)];Copy the code

2. scrollDirection

ScrollDirection indicates the sliding direction of the list, which is the same as that of a common ListView. It can be divided into Axis. Horizontal and Axis.

scrollDirection: Axis.horizontal,
Copy the code

3. header

Header is the current list header.

_headerWid(horizontal) {
  return horizontal
      ? Container()
      : Container(height: 200.0,
          child: ACEWave(waveWidth, waveHeight, 200.0,
              startOffsetXList: startOffsetX,
              startOffsetYList: startOffsetY,
              durationList: duration,
              waveColorList: colorList));
}
Copy the code

4. reverse

Reverse is whether to reverse, that is, whether the initial start is from the end;

reverse: true,
Copy the code

5. padding

Padding is the inside margin, but only for the children part of the list, not for the header;

Padding: EdgeInsets. All (40.0),Copy the code

Matters needing attention

  1. ReorderableListView does not have a constructor like ListView.builder, which requires that all items in the List be loaded at once.
  2. The outermost layer of all children items in the ReorderableListView must have a unique Key;
  3. In the course of the small dish test, when dragging to the last one, the number of dataList has been reduced since the item was removed before the item was added into the insert, and the newIndex needs to be reduced by one.

LayoutBuilder + ReorderableListView


Xiao CAI will continue to study and try small knowledge points of daily application; For the bottom of the research is not deep enough, if there is a mistake, please guide!

Source: Little Monk A Ce