zoukankan      html  css  js  c++  java
  • flutter 列表

    import 'package:flutter/foundation.dart';
    import 'package:flutter/material.dart';
    
    
    
    void main() {
      runApp(new AnimatedListSample());
    }
    
    class AnimatedListSample extends StatefulWidget {
      @override
      _AnimatedListSampleState createState() => new _AnimatedListSampleState();
    }
    
    class _AnimatedListSampleState extends State<AnimatedListSample> {
      final GlobalKey<AnimatedListState> _listKey = new GlobalKey<AnimatedListState>();
      ListModel<int> _list;
      int _selectedItem;
      int _nextItem; // The next item inserted when the user presses the '+' button.
    
      @override
      void initState() {
        super.initState();
        _list = new ListModel<int>(
          listKey: _listKey,
          initialItems: <int>[0, 1, 2],
          removedItemBuilder: _buildRemovedItem,
        );
        _nextItem = 3;
      }
    
      // Used to build list items that haven't been removed.
      Widget _buildItem(BuildContext context, int index, Animation<double> animation) {
        return new CardItem(
          animation: animation,
          item: _list[index],
          selected: _selectedItem == _list[index],
          onTap: () {
            setState(() {
              _selectedItem = _selectedItem == _list[index] ? null : _list[index];
            });
          },
        );
      }
    
      // Used to build an item after it has been removed from the list. This method is
      // needed because a removed item remains  visible until its animation has
      // completed (even though it's gone as far this ListModel is concerned).
      // The widget will be used by the [AnimatedListState.removeItem] method's
      // [AnimatedListRemovedItemBuilder] parameter.
      Widget _buildRemovedItem(int item, BuildContext context, Animation<double> animation) {
        return new CardItem(
          animation: animation,
          item: item,
          selected: false,
          // No gesture detector here: we don't want removed items to be interactive.
        );
      }
    
      // Insert the "next item" into the list model.
      void _insert() {
        final int index = _selectedItem == null ? _list.length : _list.indexOf(_selectedItem);
        _list.insert(index, _nextItem++);
      }
    
      // Remove the selected item from the list model.
      void _remove() {
        if (_selectedItem != null) {
          _list.removeAt(_list.indexOf(_selectedItem));
          setState(() {
            _selectedItem = null;
          });
        }
      }
    
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new Scaffold(
            appBar: new AppBar(
              title: const Text('AnimatedList'),
              actions: <Widget>[
                new IconButton(
                  icon: const Icon(Icons.add_circle),
                  onPressed: _insert,
                  tooltip: 'insert a new item',
                ),
                new IconButton(
                  icon: const Icon(Icons.remove_circle),
                  onPressed: _remove,
                  tooltip: 'remove the selected item',
                ),
              ],
            ),
            body: new Padding(
              padding: const EdgeInsets.all(16.0),
              child: new AnimatedList(
                key: _listKey,
                initialItemCount: _list.length,
                itemBuilder: _buildItem,
              ),
            ),
          ),
        );
      }
    }
    
    /// Keeps a Dart List in sync with an AnimatedList.
    ///
    /// The [insert] and [removeAt] methods apply to both the internal list and the
    /// animated list that belongs to [listKey].
    ///
    /// This class only exposes as much of the Dart List API as is needed by the
    /// sample app. More list methods are easily added, however methods that mutate the
    /// list must make the same changes to the animated list in terms of
    /// [AnimatedListState.insertItem] and [AnimatedList.removeItem].
    class ListModel<E> {
      ListModel({
        @required this.listKey,
        @required this.removedItemBuilder,
        Iterable<E> initialItems,
      }) : assert(listKey != null),
            assert(removedItemBuilder != null),
            _items = new List<E>.from(initialItems ?? <E>[]);
    
      final GlobalKey<AnimatedListState> listKey;
      final dynamic removedItemBuilder;
      final List<E> _items;
    
      AnimatedListState get _animatedList => listKey.currentState;
    
      void insert(int index, E item) {
        _items.insert(index, item);
        _animatedList.insertItem(index);
      }
    
      E removeAt(int index) {
        final E removedItem = _items.removeAt(index);
        if (removedItem != null) {
          _animatedList.removeItem(index, (BuildContext context, Animation<double> animation) {
            return removedItemBuilder(removedItem, context, animation);
          });
        }
        return removedItem;
      }
    
      int get length => _items.length;
      E operator [](int index) => _items[index];
      int indexOf(E item) => _items.indexOf(item);
    }
    
    /// Displays its integer item as 'item N' on a Card whose color is based on
    /// the item's value. The text is displayed in bright green if selected is true.
    /// This widget's height is based on the animation parameter, it varies
    /// from 0 to 128 as the animation varies from 0.0 to 1.0.
    class CardItem extends StatelessWidget {
      const CardItem({
        Key key,
        @required this.animation,
        this.onTap,
        @required this.item,
        this.selected: false
      }) : assert(animation != null),
            assert(item != null && item >= 0),
            assert(selected != null),
            super(key: key);
    
      final Animation<double> animation;
      final VoidCallback onTap;
      final int item;
      final bool selected;
    
      @override
      Widget build(BuildContext context) {
        TextStyle textStyle = Theme.of(context).textTheme.display1;
        if (selected)
          textStyle = textStyle.copyWith(color: Colors.lightGreenAccent[400]);
        return new Padding(
          padding: const EdgeInsets.all(2.0),
          child: new SizeTransition(
            axis: Axis.vertical,
            sizeFactor: animation,
            child: new GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: onTap,
              child: new SizedBox(
                height: 128.0,
                child: new Card(
                  color: Colors.primaries[item % Colors.primaries.length],
                  child: new Center(
                    child: new Text('Item $item', style: textStyle),
                  ),
                ),
              ),
            ),
          ),
        );
      }
    }

  • 相关阅读:
    kafka消费者问题
    kubernetes
    Grafana+prometheus+AlertManager+钉钉机器人
    kafka汇总
    java实现顺序表、链表、栈 (x)->{持续更新}
    hadoop细节 -> 持续更新
    drf之组件(认证、权限、排序、过滤、分页等)和xadmin、coreapi
    drf之视图类与路由
    drf序列化与反序列化
    drf之接口规范
  • 原文地址:https://www.cnblogs.com/sea-stream/p/12154393.html
Copyright © 2011-2022 走看看