如何创建自动滚动包装[Flutter]

问题描述 投票:0回答:1

我尝试在有TextFields的地方创建视图在底部的包装芯片。当Wrap很少有没有ListView的筹码时,如下所示:

Wrap(
    spacing: 4,
    children: [
        Chip(label: Text('TAG 1')),
        Chip(label: Text('TAG 2')),
        Chip(label: Text('TAG 3')),
        Chip(label: Text('TAG 4')),
        Chip(label: Text('TAG 5')),
    ],
)

工作正常。

但是当我放进更多筹码时,部分内容将变得不可见。

我试图将Wrap放到ListView中,但这样所有筹码都不可见。

如何利用芯片见解创建可滚动包装?

这是我什至尝试:

Column(
       mainAxisSize: MainAxisSize.min,
       children: <Widget>[
           TextField(...),
           Container(...),
           Container(...),
           Container(...),
           ListView(
             children: <Widget>[
               Wrap(
                 spacing: 4,
                 children: genTagsList(context),//Generates Chips from string array with size 20 
               )
             ],
           )
         ],
      )
android ios flutter mobile flutter-layout
1个回答
0
投票

您可以使用此。从这里找到参考https://github.com/flutter/flutter/blob/master/examples/flutter_gallery/lib/demo/material/chip_demo.dart

import 'package:flutter/material.dart';

import '../../gallery/demo.dart';

const List<String> _defaultMaterials = <String>[
  'poker',
  'tortilla',
  'fish and',
  'micro',
  'wood',
];

const List<String> _defaultActions = <String>[
  'flake',
  'cut',
  'fragment',
  'splinter',
  'nick',
  'fry',
  'solder',
  'cash in',
  'eat',
];

const Map<String, String> _results = <String, String>{
  'flake': 'flaking',
  'cut': 'cutting',
  'fragment': 'fragmenting',
  'splinter': 'splintering',
  'nick': 'nicking',
  'fry': 'frying',
  'solder': 'soldering',
  'cash in': 'cashing in',
  'eat': 'eating',
};

const List<String> _defaultTools = <String>[
  'hammer',
  'chisel',
  'fryer',
  'fabricator',
  'customer',
];

const Map<String, String> _avatars = <String, String>{
  'hammer': 'people/square/ali.png',
  'chisel': 'people/square/sandra.png',
  'fryer': 'people/square/trevor.png',
  'fabricator': 'people/square/stella.png',
  'customer': 'people/square/peter.png',
};

const Map<String, Set<String>> _toolActions = <String, Set<String>>{
  'hammer': <String>{'flake', 'fragment', 'splinter'},
  'chisel': <String>{'flake', 'nick', 'splinter'},
  'fryer': <String>{'fry'},
  'fabricator': <String>{'solder'},
  'customer': <String>{'cash in', 'eat'},
};

const Map<String, Set<String>> _materialActions = <String, Set<String>>{
  'poker': <String>{'cash in'},
  'tortilla': <String>{'fry', 'eat'},
  'fish and': <String>{'fry', 'eat'},
  'micro': <String>{'solder', 'fragment'},
  'wood': <String>{'flake', 'cut', 'splinter', 'nick'},
};

class _ChipsTile extends StatelessWidget {
  const _ChipsTile({
    Key key,
    this.label,
    this.children,
  }) : super(key: key);

  final String label;
  final List<Widget> children;

  // Wraps a list of chips into a ListTile for display as a section in the demo.
  @override
  Widget build(BuildContext context) {
    return Card(
      semanticContainer: false,
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Container(
            padding: const EdgeInsets.only(top: 16.0, bottom: 4.0),
            alignment: Alignment.center,
            child: Text(label, textAlign: TextAlign.start),
          ),
          if (children.isNotEmpty)
            Wrap(
              children: children.map<Widget>((Widget chip) {
                return Padding(
                  padding: const EdgeInsets.all(2.0),
                  child: chip,
                );
              }).toList(),
            )
          else
            Semantics(
              container: true,
              child: Container(
                alignment: Alignment.center,
                constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
                padding: const EdgeInsets.all(8.0),
                child: Text('None', style: Theme.of(context).textTheme.caption.copyWith(fontStyle: FontStyle.italic)),
              ),
            ),
        ],
      ),
    );
  }
}

class ChipDemo extends StatefulWidget {
  static const String routeName = '/material/chip';

  @override
  _ChipDemoState createState() => _ChipDemoState();
}

class _ChipDemoState extends State<ChipDemo> {
  _ChipDemoState() {
    _reset();
  }

  final Set<String> _materials = <String>{};
  String _selectedMaterial = '';
  String _selectedAction = '';
  final Set<String> _tools = <String>{};
  final Set<String> _selectedTools = <String>{};
  final Set<String> _actions = <String>{};
  bool _showShapeBorder = false;

  // Initialize members with the default data.
  void _reset() {
    _materials.clear();
    _materials.addAll(_defaultMaterials);
    _actions.clear();
    _actions.addAll(_defaultActions);
    _tools.clear();
    _tools.addAll(_defaultTools);
    _selectedMaterial = '';
    _selectedAction = '';
    _selectedTools.clear();
  }

  void _removeMaterial(String name) {
    _materials.remove(name);
    if (_selectedMaterial == name) {
      _selectedMaterial = '';
    }
  }

  void _removeTool(String name) {
    _tools.remove(name);
    _selectedTools.remove(name);
  }

  String _capitalize(String name) {
    assert(name != null && name.isNotEmpty);
    return name.substring(0, 1).toUpperCase() + name.substring(1);
  }

  // This converts a String to a unique color, based on the hash value of the
  // String object.  It takes the bottom 16 bits of the hash, and uses that to
  // pick a hue for an HSV color, and then creates the color (with a preset
  // saturation and value).  This means that any unique strings will also have
  // unique colors, but they'll all be readable, since they have the same
  // saturation and value.
  Color _nameToColor(String name) {
    assert(name.length > 1);
    final int hash = name.hashCode & 0xffff;
    final double hue = (360.0 * hash / (1 << 15)) % 360.0;
    return HSVColor.fromAHSV(1.0, hue, 0.4, 0.90).toColor();
  }

  AssetImage _nameToAvatar(String name) {
    assert(_avatars.containsKey(name));
    return AssetImage(
      _avatars[name],
      package: 'flutter_gallery_assets',
    );
  }

  String _createResult() {
    if (_selectedAction.isEmpty) {
      return '';
    }
    return _capitalize(_results[_selectedAction]) + '!';
  }

  @override
  Widget build(BuildContext context) {
    final List<Widget> chips = _materials.map<Widget>((String name) {
      return Chip(
        key: ValueKey<String>(name),
        backgroundColor: _nameToColor(name),
        label: Text(_capitalize(name)),
        onDeleted: () {
          setState(() {
            _removeMaterial(name);
          });
        },
      );
    }).toList();

    final List<Widget> inputChips = _tools.map<Widget>((String name) {
      return InputChip(
          key: ValueKey<String>(name),
          avatar: CircleAvatar(
            backgroundImage: _nameToAvatar(name),
          ),
          label: Text(_capitalize(name)),
          onDeleted: () {
            setState(() {
              _removeTool(name);
            });
          });
    }).toList();

    final List<Widget> choiceChips = _materials.map<Widget>((String name) {
      return ChoiceChip(
        key: ValueKey<String>(name),
        backgroundColor: _nameToColor(name),
        label: Text(_capitalize(name)),
        selected: _selectedMaterial == name,
        onSelected: (bool value) {
          setState(() {
            _selectedMaterial = value ? name : '';
          });
        },
      );
    }).toList();

    final List<Widget> filterChips = _defaultTools.map<Widget>((String name) {
      return FilterChip(
        key: ValueKey<String>(name),
        label: Text(_capitalize(name)),
        selected: _tools.contains(name) && _selectedTools.contains(name),
        onSelected: !_tools.contains(name)
            ? null
            : (bool value) {
                setState(() {
                  if (!value) {
                    _selectedTools.remove(name);
                  } else {
                    _selectedTools.add(name);
                  }
                });
              },
      );
    }).toList();

    Set<String> allowedActions = <String>{};
    if (_selectedMaterial != null && _selectedMaterial.isNotEmpty) {
      for (final String tool in _selectedTools) {
        allowedActions.addAll(_toolActions[tool]);
      }
      allowedActions = allowedActions.intersection(_materialActions[_selectedMaterial]);
    }

    final List<Widget> actionChips = allowedActions.map<Widget>((String name) {
      return ActionChip(
        label: Text(_capitalize(name)),
        onPressed: () {
          setState(() {
            _selectedAction = name;
          });
        },
      );
    }).toList();

    final ThemeData theme = Theme.of(context);
    final List<Widget> tiles = <Widget>[
      const SizedBox(height: 8.0, width: 0.0),
      _ChipsTile(label: 'Available Materials (Chip)', children: chips),
      _ChipsTile(label: 'Available Tools (InputChip)', children: inputChips),
      _ChipsTile(label: 'Choose a Material (ChoiceChip)', children: choiceChips),
      _ChipsTile(label: 'Choose Tools (FilterChip)', children: filterChips),
      _ChipsTile(label: 'Perform Allowed Action (ActionChip)', children: actionChips),
      const Divider(),
      Padding(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: Text(
            _createResult(),
            style: theme.textTheme.headline6,
          ),
        ),
      ),
    ];

    return Scaffold(
      appBar: AppBar(
        title: const Text('Chips'),
        actions: <Widget>[
          MaterialDemoDocumentationButton(ChipDemo.routeName),
          IconButton(
            onPressed: () {
              setState(() {
                _showShapeBorder = !_showShapeBorder;
              });
            },
            icon: const Icon(Icons.vignette, semanticLabel: 'Update border shape'),
          ),
        ],
      ),
      body: ChipTheme(
        data: _showShapeBorder
            ? theme.chipTheme.copyWith(
                shape: BeveledRectangleBorder(
                side: const BorderSide(width: 0.66, style: BorderStyle.solid, color: Colors.grey),
                borderRadius: BorderRadius.circular(10.0),
              ))
            : theme.chipTheme,
        child: Scrollbar(child: ListView(children: tiles)),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => setState(_reset),
        child: const Icon(Icons.refresh, semanticLabel: 'Reset chips'),
      ),
    );
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.