Full Code of Dn-a/flutter_tags for AI

master cf6d3f861354 cached
35 files
158.7 KB
37.3k tokens
73 symbols
1 requests
Download .txt
Repository: Dn-a/flutter_tags
Branch: master
Commit: cf6d3f861354
Files: 35
Total size: 158.7 KB

Directory structure:
gitextract_ehrk8p54/

├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── example/
│   ├── .gitignore
│   ├── .metadata
│   ├── README.md
│   ├── ios/
│   │   ├── Flutter/
│   │   │   ├── AppFrameworkInfo.plist
│   │   │   ├── Debug.xcconfig
│   │   │   ├── Release.xcconfig
│   │   │   └── flutter_export_environment.sh
│   │   ├── Runner/
│   │   │   ├── AppDelegate.swift
│   │   │   ├── Assets.xcassets/
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   └── LaunchImage.imageset/
│   │   │   │       ├── Contents.json
│   │   │   │       └── README.md
│   │   │   ├── Base.lproj/
│   │   │   │   ├── LaunchScreen.storyboard
│   │   │   │   └── Main.storyboard
│   │   │   ├── Info.plist
│   │   │   └── Runner-Bridging-Header.h
│   │   ├── Runner.xcodeproj/
│   │   │   ├── project.pbxproj
│   │   │   ├── project.xcworkspace/
│   │   │   │   └── contents.xcworkspacedata
│   │   │   └── xcshareddata/
│   │   │       └── xcschemes/
│   │   │           └── Runner.xcscheme
│   │   └── Runner.xcworkspace/
│   │       └── contents.xcworkspacedata
│   ├── lib/
│   │   └── main.dart
│   ├── pubspec.yaml
│   └── test/
│       └── widget_test.dart
├── flutter_tags.iml
├── lib/
│   ├── flutter_tags.dart
│   └── src/
│       ├── item_tags.dart
│       ├── suggestions_textfield.dart
│       ├── tags.dart
│       └── util/
│           └── custom_wrap.dart
├── pubspec.yaml
└── test/
    └── flutter_tags_test.dart

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.DS_Store
.dart_tool/

.packages
.pub/

build/
ios/.generated/
ios/Flutter/Generated.xcconfig
ios/Runner/GeneratedPluginRegistrant.*

lib/generated/
res/
.idea/
android/

lib/selectable_tags_back.dart
example/lib/main_back.dart


================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
  revision: d48e6e433cc5ca67b24b19f70aaa197e84ba63c1
  channel: beta

project_type: package


================================================
FILE: CHANGELOG.md
================================================
## [0.4.9+1] - 2020-11-11.

* `[Fixed]` - Issue #66.
* `[Fixed]` - `DataList` null id.

## [0.4.9] - 2020-09-15.

* `[Added]` - Possibility to to define the padding of the `textField`.

## [0.4.8+2] - 2020-06-02.

* `[Updated]` - Documentation.

## [0.4.8+1] - 2020-05-13.

* `[Updated]` - Documentation.

## [0.4.8] - 2020-03-07.

* `[Updated]` - Documentation.

## [0.4.7] - 2020-02-26.

* `[Updated]` -  Documentation.
* General improvement of the code.

## [0.4.6] - 2020-02-26.

* `[Fixed]` -  some problem.
* `[Added]` - Possibility to disabled/enabled `textField` field - Issue #36.
* `[Added]` - Possibility to insert tags not present in the list of suggestions with the `constraintSuggestion` field - Issue #33.
* `onRemoved` field has been moved inside `ItemTagsRemoveButton()` to maintain consistency.
* `onRemoved` now has a bool return type (ex: when you want to add a control before removing a tag).

## [0.4.5] - 2019-10-30.

* Renamed `TagstextField` to `TagsTextField`.
* Added `textCapitalization` field in `TagsTextField`.

## [0.4.4] - 2019-10-16.

* New Features and Documentation Updates.

* Added `child` field in `ItemTagsImage()`, allows more control over the images.
* Fixed alignment `textField` and `suggestions` - Issue #31.
* Added the possibility to get a list of all the `ItemTags` via GlobalKey<TagsState>.

## [0.4.3] - 2019-07-28.

* Minor Update Documentation.
* Fixed some problem.
* removed the 'position' parameter  in TagsTexField () because it is not essential. the same result can be obtained by setting the verticalDirection and TextDirection parameters in Tags ().

## [0.4.2] - 2019-07-27.

* Update Documentation.
* General improvement of the code.

## [0.4.1] - 2019-07-27.

* Minor Update Documentation.

## [0.4.0] - 2019-07-27.

* **Improvements, new Structure, new Features and Documentation Updates**
*
* `SelectableTags` and `InputTags`have been removed, now there is only one widget. **Tags()**
* Now it is possible to personalize every single tag, with the possibility of adding icons, images and a removal button.
* Possibility to display the list with horizontal scroll.

## [0.3.2] - 2019-06-20.

* Issue #14 and #13 fixed.
* Added `customData` field in Tag Class.

## [0.3.1] - 2019-05-13.

* General improvement of the code.

## [0.3.0] - 2019-04-09.

* **New features**
* Possibility to create a customizable popupMenu.
* **SelectableTags**. Possibility to set a color and an activeColor for each tag.
* **InputTags**. Possibility to hide textField.

## [0.2.4] - 2019-04-08.

* fixed some problem.

## [0.2.3] - 2019-04-05.

* General improvement of the code.
* OnInsert, onDelete and onPressed are now optional.

## [0.2.2] - 2019-03-02.

* Added property `textStyle` in InputTags. NOTE: `textColor` has been removed. now it can be set with `textStyle`.
* added property `textStyle` in SelectableTags. NOTE: if you set `color` in it will be ignored, you must use `textColor` `textActiveColor`.
* Created InputSuggestions. Return suggestions in the TextField. Is not complete, soon the list of suggestions will be implemented.
* General improvement of the code.

## [0.2.1] - 2019-03-01.

* The code has been largely rewritten.
* Now the Tag width calculation is very accurate.

## [0.2.0] - 2019-02-24.

* Improved tag width calculation; 
* Possibility to change the margin and padding of the close icon ( InputTags ).

## [0.1.9] - 2019-02-23.

* Width calculated based on the byte length of the title; 
* When the orientation changes, a recalculation of the screen width is performed.

## [0.1.8] - 2019-02-16.

* Improvement of library documentation.

## [0.1.7] - 2019-02-07.

* Added new feature SingleItem on SelectableTags; 
* Possibility to change color/background-color icon on InputTags; - General improvement of the code.

## [0.1.6] - 2019-01-07.

* Fixed error "Infinity or NaN toInt" on InputTags; - general improvement of the code.

## [0.1.5] - 2018-12-24.

* General improvement of the code.

## [0.1.4] - 2018-12-18.

* Added new features.

## [0.1.3] - 2018-12-16.

* Added new highlight feature (InputTags) - general improvement of the code.

## [0.1.2] - 2018-12-15.

* Add InputTags Widget - Improved documentation.

## [0.1.1] - 2018-12-08.

* Improved documentation.

## [0.1.0] - 2018-12-08.

* Did some changing readme.

## [0.0.1] - 2018-12-08.

* Created Selectable Tags.


================================================
FILE: LICENSE
================================================
The MIT License (MIT)

Copyright (c) 2018 Antonino Di Natale

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

================================================
FILE: README.md
================================================
# flutter_tags
[![pub package](https://img.shields.io/badge/pub-0.4.9+1-orange.svg)](https://pub.dartlang.org/packages/flutter_tags)
[![Awesome Flutter](https://img.shields.io/badge/Awesome-Flutter-blue.svg?longCache=true&style=flat-square)](https://github.com/Solido/awesome-flutter#ui)
[![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/dnag88)

Create beautiful tags quickly and easily.

## Installing
Add this to your package's pubspec.yaml file:
```dart
dependencies:
  flutter_tags: "^0.4.9+1"
```


## DEMO

<div align="center">
<table>
<tr>
<td style="text-align:center">
 <img width = "250px" src="https://github.com/Dn-a/flutter_tags/raw/master/repo-file/img/example0.4.0_1.gif" />
 </td>
 <td style="text-align:center">
  <img width = "250px" src="https://github.com/Dn-a/flutter_tags/raw/master/repo-file/img/example0.4.0_2.gif" />
  </td>
</tr>
</table>
</div>


## Simple usage
```dart

import 'package:flutter_tags/flutter_tags.dart';
.
.
.
List _items;
double _fontSize = 14;

@override
void initState(){
    super.initState();
    // if you store data on a local database (sqflite), then you could do something like this
    Model().getItems().then((items){
            _items = items;
        });
}

@override
Widget build(BuildContext context) {
    return Tags(
      key:_tagStateKey,
      textField: TagsTextField(
        textStyle: TextStyle(fontSize: _fontSize),
        constraintSuggestion: true, suggestions: [],
        //width: double.infinity, padding: EdgeInsets.symmetric(horizontal: 10),
        onSubmitted: (String str) {
          // Add item to the data source.
          setState(() {
              // required
            _items.add(str);
          });
        },
      ),
      itemCount: _items.length, // required
      itemBuilder: (int index){          
            final item = _items[index];
    
            return ItemTags(
                  // Each ItemTags must contain a Key. Keys allow Flutter to
                  // uniquely identify widgets.
                  key: Key(index.toString()),
                  index: index, // required
                  title: item.title,
                  active: item.active,
                  customData: item.customData,
                  textStyle: TextStyle( fontSize: _fontSize, ),
                  combine: ItemTagsCombine.withTextBefore,
                  image: ItemTagsImage(
                    image: AssetImage("img.jpg") // OR NetworkImage("https://...image.png")
                  ), // OR null,
                  icon: ItemTagsIcon(
                    icon: Icons.add,
                  ), // OR null,
                  removeButton: ItemTagsRemoveButton(
                    onRemoved: (){
                        // Remove the item from the data source.
                        setState(() {
                            // required
                            _items.removeAt(index);
                        });
                        //required
                        return true;
                    },
                  ), // OR null,
                  onPressed: (item) => print(item),
                  onLongPressed: (item) => print(item),
            );
    
      },
    );    
}

final GlobalKey<TagsState> _tagStateKey = GlobalKey<TagsState>();
// Allows you to get a list of all the ItemTags
_getAllItem(){
    List<Item> lst = _tagStateKey.currentState?.getAllItem;
    if(lst!=null)
        lst.where((a) => a.active==true).forEach( ( a) => print(a.title));        
}
```
## Wrapped widget example
You are free to wrap ItemTags () inside another widget
```dart
Tags(  
      itemCount: items.length, 
      itemBuilder: (int index){ 
          return Tooltip(
          message: item.title,
          child:ItemTags(
            title:item.title,
          )
          );
      },
    );    
```
### Tags() parameters
|PropName|Description|default value|
|:-------|:----------|:------------|
|`columns`|*Possibility to set number of columns when necessary*|null|
|`itemCount`|*Tag number to display*|required|
|`symmetry`|*Ability to view and scroll tags horizontally*|false|
|`horizontalScroll`|*Offset drawer width*|0.4|
|`heightHorizontalScroll`|*height for HorizontalScroll to set to display tags correctly*|60|
|`spacing`|*Horizontal space between the tags*|6|
|`runSpacing`|*Vertical space between the tags*|14|
|`alignment`|*Horizontal WrapAlignment*|WrapAlignment.center|
|`runAlignment`|*Vertical WrapAlignment*|WrapAlignment.center|
|`direction`|*Direction of the ItemTags*|Axis.horizontal|
|`verticalDirection`|*Iterate Item from the lower to the upper direction or vice versa*|VerticalDirection.down|
|`textDirection`|*Text direction of  the ItemTags*|TextDirection.ltr|
|`itemBuilder`|*tag generator*||
|`textField`|*add textField*|TagsTextFiled()|

### ItemTags() parameters
* `index` - *required*
* `title` - *required*
* `textScaleFactor` - *custom textScaleFactor*
* `active` - *bool value (default true)*
* `pressEnabled` - *active onPress tag ( default true)*
* `customData` - *Possibility to add any custom value in customData field, you can retrieve this later. A good example: store an id from Firestore document.*
* `textStyle` - *textStyle()*
* `alignment` - *MainAxisAlignment ( default MainAxisAlignment.center)*
* `combine` - * ability to combine text, icons, images in different ways ( default  ItemTagsCombine.imageOrIconOrText)*
* `icon` - *ItemTagsIcon()*
* `image` - *ItemTagsImage()*
* `removeButton` - *ItemTagsRemoveButton()*
* `borderRadius` - *BorderRadius*
* `border` - *custom border-side*
* `padding` - *default EdgeInsets.symmetric(horizontal: 7, vertical: 5)*
* `elevation` - *default 5*
* `singleItem` - *default false*
* `textOverflow` - *default TextOverflow.fade*
* `textColor` - *default Colors.black*
* `textActiveColor` - *default  Colors.white*
* `color` - *default Colors.white*
* `activeColor` - *default Colors.blueGrey*
* `highlightColor` - 
* `splashColor` - 
* `colorShowDuplicate` - *default  Colors.red*
* `onPressed` - *callback*
* `onLongPressed` - *callback*
* `onRemoved` - *callback*


## Donate
It takes time to carry on this project. If you found it useful or learned something from the source code please consider the idea of donating 5, 20, 50 € or whatever you can to support the project.
- [![Donate](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://www.paypal.me/dnag88)

## Issues
If you encounter problems, open an issue. Pull request are also welcome.


================================================
FILE: example/.gitignore
================================================
# Miscellaneous
*.class
*.lock
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# Visual Studio Code related
.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/

# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java

# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*

# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages


================================================
FILE: example/.metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
  revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
  channel: beta

project_type: app


================================================
FILE: example/README.md
================================================
# Example Flutter Tags

An example of how you could implement it.

## Getting Started - Selectable Tags
```dart
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:flutter_tags/flutter_tags.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Tags Demo',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: MyHomePage(title: 'Flutter Tags'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  ScrollController _scrollViewController;

  final List<String> _list = [
    '0',
    'SDK',
    'plugin updates',
    'Facebook',
    '哔了狗了QP又不够了',
    'Kirchhoff',
    'Italy',
    'France',
    'Spain',
    '美',
    'Dart',
    'SDK',
    'Foo',
    'Select',
    'lorem ip',
    '9',
    'Star',
    'Flutter Selectable Tags',
    '1',
    'Hubble',
    '2',
    'Input flutter tags',
    'A B C',
    '8',
    'Android Studio developer',
    'welcome to the jungle',
    'Gauss',
    '美术',
    '互联网',
    '炫舞时代',
    '篝火营地',
  ];

  bool _symmetry = false;
  bool _removeButton = true;
  bool _singleItem = false;
  bool _startDirection = false;
  bool _horizontalScroll = false;
  bool _withSuggesttions = false;
  int _count = 0;
  int _column = 0;
  double _fontSize = 14;

  String _itemCombine = 'withTextBefore';

  String _onPressed = '';

  List _icon = [Icons.home, Icons.language, Icons.headset];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _scrollViewController = ScrollController();

    _items = _list.toList();
  }

  List _items;

  final GlobalKey<TagsState> _tagStateKey = GlobalKey<TagsState>();

  @override
  Widget build(BuildContext context) {
    //List<Item> lst = _tagStateKey.currentState?.getAllItem; lst.forEach((f) => print(f.title));
    return Scaffold(
      body: NestedScrollView(
          controller: _scrollViewController,
          headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                title: Text("flutter tags"),
                centerTitle: true,
                pinned: true,
                expandedHeight: 0,
                floating: true,
                forceElevated: boxIsScrolled,
                bottom: TabBar(
                  isScrollable: false,
                  indicatorSize: TabBarIndicatorSize.label,
                  labelStyle: TextStyle(fontSize: 18.0),
                  tabs: [
                    Tab(text: "Demo 1"),
                    Tab(text: "Demo 2"),
                  ],
                  controller: _tabController,
                ),
              )
            ];
          },
          body: TabBarView(
            controller: _tabController,
            children: [
              CustomScrollView(
                slivers: <Widget>[
                  SliverList(
                      delegate: SliverChildListDelegate([
                    Container(
                      decoration: BoxDecoration(
                          border: Border(
                              bottom: BorderSide(
                                  color: Colors.grey[300], width: 0.5))),
                      margin:
                          EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                      child: ExpansionTile(
                        title: Text("Settings"),
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _removeButton,
                                        onChanged: (a) {
                                          setState(() {
                                            _removeButton = !_removeButton;
                                          });
                                        }),
                                    Text('Remove Button')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _removeButton = !_removeButton;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(5),
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _symmetry,
                                        onChanged: (a) {
                                          setState(() {
                                            _symmetry = !_symmetry;
                                          });
                                        }),
                                    Text('Symmetry')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _symmetry = !_symmetry;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(5),
                              ),
                              DropdownButton(
                                hint: _column == 0
                                    ? Text("Not set")
                                    : Text(_column.toString()),
                                items: _buildItems(),
                                onChanged: (a) {
                                  setState(() {
                                    _column = a;
                                  });
                                },
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _horizontalScroll,
                                        onChanged: (a) {
                                          setState(() {
                                            _horizontalScroll =
                                                !_horizontalScroll;
                                          });
                                        }),
                                    Text('Horizontal scroll')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _horizontalScroll = !_horizontalScroll;
                                  });
                                },
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _singleItem,
                                        onChanged: (a) {
                                          setState(() {
                                            _singleItem = !_singleItem;
                                          });
                                        }),
                                    Text('Single Item')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _singleItem = !_singleItem;
                                  });
                                },
                              ),
                            ],
                          ),
                          Column(
                            children: <Widget>[
                              Text('Font Size'),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Slider(
                                    value: _fontSize,
                                    min: 6,
                                    max: 30,
                                    onChanged: (a) {
                                      setState(() {
                                        _fontSize = (a.round()).toDouble();
                                      });
                                    },
                                  ),
                                  Text(_fontSize.toString()),
                                  Padding(
                                    padding:
                                        EdgeInsets.symmetric(horizontal: 20),
                                  ),
                                  Container(
                                    height: 30,
                                    width: 30,
                                    //color: Colors.blueGrey,
                                    child: IconButton(
                                      padding: EdgeInsets.all(0),
                                      //color: Colors.white,
                                      icon: Icon(Icons.add),
                                      onPressed: () {
                                        setState(() {
                                          _count++;
                                          _items.add(_count.toString());
                                          //_items.removeAt(3); _items.removeAt(10);
                                        });
                                      },
                                    ),
                                  ),
                                  Padding(
                                    padding:
                                        EdgeInsets.symmetric(horizontal: 5),
                                  ),
                                  Container(
                                    height: 30,
                                    width: 30,
                                    //color: Colors.grey,
                                    child: IconButton(
                                      padding: EdgeInsets.all(0),
                                      //color: Colors.white,
                                      icon: Icon(Icons.refresh),
                                      onPressed: () {
                                        setState(() {
                                          _items = _list.toList();
                                        });
                                      },
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(20),
                    ),
                    _tags1,
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          children: <Widget>[
                            Divider(
                              color: Colors.blueGrey,
                            ),
                            Padding(
                              padding: EdgeInsets.symmetric(vertical: 20),
                              child: Text(_onPressed),
                            ),
                          ],
                        )),
                  ])),
                ],
              ),
              CustomScrollView(
                slivers: <Widget>[
                  SliverList(
                      delegate: SliverChildListDelegate([
                    Container(
                      decoration: BoxDecoration(
                          border: Border(
                              bottom: BorderSide(
                                  color: Colors.grey[300], width: 0.5))),
                      margin:
                          EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                      child: ExpansionTile(
                        title: Text("Settings"),
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _withSuggesttions,
                                        onChanged: (a) {
                                          setState(() {
                                            _withSuggesttions =
                                                !_withSuggesttions;
                                          });
                                        }),
                                    Text('Suggestions')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _withSuggesttions = !_withSuggesttions;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(20),
                              ),
                              DropdownButton(
                                hint: Text(_itemCombine),
                                items: _buildItems2(),
                                onChanged: (val) {
                                  setState(() {
                                    _itemCombine = val;
                                  });
                                },
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _horizontalScroll,
                                        onChanged: (a) {
                                          setState(() {
                                            _horizontalScroll =
                                                !_horizontalScroll;
                                          });
                                        }),
                                    Text('Horizontal scroll')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _horizontalScroll = !_horizontalScroll;
                                  });
                                },
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _startDirection,
                                        onChanged: (a) {
                                          setState(() {
                                            _startDirection = !_startDirection;
                                          });
                                        }),
                                    Text('Start Direction')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _startDirection = !_startDirection;
                                  });
                                },
                              ),
                            ],
                          ),
                          Column(
                            children: <Widget>[
                              Text('Font Size'),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Slider(
                                    value: _fontSize,
                                    min: 6,
                                    max: 30,
                                    onChanged: (a) {
                                      setState(() {
                                        _fontSize = (a.round()).toDouble();
                                      });
                                    },
                                  ),
                                  Text(_fontSize.toString()),
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(20),
                    ),
                    _tags2,
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          children: <Widget>[
                            Divider(
                              color: Colors.blueGrey,
                            ),
                            Padding(
                              padding: EdgeInsets.symmetric(vertical: 20),
                              child: Text(_onPressed),
                            ),
                          ],
                        )),
                  ])),
                ],
              ),
            ],
          )),
    );
  }

  Widget get _tags1 {
    return Tags(
      key: _tagStateKey,
      symmetry: _symmetry,
      columns: _column,
      horizontalScroll: _horizontalScroll,
      //verticalDirection: VerticalDirection.up, textDirection: TextDirection.rtl,
      heightHorizontalScroll: 60 * (_fontSize / 14),
      itemCount: _items.length,
      itemBuilder: (index) {
        final item = _items[index];

        return ItemTags(
          key: Key(index.toString()),
          index: index,
          title: item,
          pressEnabled: true,
          activeColor: Colors.blueGrey[600],
          singleItem: _singleItem,
          splashColor: Colors.green,
          combine: ItemTagsCombine.withTextBefore,
          image: index > 0 && index < 5
              ? ItemTagsImage(
                  //image: AssetImage("img/p$index.jpg"),
                  child: Image.network(
                  "http://www.clipartpanda.com/clipart_images/user-66327738/download",
                  width: 16 * _fontSize / 14,
                  height: 16 * _fontSize / 14,
                ))
              : (1 == 1
                  ? ItemTagsImage(
                      image: NetworkImage(
                          "https://d32ogoqmya1dw8.cloudfront.net/images/serc/empty_user_icon_256.v2.png"),
                    )
                  : null),
          icon: (item == '0' || item == '1' || item == '2')
              ? ItemTagsIcon(
                  icon: _icon[int.parse(item)],
                )
              : null,
          removeButton: _removeButton
              ? ItemTagsRemoveButton(
                  onRemoved: () {
                    setState(() {
                      _items.removeAt(index);
                    });
                    return true;
                  },
                )
              : null,
          textScaleFactor:
              utf8.encode(item.substring(0, 1)).length > 2 ? 0.8 : 1,
          textStyle: TextStyle(
            fontSize: _fontSize,
          ),
          onPressed: (item) => print(item),
        );
      },
    );
  }

  // Position for popup menu
  Offset _tapPosition;

  Widget get _tags2 {
    //popup Menu
    final RenderBox overlay = Overlay.of(context).context?.findRenderObject();

    ItemTagsCombine combine = ItemTagsCombine.onlyText;

    switch (_itemCombine) {
      case 'onlyText':
        combine = ItemTagsCombine.onlyText;
        break;
      case 'onlyIcon':
        combine = ItemTagsCombine.onlyIcon;
        break;
      case 'onlyIcon':
        combine = ItemTagsCombine.onlyIcon;
        break;
      case 'onlyImage':
        combine = ItemTagsCombine.onlyImage;
        break;
      case 'imageOrIconOrText':
        combine = ItemTagsCombine.imageOrIconOrText;
        break;
      case 'withTextAfter':
        combine = ItemTagsCombine.withTextAfter;
        break;
      case 'withTextBefore':
        combine = ItemTagsCombine.withTextBefore;
        break;
    }

    return Tags(
      key: Key("2"),
      symmetry: _symmetry,
      columns: _column,
      horizontalScroll: _horizontalScroll,
      verticalDirection:
          _startDirection ? VerticalDirection.up : VerticalDirection.down,
      textDirection: _startDirection ? TextDirection.rtl : TextDirection.ltr,
      heightHorizontalScroll: 60 * (_fontSize / 14),
      textField: _textField,
      itemCount: _items.length,
      itemBuilder: (index) {
        final item = _items[index];

        return GestureDetector(
          child: ItemTags(
            key: Key(index.toString()),
            index: index,
            title: item,
            pressEnabled: false,
            activeColor: Colors.green[400],
            combine: combine,
            image: index > 0 && index < 5
                ? ItemTagsImage(image: AssetImage("img/p$index.jpg"))
                : (1 == 1
                    ? ItemTagsImage(
                        image: NetworkImage(
                            "https://image.flaticon.com/icons/png/512/44/44948.png"))
                    : null),
            icon: (item == '0' || item == '1' || item == '2')
                ? ItemTagsIcon(
                    icon: _icon[int.parse(item)],
                  )
                : null,
            removeButton: ItemTagsRemoveButton(
              backgroundColor: Colors.green[900],
              onRemoved: () {
                setState(() {
                  _items.removeAt(index);
                });
                return true;
              },
            ),
            textScaleFactor:
                utf8.encode(item.substring(0, 1)).length > 2 ? 0.8 : 1,
            textStyle: TextStyle(
              fontSize: _fontSize,
            ),
          ),
          onTapDown: (details) => _tapPosition = details.globalPosition,
          onLongPress: () {
            showMenu(
                    //semanticLabel: item,
                    items: <PopupMenuEntry>[
                  PopupMenuItem(
                    child: Text(item, style: TextStyle(color: Colors.blueGrey)),
                    enabled: false,
                  ),
                  PopupMenuDivider(),
                  PopupMenuItem(
                    value: 1,
                    child: Row(
                      children: <Widget>[
                        Icon(Icons.content_copy),
                        Text("Copy text"),
                      ],
                    ),
                  ),
                ],
                    context: context,
                    position: RelativeRect.fromRect(
                        _tapPosition & Size(40, 40),
                        Offset.zero &
                            overlay
                                .size) // & RelativeRect.fromLTRB(65.0, 40.0, 0.0, 0.0),
                    )
                .then((value) {
              if (value == 1) Clipboard.setData(ClipboardData(text: item));
            });
          },
        );
      },
    );
  }

  TagsTextField get _textField {
    return TagsTextField(
      autofocus: false,
      //width: double.infinity,
      //padding: EdgeInsets.symmetric(horizontal: 10),
      textStyle: TextStyle(
        fontSize: _fontSize,
        //height: 1
      ),
      enabled: true,
      constraintSuggestion: true,
      suggestions: _withSuggesttions
          ? [
        "One",
        "two",
        "android",
        "Dart",
        "flutter",
        "test",
        "tests",
        "androids",
        "androidsaaa",
        "Test",
        "suggest",
        "suggestions",
        "互联网",
        "last",
        "lest",
        "炫舞时代"
      ]
          : null,
      onSubmitted: (String str) {
        setState(() {
          _items.add(str);
        });
      },
    );
  }

  List<DropdownMenuItem> _buildItems() {
    List<DropdownMenuItem> list = [];

    int count = 19;

    list.add(
      DropdownMenuItem(
        child: Text("Not set"),
        value: 0,
      ),
    );

    for (int i = 1; i < count; i++)
      list.add(
        DropdownMenuItem(
          child: Text(i.toString()),
          value: i,
        ),
      );

    return list;
  }

  List<DropdownMenuItem> _buildItems2() {
    List<DropdownMenuItem> list = [];

    list.add(DropdownMenuItem(
      child: Text("onlyText"),
      value: 'onlyText',
    ));

    list.add(DropdownMenuItem(
      child: Text("onlyIcon"),
      value: 'onlyIcon',
    ));
    list.add(DropdownMenuItem(
      child: Text("onlyImage"),
      value: 'onlyImage',
    ));
    list.add(DropdownMenuItem(
      child: Text("imageOrIconOrText"),
      value: 'imageOrIconOrText',
    ));
    list.add(DropdownMenuItem(
      child: Text("withTextBefore"),
      value: 'withTextBefore',
    ));
    list.add(DropdownMenuItem(
      child: Text("withTextAfter"),
      value: 'withTextAfter',
    ));

    return list;
  }
}
```

## DEMO
![Demo 1](https://github.com/Dn-a/flutter_tags/raw/master/repo-file/img/example0.4.0_1.gif)
![Demo 1](https://github.com/Dn-a/flutter_tags/raw/master/repo-file/img/example0.4.0_2.gif)

## Other
This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)

For help getting started with Flutter, view our 
[online documentation](https://flutter.io/docs), which offers tutorials, 
samples, guidance on mobile development, and a full API reference.


================================================
FILE: example/ios/Flutter/AppFrameworkInfo.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>CFBundleDevelopmentRegion</key>
  <string>en</string>
  <key>CFBundleExecutable</key>
  <string>App</string>
  <key>CFBundleIdentifier</key>
  <string>io.flutter.flutter.app</string>
  <key>CFBundleInfoDictionaryVersion</key>
  <string>6.0</string>
  <key>CFBundleName</key>
  <string>App</string>
  <key>CFBundlePackageType</key>
  <string>FMWK</string>
  <key>CFBundleShortVersionString</key>
  <string>1.0</string>
  <key>CFBundleSignature</key>
  <string>????</string>
  <key>CFBundleVersion</key>
  <string>1.0</string>
  <key>MinimumOSVersion</key>
  <string>8.0</string>
</dict>
</plist>


================================================
FILE: example/ios/Flutter/Debug.xcconfig
================================================
#include "Generated.xcconfig"


================================================
FILE: example/ios/Flutter/Release.xcconfig
================================================
#include "Generated.xcconfig"


================================================
FILE: example/ios/Flutter/flutter_export_environment.sh
================================================
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=C:\flutter"
export "FLUTTER_APPLICATION_PATH=D:\Android\Flutter\package\flutter_tags\example"
export "FLUTTER_TARGET=lib\main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build\ios"
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
export "FLUTTER_FRAMEWORK_DIR=C:\flutter\bin\cache\artifacts\engine\ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=false"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.packages"


================================================
FILE: example/ios/Runner/AppDelegate.swift
================================================
import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}


================================================
FILE: example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
  "images" : [
    {
      "size" : "20x20",
      "idiom" : "iphone",
      "filename" : "Icon-App-20x20@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "20x20",
      "idiom" : "iphone",
      "filename" : "Icon-App-20x20@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "Icon-App-29x29@1x.png",
      "scale" : "1x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "Icon-App-29x29@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "iphone",
      "filename" : "Icon-App-29x29@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "Icon-App-40x40@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "iphone",
      "filename" : "Icon-App-40x40@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "Icon-App-60x60@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "60x60",
      "idiom" : "iphone",
      "filename" : "Icon-App-60x60@3x.png",
      "scale" : "3x"
    },
    {
      "size" : "20x20",
      "idiom" : "ipad",
      "filename" : "Icon-App-20x20@1x.png",
      "scale" : "1x"
    },
    {
      "size" : "20x20",
      "idiom" : "ipad",
      "filename" : "Icon-App-20x20@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "Icon-App-29x29@1x.png",
      "scale" : "1x"
    },
    {
      "size" : "29x29",
      "idiom" : "ipad",
      "filename" : "Icon-App-29x29@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "Icon-App-40x40@1x.png",
      "scale" : "1x"
    },
    {
      "size" : "40x40",
      "idiom" : "ipad",
      "filename" : "Icon-App-40x40@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "Icon-App-76x76@1x.png",
      "scale" : "1x"
    },
    {
      "size" : "76x76",
      "idiom" : "ipad",
      "filename" : "Icon-App-76x76@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "83.5x83.5",
      "idiom" : "ipad",
      "filename" : "Icon-App-83.5x83.5@2x.png",
      "scale" : "2x"
    },
    {
      "size" : "1024x1024",
      "idiom" : "ios-marketing",
      "filename" : "Icon-App-1024x1024@1x.png",
      "scale" : "1x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}


================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
================================================
{
  "images" : [
    {
      "idiom" : "universal",
      "filename" : "LaunchImage.png",
      "scale" : "1x"
    },
    {
      "idiom" : "universal",
      "filename" : "LaunchImage@2x.png",
      "scale" : "2x"
    },
    {
      "idiom" : "universal",
      "filename" : "LaunchImage@3x.png",
      "scale" : "3x"
    }
  ],
  "info" : {
    "version" : 1,
    "author" : "xcode"
  }
}


================================================
FILE: example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
================================================
# Launch Screen Assets

You can customize the launch screen with your own desired assets by replacing the image files in this directory.

You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.

================================================
FILE: example/ios/Runner/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
    </dependencies>
    <scenes>
        <!--View Controller-->
        <scene sceneID="EHf-IW-A2E">
            <objects>
                <viewController id="01J-lp-oVM" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
                        <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <subviews>
                            <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
                            </imageView>
                        </subviews>
                        <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
                        <constraints>
                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
                            <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
                        </constraints>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
            </objects>
            <point key="canvasLocation" x="53" y="375"/>
        </scene>
    </scenes>
    <resources>
        <image name="LaunchImage" width="168" height="185"/>
    </resources>
</document>


================================================
FILE: example/ios/Runner/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
    <dependencies>
        <deployment identifier="iOS"/>
        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
    </dependencies>
    <scenes>
        <!--Flutter View Controller-->
        <scene sceneID="tne-QT-ifu">
            <objects>
                <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
                    <layoutGuides>
                        <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
                        <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
                    </layoutGuides>
                    <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
                        <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
                        <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
                    </view>
                </viewController>
                <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
            </objects>
        </scene>
    </scenes>
</document>


================================================
FILE: example/ios/Runner/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>CFBundleDevelopmentRegion</key>
	<string>en</string>
	<key>CFBundleExecutable</key>
	<string>$(EXECUTABLE_NAME)</string>
	<key>CFBundleIdentifier</key>
	<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
	<key>CFBundleInfoDictionaryVersion</key>
	<string>6.0</string>
	<key>CFBundleName</key>
	<string>example_flutter_tags</string>
	<key>CFBundlePackageType</key>
	<string>APPL</string>
	<key>CFBundleShortVersionString</key>
	<string>$(FLUTTER_BUILD_NAME)</string>
	<key>CFBundleSignature</key>
	<string>????</string>
	<key>CFBundleVersion</key>
	<string>$(FLUTTER_BUILD_NUMBER)</string>
	<key>LSRequiresIPhoneOS</key>
	<true/>
	<key>UILaunchStoryboardName</key>
	<string>LaunchScreen</string>
	<key>UIMainStoryboardFile</key>
	<string>Main</string>
	<key>UISupportedInterfaceOrientations</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UISupportedInterfaceOrientations~ipad</key>
	<array>
		<string>UIInterfaceOrientationPortrait</string>
		<string>UIInterfaceOrientationPortraitUpsideDown</string>
		<string>UIInterfaceOrientationLandscapeLeft</string>
		<string>UIInterfaceOrientationLandscapeRight</string>
	</array>
	<key>UIViewControllerBasedStatusBarAppearance</key>
	<false/>
</dict>
</plist>


================================================
FILE: example/ios/Runner/Runner-Bridging-Header.h
================================================
#import "GeneratedPluginRegistrant.h"

================================================
FILE: example/ios/Runner.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
	archiveVersion = 1;
	classes = {
	};
	objectVersion = 46;
	objects = {

/* Begin PBXBuildFile section */
		1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
		2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */ = {isa = PBXBuildFile; fileRef = 2D5378251FAA1A9400D5DBA9 /* flutter_assets */; };
		3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
		3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; };
		3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
		74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
		9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; };
		9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
		9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; };
		97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
		97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
		97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */

/* Begin PBXCopyFilesBuildPhase section */
		9705A1C41CF9048500538489 /* Embed Frameworks */ = {
			isa = PBXCopyFilesBuildPhase;
			buildActionMask = 2147483647;
			dstPath = "";
			dstSubfolderSpec = 10;
			files = (
				3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */,
				9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */,
			);
			name = "Embed Frameworks";
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
		1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
		1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
		2D5378251FAA1A9400D5DBA9 /* flutter_assets */ = {isa = PBXFileReference; lastKnownFileType = folder; name = flutter_assets; path = Flutter/flutter_assets; sourceTree = SOURCE_ROOT; };
		3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
		3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = "<group>"; };
		74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
		74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
		7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
		9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
		9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
		9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = "<group>"; };
		97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
		97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
		97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
		97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
		97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
		97C146EB1CF9000F007C117D /* Frameworks */ = {
			isa = PBXFrameworksBuildPhase;
			buildActionMask = 2147483647;
			files = (
				9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */,
				3B80C3941E831B6300D905FE /* App.framework in Frameworks */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
		9740EEB11CF90186004384FC /* Flutter */ = {
			isa = PBXGroup;
			children = (
				2D5378251FAA1A9400D5DBA9 /* flutter_assets */,
				3B80C3931E831B6300D905FE /* App.framework */,
				3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
				9740EEBA1CF902C7004384FC /* Flutter.framework */,
				9740EEB21CF90195004384FC /* Debug.xcconfig */,
				7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
				9740EEB31CF90195004384FC /* Generated.xcconfig */,
			);
			name = Flutter;
			sourceTree = "<group>";
		};
		97C146E51CF9000F007C117D = {
			isa = PBXGroup;
			children = (
				9740EEB11CF90186004384FC /* Flutter */,
				97C146F01CF9000F007C117D /* Runner */,
				97C146EF1CF9000F007C117D /* Products */,
			);
			sourceTree = "<group>";
		};
		97C146EF1CF9000F007C117D /* Products */ = {
			isa = PBXGroup;
			children = (
				97C146EE1CF9000F007C117D /* Runner.app */,
			);
			name = Products;
			sourceTree = "<group>";
		};
		97C146F01CF9000F007C117D /* Runner */ = {
			isa = PBXGroup;
			children = (
				97C146FA1CF9000F007C117D /* Main.storyboard */,
				97C146FD1CF9000F007C117D /* Assets.xcassets */,
				97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
				97C147021CF9000F007C117D /* Info.plist */,
				97C146F11CF9000F007C117D /* Supporting Files */,
				1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
				1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
				74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
				74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
			);
			path = Runner;
			sourceTree = "<group>";
		};
		97C146F11CF9000F007C117D /* Supporting Files */ = {
			isa = PBXGroup;
			children = (
			);
			name = "Supporting Files";
			sourceTree = "<group>";
		};
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
		97C146ED1CF9000F007C117D /* Runner */ = {
			isa = PBXNativeTarget;
			buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
			buildPhases = (
				9740EEB61CF901F6004384FC /* Run Script */,
				97C146EA1CF9000F007C117D /* Sources */,
				97C146EB1CF9000F007C117D /* Frameworks */,
				97C146EC1CF9000F007C117D /* Resources */,
				9705A1C41CF9048500538489 /* Embed Frameworks */,
				3B06AD1E1E4923F5004D2608 /* Thin Binary */,
			);
			buildRules = (
			);
			dependencies = (
			);
			name = Runner;
			productName = Runner;
			productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
			productType = "com.apple.product-type.application";
		};
/* End PBXNativeTarget section */

/* Begin PBXProject section */
		97C146E61CF9000F007C117D /* Project object */ = {
			isa = PBXProject;
			attributes = {
				LastUpgradeCheck = 0910;
				ORGANIZATIONNAME = "The Chromium Authors";
				TargetAttributes = {
					97C146ED1CF9000F007C117D = {
						CreatedOnToolsVersion = 7.3.1;
						LastSwiftMigration = 0910;
					};
				};
			};
			buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
			compatibilityVersion = "Xcode 3.2";
			developmentRegion = English;
			hasScannedForEncodings = 0;
			knownRegions = (
				en,
				Base,
			);
			mainGroup = 97C146E51CF9000F007C117D;
			productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
			projectDirPath = "";
			projectRoot = "";
			targets = (
				97C146ED1CF9000F007C117D /* Runner */,
			);
		};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
		97C146EC1CF9000F007C117D /* Resources */ = {
			isa = PBXResourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
				3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
				9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */,
				97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
				2D5378261FAA1A9400D5DBA9 /* flutter_assets in Resources */,
				97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
		3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
			);
			name = "Thin Binary";
			outputPaths = (
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/sh;
			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin";
		};
		9740EEB61CF901F6004384FC /* Run Script */ = {
			isa = PBXShellScriptBuildPhase;
			buildActionMask = 2147483647;
			files = (
			);
			inputPaths = (
			);
			name = "Run Script";
			outputPaths = (
			);
			runOnlyForDeploymentPostprocessing = 0;
			shellPath = /bin/sh;
			shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
		};
/* End PBXShellScriptBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
		97C146EA1CF9000F007C117D /* Sources */ = {
			isa = PBXSourcesBuildPhase;
			buildActionMask = 2147483647;
			files = (
				74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
				1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
			);
			runOnlyForDeploymentPostprocessing = 0;
		};
/* End PBXSourcesBuildPhase section */

/* Begin PBXVariantGroup section */
		97C146FA1CF9000F007C117D /* Main.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				97C146FB1CF9000F007C117D /* Base */,
			);
			name = Main.storyboard;
			sourceTree = "<group>";
		};
		97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
			isa = PBXVariantGroup;
			children = (
				97C147001CF9000F007C117D /* Base */,
			);
			name = LaunchScreen.storyboard;
			sourceTree = "<group>";
		};
/* End PBXVariantGroup section */

/* Begin XCBuildConfiguration section */
		249021D3217E4FDB00AE95B9 /* Profile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
				VALIDATE_PRODUCT = YES;
			};
			name = Profile;
		};
		249021D4217E4FDB00AE95B9 /* Profile */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
				DEVELOPMENT_TEAM = S8QB4VV633;
				ENABLE_BITCODE = NO;
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				INFOPLIST_FILE = Runner/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.dna.exampleFlutterTags;
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_VERSION = 4.0;
				VERSIONING_SYSTEM = "apple-generic";
			};
			name = Profile;
		};
		97C147031CF9000F007C117D /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = dwarf;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				ENABLE_TESTABILITY = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_DYNAMIC_NO_PIC = NO;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_OPTIMIZATION_LEVEL = 0;
				GCC_PREPROCESSOR_DEFINITIONS = (
					"DEBUG=1",
					"$(inherited)",
				);
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
				MTL_ENABLE_DEBUG_INFO = YES;
				ONLY_ACTIVE_ARCH = YES;
				SDKROOT = iphoneos;
				TARGETED_DEVICE_FAMILY = "1,2";
			};
			name = Debug;
		};
		97C147041CF9000F007C117D /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
			buildSettings = {
				ALWAYS_SEARCH_USER_PATHS = NO;
				CLANG_ANALYZER_NONNULL = YES;
				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
				CLANG_CXX_LIBRARY = "libc++";
				CLANG_ENABLE_MODULES = YES;
				CLANG_ENABLE_OBJC_ARC = YES;
				CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
				CLANG_WARN_BOOL_CONVERSION = YES;
				CLANG_WARN_COMMA = YES;
				CLANG_WARN_CONSTANT_CONVERSION = YES;
				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
				CLANG_WARN_EMPTY_BODY = YES;
				CLANG_WARN_ENUM_CONVERSION = YES;
				CLANG_WARN_INFINITE_RECURSION = YES;
				CLANG_WARN_INT_CONVERSION = YES;
				CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
				CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
				CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
				CLANG_WARN_STRICT_PROTOTYPES = YES;
				CLANG_WARN_SUSPICIOUS_MOVE = YES;
				CLANG_WARN_UNREACHABLE_CODE = YES;
				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
				"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
				COPY_PHASE_STRIP = NO;
				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
				ENABLE_NS_ASSERTIONS = NO;
				ENABLE_STRICT_OBJC_MSGSEND = YES;
				GCC_C_LANGUAGE_STANDARD = gnu99;
				GCC_NO_COMMON_BLOCKS = YES;
				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
				GCC_WARN_UNDECLARED_SELECTOR = YES;
				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
				GCC_WARN_UNUSED_FUNCTION = YES;
				GCC_WARN_UNUSED_VARIABLE = YES;
				IPHONEOS_DEPLOYMENT_TARGET = 8.0;
				MTL_ENABLE_DEBUG_INFO = NO;
				SDKROOT = iphoneos;
				SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
				TARGETED_DEVICE_FAMILY = "1,2";
				VALIDATE_PRODUCT = YES;
			};
			name = Release;
		};
		97C147061CF9000F007C117D /* Debug */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CLANG_ENABLE_MODULES = YES;
				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
				ENABLE_BITCODE = NO;
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				INFOPLIST_FILE = Runner/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.dna.exampleFlutterTags;
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
				SWIFT_OPTIMIZATION_LEVEL = "-Onone";
				SWIFT_SWIFT3_OBJC_INFERENCE = On;
				SWIFT_VERSION = 4.0;
				VERSIONING_SYSTEM = "apple-generic";
			};
			name = Debug;
		};
		97C147071CF9000F007C117D /* Release */ = {
			isa = XCBuildConfiguration;
			baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
			buildSettings = {
				ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
				CLANG_ENABLE_MODULES = YES;
				CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
				ENABLE_BITCODE = NO;
				FRAMEWORK_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				INFOPLIST_FILE = Runner/Info.plist;
				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
				LIBRARY_SEARCH_PATHS = (
					"$(inherited)",
					"$(PROJECT_DIR)/Flutter",
				);
				PRODUCT_BUNDLE_IDENTIFIER = com.dna.exampleFlutterTags;
				PRODUCT_NAME = "$(TARGET_NAME)";
				SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
				SWIFT_SWIFT3_OBJC_INFERENCE = On;
				SWIFT_VERSION = 4.0;
				VERSIONING_SYSTEM = "apple-generic";
			};
			name = Release;
		};
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
		97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				97C147031CF9000F007C117D /* Debug */,
				97C147041CF9000F007C117D /* Release */,
				249021D3217E4FDB00AE95B9 /* Profile */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
		97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
			isa = XCConfigurationList;
			buildConfigurations = (
				97C147061CF9000F007C117D /* Debug */,
				97C147071CF9000F007C117D /* Release */,
				249021D4217E4FDB00AE95B9 /* Profile */,
			);
			defaultConfigurationIsVisible = 0;
			defaultConfigurationName = Release;
		};
/* End XCConfigurationList section */

	};
	rootObject = 97C146E61CF9000F007C117D /* Project object */;
}


================================================
FILE: example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "group:Runner.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
   LastUpgradeVersion = "0910"
   version = "1.3">
   <BuildAction
      parallelizeBuildables = "YES"
      buildImplicitDependencies = "YES">
      <BuildActionEntries>
         <BuildActionEntry
            buildForTesting = "YES"
            buildForRunning = "YES"
            buildForProfiling = "YES"
            buildForArchiving = "YES"
            buildForAnalyzing = "YES">
            <BuildableReference
               BuildableIdentifier = "primary"
               BlueprintIdentifier = "97C146ED1CF9000F007C117D"
               BuildableName = "Runner.app"
               BlueprintName = "Runner"
               ReferencedContainer = "container:Runner.xcodeproj">
            </BuildableReference>
         </BuildActionEntry>
      </BuildActionEntries>
   </BuildAction>
   <TestAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      language = ""
      shouldUseLaunchSchemeArgsEnv = "YES">
      <Testables>
      </Testables>
      <MacroExpansion>
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
            BuildableName = "Runner.app"
            BlueprintName = "Runner"
            ReferencedContainer = "container:Runner.xcodeproj">
         </BuildableReference>
      </MacroExpansion>
      <AdditionalOptions>
      </AdditionalOptions>
   </TestAction>
   <LaunchAction
      buildConfiguration = "Debug"
      selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
      selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
      language = ""
      launchStyle = "0"
      useCustomWorkingDirectory = "NO"
      ignoresPersistentStateOnLaunch = "NO"
      debugDocumentVersioning = "YES"
      debugServiceExtension = "internal"
      allowLocationSimulation = "YES">
      <BuildableProductRunnable
         runnableDebuggingMode = "0">
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
            BuildableName = "Runner.app"
            BlueprintName = "Runner"
            ReferencedContainer = "container:Runner.xcodeproj">
         </BuildableReference>
      </BuildableProductRunnable>
      <AdditionalOptions>
      </AdditionalOptions>
   </LaunchAction>
   <ProfileAction
      buildConfiguration = "Profile"
      shouldUseLaunchSchemeArgsEnv = "YES"
      savedToolIdentifier = ""
      useCustomWorkingDirectory = "NO"
      debugDocumentVersioning = "YES">
      <BuildableProductRunnable
         runnableDebuggingMode = "0">
         <BuildableReference
            BuildableIdentifier = "primary"
            BlueprintIdentifier = "97C146ED1CF9000F007C117D"
            BuildableName = "Runner.app"
            BlueprintName = "Runner"
            ReferencedContainer = "container:Runner.xcodeproj">
         </BuildableReference>
      </BuildableProductRunnable>
   </ProfileAction>
   <AnalyzeAction
      buildConfiguration = "Debug">
   </AnalyzeAction>
   <ArchiveAction
      buildConfiguration = "Release"
      revealArchiveInOrganizer = "YES">
   </ArchiveAction>
</Scheme>


================================================
FILE: example/ios/Runner.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
   version = "1.0">
   <FileRef
      location = "group:Runner.xcodeproj">
   </FileRef>
</Workspace>


================================================
FILE: example/lib/main.dart
================================================
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

import 'package:flutter_tags/flutter_tags.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Tags Demo',
      theme: ThemeData(
        primarySwatch: Colors.blueGrey,
      ),
      home: MyHomePage(title: 'Flutter Tags'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

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

class _MyHomePageState extends State<MyHomePage>
    with SingleTickerProviderStateMixin {
  TabController _tabController;
  ScrollController _scrollViewController;

  final List<String> _list = [
    '0',
    'SDK',
    'plugin updates',
    'Facebook',
    '哔了狗了QP又不够了',
    'Kirchhoff',
    'Italy',
    'France',
    'Spain',
    '美',
    'Dart',
    'SDK',
    'Foo',
    'Select',
    'lorem ip',
    '9',
    'Star',
    'Flutter Selectable Tags',
    '1',
    'Hubble',
    '2',
    'Input flutter tags',
    'A B C',
    '8',
    'Android Studio developer',
    'welcome to the jungle',
    'Gauss',
    '美术',
    '互联网',
    '炫舞时代',
    '篝火营地',
  ];

  bool _symmetry = false;
  bool _removeButton = true;
  bool _singleItem = true;
  bool _startDirection = false;
  bool _horizontalScroll = true;
  bool _withSuggesttions = false;
  int _count = 0;
  int _column = 0;
  double _fontSize = 14;

  String _itemCombine = 'withTextBefore';

  String _onPressed = '';

  List _icon = [Icons.home, Icons.language, Icons.headset];

  @override
  void initState() {
    super.initState();
    _tabController = TabController(length: 2, vsync: this);
    _scrollViewController = ScrollController();

    _items = _list.toList();
  }

  List _items;

  final GlobalKey<TagsState> _tagStateKey = GlobalKey<TagsState>();

  @override
  Widget build(BuildContext context) {
    //List<Item> lst = _tagStateKey.currentState?.getAllItem; lst.forEach((f) => print(f.title));
    return Scaffold(
      body: NestedScrollView(
          controller: _scrollViewController,
          headerSliverBuilder: (BuildContext context, bool boxIsScrolled) {
            return <Widget>[
              SliverAppBar(
                title: Text("flutter tags"),
                centerTitle: true,
                pinned: true,
                expandedHeight: 0,
                floating: true,
                forceElevated: boxIsScrolled,
                bottom: TabBar(
                  isScrollable: false,
                  indicatorSize: TabBarIndicatorSize.label,
                  labelStyle: TextStyle(fontSize: 18.0),
                  tabs: [
                    Tab(text: "Demo 1"),
                    Tab(text: "Demo 2"),
                  ],
                  controller: _tabController,
                ),
              )
            ];
          },
          body: TabBarView(
            controller: _tabController,
            children: [
              CustomScrollView(
                slivers: <Widget>[
                  SliverList(
                      delegate: SliverChildListDelegate([
                    Container(
                      decoration: BoxDecoration(
                          border: Border(
                              bottom: BorderSide(
                                  color: Colors.grey[300], width: 0.5))),
                      margin:
                          EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                      child: ExpansionTile(
                        title: Text("Settings"),
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _removeButton,
                                        onChanged: (a) {
                                          setState(() {
                                            _removeButton = !_removeButton;
                                          });
                                        }),
                                    Text('Remove Button')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _removeButton = !_removeButton;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(5),
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _symmetry,
                                        onChanged: (a) {
                                          setState(() {
                                            _symmetry = !_symmetry;
                                          });
                                        }),
                                    Text('Symmetry')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _symmetry = !_symmetry;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(5),
                              ),
                              DropdownButton(
                                hint: _column == 0
                                    ? Text("Not set")
                                    : Text(_column.toString()),
                                items: _buildItems(),
                                onChanged: (a) {
                                  setState(() {
                                    _column = a;
                                  });
                                },
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _horizontalScroll,
                                        onChanged: (a) {
                                          setState(() {
                                            _horizontalScroll =
                                                !_horizontalScroll;
                                          });
                                        }),
                                    Text('Horizontal scroll')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _horizontalScroll = !_horizontalScroll;
                                  });
                                },
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _singleItem,
                                        onChanged: (a) {
                                          setState(() {
                                            _singleItem = !_singleItem;
                                          });
                                        }),
                                    Text('Single Item')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _singleItem = !_singleItem;
                                  });
                                },
                              ),
                            ],
                          ),
                          Column(
                            children: <Widget>[
                              Text('Font Size'),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Slider(
                                    value: _fontSize,
                                    min: 6,
                                    max: 30,
                                    onChanged: (a) {
                                      setState(() {
                                        _fontSize = (a.round()).toDouble();
                                      });
                                    },
                                  ),
                                  Text(_fontSize.toString()),
                                  Padding(
                                    padding:
                                        EdgeInsets.symmetric(horizontal: 20),
                                  ),
                                  Container(
                                    height: 30,
                                    width: 30,
                                    //color: Colors.blueGrey,
                                    child: IconButton(
                                      padding: EdgeInsets.all(0),
                                      //color: Colors.white,
                                      icon: Icon(Icons.add),
                                      onPressed: () {
                                        setState(() {
                                          _count++;
                                          _items.add(_count.toString());
                                          //_items.removeAt(3); _items.removeAt(10);
                                        });
                                      },
                                    ),
                                  ),
                                  Padding(
                                    padding:
                                        EdgeInsets.symmetric(horizontal: 5),
                                  ),
                                  Container(
                                    height: 30,
                                    width: 30,
                                    //color: Colors.grey,
                                    child: IconButton(
                                      padding: EdgeInsets.all(0),
                                      //color: Colors.white,
                                      icon: Icon(Icons.refresh),
                                      onPressed: () {
                                        setState(() {
                                          _items = _list.toList();
                                        });
                                      },
                                    ),
                                  ),
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(20),
                    ),
                    _tags1,
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          children: <Widget>[
                            Divider(
                              color: Colors.blueGrey,
                            ),
                            Padding(
                              padding: EdgeInsets.symmetric(vertical: 20),
                              child: Text(_onPressed),
                            ),
                          ],
                        )),
                  ])),
                ],
              ),
              CustomScrollView(
                slivers: <Widget>[
                  SliverList(
                      delegate: SliverChildListDelegate([
                    Container(
                      decoration: BoxDecoration(
                          border: Border(
                              bottom: BorderSide(
                                  color: Colors.grey[300], width: 0.5))),
                      margin:
                          EdgeInsets.symmetric(horizontal: 10, vertical: 10),
                      child: ExpansionTile(
                        title: Text("Settings"),
                        children: <Widget>[
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _withSuggesttions,
                                        onChanged: (a) {
                                          setState(() {
                                            _withSuggesttions =
                                                !_withSuggesttions;
                                          });
                                        }),
                                    Text('Suggestions')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _withSuggesttions = !_withSuggesttions;
                                  });
                                },
                              ),
                              Padding(
                                padding: EdgeInsets.all(20),
                              ),
                              DropdownButton(
                                hint: Text(_itemCombine),
                                items: _buildItems2(),
                                onChanged: (val) {
                                  setState(() {
                                    _itemCombine = val;
                                  });
                                },
                              ),
                            ],
                          ),
                          Row(
                            mainAxisAlignment: MainAxisAlignment.center,
                            children: <Widget>[
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _horizontalScroll,
                                        onChanged: (a) {
                                          setState(() {
                                            _horizontalScroll =
                                                !_horizontalScroll;
                                          });
                                        }),
                                    Text('Horizontal scroll')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _horizontalScroll = !_horizontalScroll;
                                  });
                                },
                              ),
                              GestureDetector(
                                child: Row(
                                  children: <Widget>[
                                    Checkbox(
                                        value: _startDirection,
                                        onChanged: (a) {
                                          setState(() {
                                            _startDirection = !_startDirection;
                                          });
                                        }),
                                    Text('Start Direction')
                                  ],
                                ),
                                onTap: () {
                                  setState(() {
                                    _startDirection = !_startDirection;
                                  });
                                },
                              ),
                            ],
                          ),
                          Column(
                            children: <Widget>[
                              Text('Font Size'),
                              Row(
                                mainAxisAlignment: MainAxisAlignment.center,
                                children: <Widget>[
                                  Slider(
                                    value: _fontSize,
                                    min: 6,
                                    max: 30,
                                    onChanged: (a) {
                                      setState(() {
                                        _fontSize = (a.round()).toDouble();
                                      });
                                    },
                                  ),
                                  Text(_fontSize.toString()),
                                ],
                              ),
                            ],
                          ),
                        ],
                      ),
                    ),
                    Padding(
                      padding: EdgeInsets.all(20),
                    ),
                    _tags2,
                    Container(
                        padding: EdgeInsets.all(20),
                        child: Column(
                          children: <Widget>[
                            Divider(
                              color: Colors.blueGrey,
                            ),
                            Padding(
                              padding: EdgeInsets.symmetric(vertical: 20),
                              child: Text(_onPressed),
                            ),
                          ],
                        )),
                  ])),
                ],
              ),
            ],
          )),
    );
  }

  Widget get _tags1 {
    return Tags(
      key: _tagStateKey,
      symmetry: _symmetry,
      columns: _column,
      horizontalScroll: _horizontalScroll,
      //verticalDirection: VerticalDirection.up, textDirection: TextDirection.rtl,
      heightHorizontalScroll: 60 * (_fontSize / 14),
      itemCount: _items.length,
      itemBuilder: (index) {
        final item = _items[index];

        return ItemTags(
          key: Key(index.toString()),
          index: index,
          title: item,
          pressEnabled: true,
          activeColor: Colors.blueGrey[600],
          singleItem: _singleItem,
          splashColor: Colors.green,
          combine: ItemTagsCombine.withTextBefore,
          image: index > 0 && index < 5
              ? ItemTagsImage(
                  //image: AssetImage("img/p$index.jpg"),
                  child: Image.network(
                  "http://www.clipartpanda.com/clipart_images/user-66327738/download",
                  width: 16 * _fontSize / 14,
                  height: 16 * _fontSize / 14,
                ))
              : (1 == 1
                  ? ItemTagsImage(
                      image: NetworkImage(
                          "https://d32ogoqmya1dw8.cloudfront.net/images/serc/empty_user_icon_256.v2.png"),
                    )
                  : null),
          icon: (item == '0' || item == '1' || item == '2')
              ? ItemTagsIcon(
                  icon: _icon[int.parse(item)],
                )
              : null,
          removeButton: _removeButton
              ? ItemTagsRemoveButton(
                  onRemoved: () {
                    setState(() {
                      _items.removeAt(index);
                    });
                    return true;
                  },
                )
              : null,
          textScaleFactor:
              utf8.encode(item.substring(0, 1)).length > 2 ? 0.8 : 1,
          textStyle: TextStyle(
            fontSize: _fontSize,
          ),
          onPressed: (item) => print(item),
        );
      },
    );
  }

  // Position for popup menu
  Offset _tapPosition;

  Widget get _tags2 {
    //popup Menu
    final RenderBox overlay = Overlay.of(context).context?.findRenderObject();

    ItemTagsCombine combine = ItemTagsCombine.onlyText;

    switch (_itemCombine) {
      case 'onlyText':
        combine = ItemTagsCombine.onlyText;
        break;
      case 'onlyIcon':
        combine = ItemTagsCombine.onlyIcon;
        break;
      case 'onlyIcon':
        combine = ItemTagsCombine.onlyIcon;
        break;
      case 'onlyImage':
        combine = ItemTagsCombine.onlyImage;
        break;
      case 'imageOrIconOrText':
        combine = ItemTagsCombine.imageOrIconOrText;
        break;
      case 'withTextAfter':
        combine = ItemTagsCombine.withTextAfter;
        break;
      case 'withTextBefore':
        combine = ItemTagsCombine.withTextBefore;
        break;
    }

    return Tags(
      key: Key("2"),
      symmetry: _symmetry,
      columns: _column,
      horizontalScroll: _horizontalScroll,
      verticalDirection:
          _startDirection ? VerticalDirection.up : VerticalDirection.down,
      textDirection: _startDirection ? TextDirection.rtl : TextDirection.ltr,
      heightHorizontalScroll: 60 * (_fontSize / 14),
      textField: _textField,
      itemCount: _items.length,
      itemBuilder: (index) {
        final item = _items[index];

        return GestureDetector(
          child: ItemTags(
            key: Key(index.toString()),
            index: index,
            title: item,
            pressEnabled: false,
            activeColor: Colors.green[400],
            combine: combine,
            image: index > 0 && index < 5
                ? ItemTagsImage(image: AssetImage("img/p$index.jpg"))
                : (1 == 1
                    ? ItemTagsImage(
                        image: NetworkImage(
                            "https://image.flaticon.com/icons/png/512/44/44948.png"))
                    : null),
            icon: (item == '0' || item == '1' || item == '2')
                ? ItemTagsIcon(
                    icon: _icon[int.parse(item)],
                  )
                : null,
            removeButton: ItemTagsRemoveButton(
              backgroundColor: Colors.green[900],
              onRemoved: () {
                setState(() {
                  _items.removeAt(index);
                });
                return true;
              },
            ),
            textScaleFactor:
                utf8.encode(item.substring(0, 1)).length > 2 ? 0.8 : 1,
            textStyle: TextStyle(
              fontSize: _fontSize,
            ),
          ),
          onTapDown: (details) => _tapPosition = details.globalPosition,
          onLongPress: () {
            showMenu(
                    //semanticLabel: item,
                    items: <PopupMenuEntry>[
                  PopupMenuItem(
                    child: Text(item, style: TextStyle(color: Colors.blueGrey)),
                    enabled: false,
                  ),
                  PopupMenuDivider(),
                  PopupMenuItem(
                    value: 1,
                    child: Row(
                      children: <Widget>[
                        Icon(Icons.content_copy),
                        Text("Copy text"),
                      ],
                    ),
                  ),
                ],
                    context: context,
                    position: RelativeRect.fromRect(
                        _tapPosition & Size(40, 40),
                        Offset.zero &
                            overlay
                                .size) // & RelativeRect.fromLTRB(65.0, 40.0, 0.0, 0.0),
                    )
                .then((value) {
              if (value == 1) Clipboard.setData(ClipboardData(text: item));
            });
          },
        );
      },
    );
  }

  TagsTextField get _textField {
    return TagsTextField(
      autofocus: false,
      width: double.infinity,
      padding: EdgeInsets.symmetric(horizontal: 10),
      textStyle: TextStyle(
        fontSize: _fontSize,
        //height: 1
      ),
      enabled: true,
      constraintSuggestion: true,
      suggestions: _withSuggesttions
          ? [
              "One",
              "two",
              "android",
              "Dart",
              "flutter",
              "test",
              "tests",
              "androids",
              "androidsaaa",
              "Test",
              "suggest",
              "suggestions",
              "互联网",
              "last",
              "lest",
              "炫舞时代"
            ]
          : null,
      onSubmitted: (String str) {
        setState(() {
          _items.add(str);
        });
      },
    );
  }

  List<DropdownMenuItem> _buildItems() {
    List<DropdownMenuItem> list = [];

    int count = 19;

    list.add(
      DropdownMenuItem(
        child: Text("Not set"),
        value: 0,
      ),
    );

    for (int i = 1; i < count; i++)
      list.add(
        DropdownMenuItem(
          child: Text(i.toString()),
          value: i,
        ),
      );

    return list;
  }

  List<DropdownMenuItem> _buildItems2() {
    List<DropdownMenuItem> list = [];

    list.add(DropdownMenuItem(
      child: Text("onlyText"),
      value: 'onlyText',
    ));

    list.add(DropdownMenuItem(
      child: Text("onlyIcon"),
      value: 'onlyIcon',
    ));
    list.add(DropdownMenuItem(
      child: Text("onlyImage"),
      value: 'onlyImage',
    ));
    list.add(DropdownMenuItem(
      child: Text("imageOrIconOrText"),
      value: 'imageOrIconOrText',
    ));
    list.add(DropdownMenuItem(
      child: Text("withTextBefore"),
      value: 'withTextBefore',
    ));
    list.add(DropdownMenuItem(
      child: Text("withTextAfter"),
      value: 'withTextAfter',
    ));

    return list;
  }
}


================================================
FILE: example/pubspec.yaml
================================================
name: example_flutter_tags
description: A new Flutter application.

# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# Read more about versioning at semver.org.
version: 1.0.0+1

environment:
  sdk: ">=2.0.0-dev.68.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_tags:
    path: ../

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter


# For information on the generic Dart part of this file, see the
# following page: https://www.dartlang.org/tools/pub/pubspec

# The following section is specific to Flutter.
flutter:

  # The following line ensures that the Material Icons font is
  # included with your application, so that you can use the icons in
  # the material Icons class.
  uses-material-design: true

  # To add assets to your application, add an assets section, like this:
  assets:
    - img/p1.jpg
    - img/p2.jpg
    - img/p3.jpg
    - img/p4.jpg

  # An image asset can refer to one or more resolution-specific "variants", see
  # https://flutter.io/assets-and-images/#resolution-aware.

  # For details regarding adding assets from package dependencies, see
  # https://flutter.io/assets-and-images/#from-packages

  # To add custom fonts to your application, add a fonts section here,
  # in this "flutter" section. Each entry in this list should have a
  # "family" key with the font family name, and a "fonts" key with a
  # list giving the asset and other descriptors for the font. For
  # example:
  # fonts:
  #   - family: Schyler
  #     fonts:
  #       - asset: fonts/Schyler-Regular.ttf
  #       - asset: fonts/Schyler-Italic.ttf
  #         style: italic
  #   - family: Trajan Pro
  #     fonts:
  #       - asset: fonts/TrajanPro.ttf
  #       - asset: fonts/TrajanPro_Bold.ttf
  #         weight: 700
  #
  # For details regarding fonts from package dependencies,
  # see https://flutter.io/custom-fonts/#from-packages


================================================
FILE: example/test/widget_test.dart
================================================
import 'package:flutter/material.dart';

void main() {}


================================================
FILE: flutter_tags.iml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
  <component name="FacetManager">
    <facet type="android" name="Android">
      <configuration>
        <option name="ALLOW_USER_CONFIGURATION" value="false" />
      </configuration>
    </facet>
  </component>
  <component name="NewModuleRootManager" inherit-compiler-output="true">
    <exclude-output />
    <content url="file://$MODULE_DIR$">
      <sourceFolder url="file://$MODULE_DIR$/lib" isTestSource="false" />
      <sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
      <sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
      <excludeFolder url="file://$MODULE_DIR$/.dart_tool" />
      <excludeFolder url="file://$MODULE_DIR$/.idea" />
      <excludeFolder url="file://$MODULE_DIR$/.pub" />
      <excludeFolder url="file://$MODULE_DIR$/build" />
      <excludeFolder url="file://$MODULE_DIR$/example/.dart_tool" />
      <excludeFolder url="file://$MODULE_DIR$/example/.pub" />
      <excludeFolder url="file://$MODULE_DIR$/example/build" />
      <excludeFolder url="file://$MODULE_DIR$/example/example_flutter_tags/.dart_tool" />
      <excludeFolder url="file://$MODULE_DIR$/example/example_flutter_tags/.pub" />
      <excludeFolder url="file://$MODULE_DIR$/example/example_flutter_tags/build" />
    </content>
    <orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
    <orderEntry type="sourceFolder" forTests="false" />
    <orderEntry type="library" name="Dart SDK" level="project" />
    <orderEntry type="library" name="Flutter Plugins" level="project" />
    <orderEntry type="library" name="Dart Packages" level="project" />
  </component>
</module>

================================================
FILE: lib/flutter_tags.dart
================================================
library flutter_tags;

export 'src/suggestions_textfield.dart';
export 'src/item_tags.dart';
export 'src/tags.dart';


================================================
FILE: lib/src/item_tags.dart
================================================
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_tags/src/tags.dart';

/// Used by [ItemTags.onPressed].
typedef OnPressedCallback = void Function(Item i);

/// Used by [ItemTags.OnLongPressed].
typedef OnLongPressedCallback = void Function(Item i);

/// Used by [ItemTags.removeButton.onRemoved].
typedef OnRemovedCallback = bool Function();

/// combines icon text or image
enum ItemTagsCombine {
  onlyText,
  onlyIcon,
  onlyImage,
  imageOrIconOrText,
  withTextBefore,
  withTextAfter
}

class ItemTags extends StatefulWidget {
  ItemTags(
      {@required this.index,
      @required this.title,
      this.textScaleFactor,
      this.active = true,
      this.pressEnabled = true,
      this.customData,
      this.textStyle = const TextStyle(fontSize: 14),
      this.alignment = MainAxisAlignment.center,
      this.combine = ItemTagsCombine.imageOrIconOrText,
      this.icon,
      this.image,
      this.removeButton,
      this.borderRadius,
      this.border,
      this.padding = const EdgeInsets.symmetric(horizontal: 7, vertical: 5),
      this.elevation = 5,
      this.singleItem = false,
      this.textOverflow = TextOverflow.fade,
      this.textColor = Colors.black,
      this.textActiveColor = Colors.white,
      this.color = Colors.white,
      this.activeColor = Colors.blueGrey,
      this.highlightColor,
      this.splashColor,
      this.colorShowDuplicate = Colors.red,
      this.onPressed,
      this.onLongPressed,
      Key key})
      : assert(index != null),
        assert(title != null),
        super(key: key);

  /// Id of [ItemTags] - required
  final int index;

  /// Title of [ItemTags] - required
  final String title;

  /// Scale Factor of [ItemTags] - double
  final double textScaleFactor;

  /// Initial bool value
  final bool active;

  /// Initial bool value
  final bool pressEnabled;

  /// Possibility to add any custom value in customData field, you can retrieve this later. A good example: store an id from Firestore document.
  final dynamic customData;

  /// ItemTagsCombine (text,icon,textIcon,textImage) of [ItemTags]
  final ItemTagsCombine combine;

  /// Icon of [ItemTags]
  final ItemTagsIcon icon;

  /// Image of [ItemTags]
  final ItemTagsImage image;

  /// Custom Remove Button of [ItemTags]
  final ItemTagsRemoveButton removeButton;

  /// TextStyle of the [ItemTags]
  final TextStyle textStyle;

  /// TextStyle of the [ItemTags]
  final MainAxisAlignment alignment;

  /// border-radius of [ItemTags]
  final BorderRadius borderRadius;

  /// custom border-side of [ItemTags]
  final BoxBorder border;

  /// padding of the [ItemTags]
  final EdgeInsets padding;

  /// BoxShadow of the [ItemTags]
  final double elevation;

  /// when you want only one tag selected. same radio-button
  final bool singleItem;

  /// type of text overflow within the [ItemTags]
  final TextOverflow textOverflow;

  /// text color of the [ItemTags]
  final Color textColor;

  /// color of the [ItemTags] text activated
  final Color textActiveColor;

  /// background color [ItemTags]
  final Color color;

  /// background color [ItemTags] activated
  final Color activeColor;

  /// highlight Color [ItemTags]
  final Color highlightColor;

  /// Splash color [ItemTags]
  final Color splashColor;

  /// Color show duplicate [ItemTags]
  final Color colorShowDuplicate;

  /// callback
  final OnPressedCallback onPressed;

  /// callback
  final OnLongPressedCallback onLongPressed;

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

class _ItemTagsState extends State<ItemTags> {
  final double _initBorderRadius = 50;

  DataListInherited _dataListInherited;
  DataList _dataList;

  void _setDataList() {
    // Get List<DataList> from Tags widget
    _dataListInherited = DataListInherited.of(context);

    // set List length
    if (_dataListInherited.list.length < _dataListInherited.itemCount)
      _dataListInherited.list.length = _dataListInherited.itemCount;

    if (_dataListInherited.list.length > (widget.index + 1) &&
        _dataListInherited.list.elementAt(widget.index) != null &&
        _dataListInherited.list.elementAt(widget.index).title != widget.title) {
      // when an element is removed from the data source
      _dataListInherited.list.removeAt(widget.index);

      // when all item list changed in data source
      if (_dataListInherited.list.elementAt(widget.index) != null &&
          _dataListInherited.list.elementAt(widget.index).title != widget.title)
        _dataListInherited.list
            .removeRange(widget.index, _dataListInherited.list.length);
    }

    // add new Item in the List
    if (_dataListInherited.list.length < (widget.index + 1)) {
      //print("add");
      _dataListInherited.list.insert(
          widget.index,
          DataList(
              title: widget.title,
              index: widget.index,
              active: widget.singleItem ? false : widget.active,
              customData: widget.customData));
    } else if (_dataListInherited.list.elementAt(widget.index) == null) {
      //print("replace");
      _dataListInherited.list[widget.index] = DataList(
          title: widget.title,
          index: widget.index,
          active: widget.singleItem ? false : widget.active,
          customData: widget.customData);
    }

    // removes items that have been orphaned
    if (_dataListInherited.itemCount == widget.index + 1 &&
        _dataListInherited.list.length > _dataListInherited.itemCount)
      _dataListInherited.list
          .removeRange(widget.index + 1, _dataListInherited.list.length);

    //print(_dataListInherited.list.length);

    // update Listener
    if (_dataList != null) _dataList.removeListener(_didValueChange);

    _dataList = _dataListInherited.list.elementAt(widget.index);
    _dataList.addListener(_didValueChange);
  }

  _didValueChange() => setState(() {});

  @override
  void dispose() {
    _dataList.removeListener(_didValueChange);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    _setDataList();

    final double fontSize = widget.textStyle.fontSize;

    Color color = _dataList.active ? widget.activeColor : widget.color;

    if (_dataList.showDuplicate) color = widget.colorShowDuplicate;

    return Material(
      color: color,
      borderRadius:
          widget.borderRadius ?? BorderRadius.circular(_initBorderRadius),
      elevation: widget.elevation,
      //shadowColor: _dataList.highlights? Colors.red : Colors.blue,
      child: InkWell(
        borderRadius:
            widget.borderRadius ?? BorderRadius.circular(_initBorderRadius),
        highlightColor:
            widget.pressEnabled ? widget.highlightColor : Colors.transparent,
        splashColor:
            widget.pressEnabled ? widget.splashColor : Colors.transparent,
        child: Container(
            decoration: BoxDecoration(
                border: widget.border ??
                    Border.all(color: widget.activeColor, width: 0.5),
                borderRadius: widget.borderRadius ??
                    BorderRadius.circular(_initBorderRadius)),
            padding: widget.padding * (fontSize / 14),
            child: _combine),
        onTap: widget.pressEnabled
            ? () {
                if (widget.singleItem) {
                  _singleItem(_dataListInherited, _dataList);
                  _dataList.active = true;
                } else
                  _dataList.active = !_dataList.active;

                if (widget.onPressed != null)
                  widget.onPressed(Item(
                      index: widget.index,
                      title: _dataList.title,
                      active: _dataList.active,
                      customData: widget.customData));
              }
            : null,
        onLongPress: widget.onLongPressed != null
            ? () => widget.onLongPressed(Item(
                index: widget.index,
                title: _dataList.title,
                active: _dataList.active,
                customData: widget.customData))
            : null,
      ),
    );
  }

  Widget get _combine {
    if (widget.image != null)
      assert((widget.image.image != null && widget.image.child == null) ||
          (widget.image.child != null && widget.image.image == null));
    final Widget text = Text(
      widget.title,
      softWrap: false,
      textAlign: _textAlignment,
      overflow: widget.textOverflow,
      textScaleFactor: widget.textScaleFactor,
      style: _textStyle,
    );
    final Widget icon = widget.icon != null
        ? Container(
            padding: widget.icon.padding ??
                (widget.combine == ItemTagsCombine.onlyIcon ||
                        widget.combine == ItemTagsCombine.imageOrIconOrText
                    ? null
                    : widget.combine == ItemTagsCombine.withTextAfter
                        ? EdgeInsets.only(right: 5)
                        : EdgeInsets.only(left: 5)),
            child: Icon(
              widget.icon.icon,
              color: _textStyle.color,
              size: _textStyle.fontSize * 1.2,
            ),
          )
        : text;
    final Widget image = widget.image != null
        ? Container(
            padding: widget.image.padding ??
                (widget.combine == ItemTagsCombine.onlyImage ||
                        widget.combine == ItemTagsCombine.imageOrIconOrText
                    ? null
                    : widget.combine == ItemTagsCombine.withTextAfter
                        ? EdgeInsets.only(right: 5)
                        : EdgeInsets.only(left: 5)),
            child: widget.image.child ??
                CircleAvatar(
                  radius:
                      widget.image.radius * (widget.textStyle.fontSize / 14),
                  backgroundColor: Colors.transparent,
                  backgroundImage: widget.image.image,
                ),
          )
        : text;

    final List list = List();

    switch (widget.combine) {
      case ItemTagsCombine.onlyText:
        list.add(text);
        break;
      case ItemTagsCombine.onlyIcon:
        list.add(icon);
        break;
      case ItemTagsCombine.onlyImage:
        list.add(image);
        break;
      case ItemTagsCombine.imageOrIconOrText:
        list.add((image != text ? image : icon));
        break;
      case ItemTagsCombine.withTextBefore:
        list.add(text);
        if (image != text)
          list.add(image);
        else if (icon != text) list.add(icon);
        break;
      case ItemTagsCombine.withTextAfter:
        if (image != text)
          list.add(image);
        else if (icon != text) list.add(icon);
        list.add(text);
    }

    final Widget row = Row(
        mainAxisAlignment: widget.alignment,
        mainAxisSize: MainAxisSize.min,
        children: List.generate(list.length, (i) {
          if (i == 0 && list.length > 1)
            return Flexible(
              flex: widget.combine == ItemTagsCombine.withTextAfter ? 0 : 1,
              child: list[i],
            );
          return Flexible(
            flex: widget.combine == ItemTagsCombine.withTextAfter ||
                    list.length == 1
                ? 1
                : 0,
            child: list[i],
          );
        }));

    if (widget.removeButton != null)
      return Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Flexible(
                fit:
                    _dataListInherited.symmetry ? FlexFit.tight : FlexFit.loose,
                flex: 2,
                child: row),
            Flexible(
                flex: 0,
                child: FittedBox(
                    alignment: Alignment.centerRight,
                    fit: BoxFit.fill,
                    child: GestureDetector(
                      child: Container(
                        margin: widget.removeButton.margin ??
                            EdgeInsets.only(left: 5),
                        padding:
                            (widget.removeButton.padding ?? EdgeInsets.all(2)) *
                                (widget.textStyle.fontSize / 14),
                        decoration: BoxDecoration(
                          color: widget.removeButton.backgroundColor ??
                              Colors.black,
                          borderRadius: widget.removeButton.borderRadius ??
                              BorderRadius.circular(_initBorderRadius),
                        ),
                        child: widget.removeButton.padding ??
                            Icon(
                              Icons.clear,
                              color: widget.removeButton.color ?? Colors.white,
                              size: (widget.removeButton.size ?? 12) *
                                  (widget.textStyle.fontSize / 14),
                            ),
                      ),
                      onTap: () {
                        if (widget.removeButton.onRemoved != null) {
                          if (widget.removeButton.onRemoved())
                            _dataListInherited.list.removeAt(widget.index);
                        }
                      },
                    )))
          ]);

    return row;
  }

  ///Text Alignment
  TextAlign get _textAlignment {
    switch (widget.alignment) {
      case MainAxisAlignment.spaceBetween:
      case MainAxisAlignment.start:
        return TextAlign.start;
        break;
      case MainAxisAlignment.end:
        return TextAlign.end;
        break;
      case MainAxisAlignment.spaceAround:
      case MainAxisAlignment.spaceEvenly:
      case MainAxisAlignment.center:
        return TextAlign.center;
    }
    return null;
  }

  ///TextStyle
  TextStyle get _textStyle {
    return widget.textStyle.apply(
      color: _dataList.active ? widget.textActiveColor : widget.textColor,
    );
  }

  /// Single item selection
  void _singleItem(DataListInherited dataSetIn, DataList dataSet) {
    dataSetIn.list
        .where((tg) => tg != null)
        .where((tg) => tg.active)
        .where((tg2) => tg2 != dataSet)
        .forEach((tg) => tg.active = false);
  }
}

///callback
class Item {
  Item({this.index, this.title, this.active, this.customData});
  final int index;
  final String title;
  final bool active;
  final dynamic customData;

  @override
  String toString() {
    return "id:$index, title: $title, active: $active, customData: $customData";
  }
}

/// ItemTag Image
class ItemTagsImage {
  ItemTagsImage({this.radius = 8, this.padding, this.image, this.child});

  final double radius;
  final EdgeInsets padding;
  final ImageProvider image;
  final Widget child;
}

/// ItemTag Icon
class ItemTagsIcon {
  ItemTagsIcon({this.padding, @required this.icon});

  final EdgeInsets padding;
  final IconData icon;
}

/// ItemTag RemoveButton
class ItemTagsRemoveButton {
  ItemTagsRemoveButton(
      {this.icon,
      this.size,
      this.backgroundColor,
      this.color,
      this.borderRadius,
      this.padding,
      this.margin,
      this.onRemoved});

  final IconData icon;
  final double size;
  final Color backgroundColor;
  final Color color;
  final BorderRadius borderRadius;
  final EdgeInsets padding;
  final EdgeInsets margin;

  /// callback
  final OnRemovedCallback onRemoved;
}


================================================
FILE: lib/src/suggestions_textfield.dart
================================================
import 'package:flutter/material.dart';

// InputSuggestions version 0.0.1
// currently yield inline suggestions
// I will soon implement a list with suggestions
// Credit Dn-a -> https://github.com/Dn-a

/// Used by [SuggestionsTextField.onChanged].
typedef OnChangedCallback = void Function(String string);

/// Used by [SuggestionsTextField.onSubmitted].
typedef OnSubmittedCallback = void Function(String string);

class SuggestionsTextField extends StatefulWidget {
  SuggestionsTextField(
      {@required this.tagsTextField, this.onSubmitted, Key key})
      : assert(tagsTextField != null),
        super(key: key);

  final TagsTextField tagsTextField;
  final OnSubmittedCallback onSubmitted;

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

class _SuggestionsTextFieldState extends State<SuggestionsTextField> {
  final _controller = TextEditingController();

  List<String> _matches = List();
  String _helperText;
  bool _helperCheck = true;

  List<String> _suggestions;
  bool _constraintSuggestion;
  double _fontSize;
  InputDecoration _inputDecoration;

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    _helperText = widget.tagsTextField.helperText ?? "no matches";
    _suggestions = widget.tagsTextField.suggestions;
    _constraintSuggestion = widget.tagsTextField.constraintSuggestion;
    _inputDecoration = widget.tagsTextField.inputDecoration;
    _fontSize = widget.tagsTextField.textStyle.fontSize;

    return Stack(
      alignment: Alignment.centerLeft,
      children: <Widget>[
        Visibility(
          visible: _suggestions != null,
          child: Container(
            //width: double.infinity,
            padding: _inputDecoration != null
                ? _inputDecoration.contentPadding
                : EdgeInsets.symmetric(
                    vertical: 6 * (_fontSize / 14),
                    horizontal: 6 * (_fontSize / 14)),
            child: Text(
              _matches.isNotEmpty ? (_matches.first) : "",
              softWrap: false,
              overflow: TextOverflow.fade,
              style: TextStyle(
                height: widget.tagsTextField.textStyle.height == null
                    ? 1
                    : widget.tagsTextField.textStyle.height,
                fontSize: _fontSize ?? null,
                color: widget.tagsTextField.suggestionTextColor ?? Colors.red,
              ),
            ),
          ),
        ),
        TextField(
          controller: _controller,
          enabled: widget.tagsTextField.enabled,
          autofocus: widget.tagsTextField.autofocus ?? true,
          keyboardType: widget.tagsTextField.keyboardType ?? null,
          textCapitalization: widget.tagsTextField.textCapitalization ??
              TextCapitalization.none,
          maxLength: widget.tagsTextField.maxLength ?? null,
          maxLines: 1,
          autocorrect: widget.tagsTextField.autocorrect ?? false,
          style: widget.tagsTextField.textStyle.copyWith(
              height: widget.tagsTextField.textStyle.height == null ? 1 : null),
          decoration: _initialInputDecoration,
          onChanged: (str) => _checkOnChanged(str),
          onSubmitted: (str) => _onSubmitted(str),
        )
      ],
    );
  }

  InputDecoration get _initialInputDecoration {
    var input = _inputDecoration ??
        InputDecoration(
            disabledBorder: InputBorder.none,
            errorBorder: InputBorder.none,
            contentPadding: EdgeInsets.symmetric(
                vertical: 6 * (_fontSize / 14),
                horizontal: 6 * (_fontSize / 14)),
            focusedBorder: UnderlineInputBorder(
              borderSide: BorderSide(
                color: Colors.blueGrey[300],
              ),
            ),
            enabledBorder: UnderlineInputBorder(
              borderSide:
                  BorderSide(color: Colors.blueGrey[400].withOpacity(0.3)),
            ),
            border: UnderlineInputBorder(
              borderSide:
                  BorderSide(color: Colors.blueGrey[400].withOpacity(0.3)),
            ));

    return input.copyWith(
        helperText: _helperCheck || _suggestions == null ? null : _helperText,
        helperStyle: widget.tagsTextField.helperTextStyle,
        hintText: widget.tagsTextField.hintText ?? 'Add a tag',
        hintStyle: TextStyle(color: widget.tagsTextField.hintTextColor));
  }

  ///OnSubmitted
  void _onSubmitted(String str) {
    var onSubmitted = widget.onSubmitted;

    if (_suggestions != null && _matches.isNotEmpty) str = _matches.first;

    if (widget.tagsTextField.lowerCase) str = str.toLowerCase();

    str = str.trim();

    if (_suggestions != null) {
      if (_matches.isNotEmpty || !_constraintSuggestion) {
        if (onSubmitted != null) onSubmitted(str);
        setState(() {
          _matches = [];
        });
        _controller.clear();
      }
    } else if (str.isNotEmpty) {
      if (onSubmitted != null) onSubmitted(str);
      _controller.clear();
    }
  }

  ///Check onChanged
  void _checkOnChanged(String str) {
    if (_suggestions != null) {
      _matches =
          _suggestions.where((String sgt) => sgt.startsWith(str)).toList();

      if (str.isEmpty) _matches = [];

      if (_matches.length > 1) _matches.removeWhere((String mtc) => mtc == str);

      setState(() {
        _helperCheck =
            _matches.isNotEmpty || str.isEmpty || !_constraintSuggestion
                ? true
                : false;
        _matches.sort((a, b) => a.compareTo(b));
      });
    }

    if (widget.tagsTextField.onChanged != null)
      widget.tagsTextField.onChanged(str);
  }
}

/// Tags TextField
class TagsTextField {
  TagsTextField(
      {this.lowerCase = false,
      this.textStyle = const TextStyle(fontSize: 14),
      this.width = 200,
      this.padding,
      this.enabled = true,
      this.duplicates = false,
      this.suggestions,
      this.constraintSuggestion = true,
      this.autocorrect,
      this.autofocus,
      this.hintText,
      this.hintTextColor,
      this.suggestionTextColor,
      this.helperText,
      this.helperTextStyle,
      this.keyboardType,
      this.textCapitalization,
      this.maxLength,
      this.inputDecoration,
      this.onSubmitted,
      this.onChanged});

  final double width;
  final EdgeInsets padding;
  final bool enabled;
  final bool duplicates;
  final TextStyle textStyle;
  final InputDecoration inputDecoration;
  final bool autocorrect;
  final List<String> suggestions;

  /// Allows you to insert tags not present in the list of suggestions
  final bool constraintSuggestion;
  final bool lowerCase;
  final bool autofocus;
  final String hintText;
  final Color hintTextColor;
  final Color suggestionTextColor;
  final String helperText;
  final TextStyle helperTextStyle;
  final TextInputType keyboardType;
  final TextCapitalization textCapitalization;
  final int maxLength;
  final OnSubmittedCallback onSubmitted;
  final OnChangedCallback onChanged;
}


================================================
FILE: lib/src/tags.dart
================================================
import 'package:flutter/material.dart';

import '../flutter_tags.dart';
import 'util/custom_wrap.dart';
import 'package:flutter_tags/src/suggestions_textfield.dart';

///ItemBuilder
typedef Widget ItemBuilder(int index);

class Tags extends StatefulWidget {
  Tags(
      {this.columns,
      this.itemCount = 0,
      this.symmetry = false,
      this.horizontalScroll = false,
      this.heightHorizontalScroll = 60,
      this.spacing = 6,
      this.runSpacing = 14,
      this.alignment = WrapAlignment.center,
      this.runAlignment = WrapAlignment.center,
      this.direction = Axis.horizontal,
      this.verticalDirection = VerticalDirection.down,
      this.textDirection = TextDirection.ltr,
      this.itemBuilder,
      this.textField,
      Key key})
      : assert(itemCount >= 0),
        assert(alignment != null),
        assert(runAlignment != null),
        assert(direction != null),
        assert(verticalDirection != null),
        assert(textDirection != null),
        super(key: key);

  ///specific number of columns
  final int columns;

  ///numer of item List
  final int itemCount;

  /// imposes the same width and the same number of columns for each row
  final bool symmetry;

  /// ability to scroll tags horizontally
  final bool horizontalScroll;

  /// horizontal spacing of  the [ItemTags]
  final double heightHorizontalScroll;

  /// horizontal spacing of  the [ItemTags]
  final double spacing;

  /// vertical spacing of  the [ItemTags]
  final double runSpacing;

  /// horizontal alignment of  the [ItemTags]
  final WrapAlignment alignment;

  /// vertical alignment of  the [ItemTags]
  final WrapAlignment runAlignment;

  /// direction of  the [ItemTags]
  final Axis direction;

  /// Iterate [Item] from the lower to the upper direction or vice versa
  final VerticalDirection verticalDirection;

  /// Text direction of  the [ItemTags]
  final TextDirection textDirection;

  /// Generates a list of [ItemTags].
  ///
  /// Creates a list with [length] positions and fills it with values created by
  /// calling [generator] for each index in the range `0` .. `length - 1`
  /// in increasing order.
  final ItemBuilder itemBuilder;

  /// custom TextField
  final TagsTextField textField;

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

class TagsState extends State<Tags> {
  final GlobalKey _containerKey = GlobalKey();
  Orientation _orientation = Orientation.portrait;
  double _width = 0;

  final List<DataList> _list = List();

  List<Item> get getAllItem => _list.toList();

  //get the current width of the screen
  void _getWidthContext() {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      final keyContext = _containerKey.currentContext;
      if (keyContext != null) {
        final RenderBox box = keyContext.findRenderObject();
        final size = box.size;
        setState(() {
          _width = size.width;
        });
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    // essential to avoid infinite loop of addPostFrameCallback
    if (widget.symmetry &&
        (MediaQuery.of(context).orientation != _orientation || _width == 0)) {
      _orientation = MediaQuery.of(context).orientation;
      _getWidthContext();
    }

    Widget child;
    if (widget.horizontalScroll && !widget.symmetry)
      child = Container(
        height: widget.heightHorizontalScroll,
        color: Colors.transparent,
        child: ListView(
          padding: EdgeInsets.all(0),
          scrollDirection: Axis.horizontal,
          shrinkWrap: true,
          physics: ClampingScrollPhysics(),
          children: _buildItems(),
        ),
      );
    else
      child = CustomWrap(
        key: _containerKey,
        alignment: widget.alignment,
        runAlignment: widget.runAlignment,
        spacing: widget.spacing,
        runSpacing: widget.runSpacing,
        column: widget.columns,
        symmetry: widget.symmetry,
        textDirection: widget.textDirection,
        direction: widget.direction,
        verticalDirection: widget.verticalDirection,
        crossAxisAlignment: WrapCrossAlignment.end,
        children: _buildItems(),
      );

    return DataListInherited(
      list: _list,
      symmetry: widget.symmetry,
      itemCount: widget.itemCount,
      child: child,
    );
  }

  List<Widget> _buildItems() {
    /*if(_list.length < widget.itemCount)
            _list.clear();*/

    final Widget textField = widget.textField != null
        ? Container(
            alignment: Alignment.center,
            width: widget.symmetry ? _widthCalc() : widget.textField.width,
            padding: widget.textField.padding,
            child: SuggestionsTextField(
              tagsTextField: widget.textField,
              onSubmitted: (String str) {
                if (!widget.textField.duplicates) {
                  final List<DataList> lst =
                      _list.where((l) => l.title == str).toList();

                  if (lst.isNotEmpty) {
                    lst.forEach((d) => d.showDuplicate = true);
                    return;
                  }
                }

                if (widget.textField.onSubmitted != null)
                  widget.textField.onSubmitted(str);
              },
            ),
          )
        : null;

    List<Widget> finalList = List();

    List<Widget> itemList = List.generate(widget.itemCount, (i) {
      final Widget item = widget.itemBuilder(i);
      if (widget.symmetry)
        return Container(
          width: _widthCalc(),
          child: item,
        );
      else if (widget.horizontalScroll)
        return Container(
          margin: EdgeInsets.symmetric(horizontal: widget.spacing),
          alignment: Alignment.center,
          child: item,
        );
      return item;
    });

    if (widget.horizontalScroll && widget.textDirection == TextDirection.rtl)
      itemList = itemList.reversed.toList();

    if (textField == null) {
      finalList.addAll(itemList);
      return finalList;
    }

    if (widget.horizontalScroll &&
        widget.verticalDirection == VerticalDirection.up) {
      finalList.add(textField);
      finalList.addAll(itemList);
    } else {
      finalList.addAll(itemList);
      finalList.add(textField);
    }

    return finalList;
  }

  //Container width divided by the number of columns when symmetry is active
  double _widthCalc() {
    int columns = widget.columns ?? 0;
    int margin = widget.spacing.round();

    int subtraction = columns * (margin);
    double width = (_width > 1) ? (_width - subtraction) / columns : _width;

    return width;
  }
}

/// Inherited Widget
class DataListInherited extends InheritedWidget {
  DataListInherited(
      {Key key, this.list, this.symmetry, this.itemCount, Widget child})
      : super(key: key, child: child);

  final List<DataList> list;
  final bool symmetry;
  final int itemCount;

  @override
  bool updateShouldNotify(DataListInherited old) {
    //print("inherited");
    return false;
  }

  /*static DataListInherited of(BuildContext context) =>
      context.inheritFromWidgetOfExactType(DataListInherited);*/
  static DataListInherited of(BuildContext context) =>
      context.dependOnInheritedWidgetOfExactType();
}

/// Data List
class DataList extends ValueNotifier implements Item {
  DataList(
      {@required this.title,
      this.index,
      bool highlights = false,
      bool active = true,
      this.customData})
      : _showDuplicate = highlights,
        _active = active,
        super(active);

  final String title;
  final dynamic customData;
  final int index;

  get showDuplicate {
    final val = _showDuplicate;
    _showDuplicate = false;
    return val;
  }

  bool _showDuplicate;
  set showDuplicate(bool a) {
    _showDuplicate = a;
    // rebuild only the specific Item that changes its value
    notifyListeners();
  }

  get active => _active;
  bool _active;
  set active(bool a) {
    _active = a;
    // rebuild only the specific Item that changes its value
    notifyListeners();
  }
}


================================================
FILE: lib/src/util/custom_wrap.dart
================================================
import 'dart:math' as math;
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

/// Custom Wrap
class CustomWrap extends MultiChildRenderObjectWidget {
  CustomWrap({
    Key key,
    this.column,
    this.symmetry,
    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);

  final int column;

  final bool symmetry;

  final Axis direction;

  final WrapAlignment alignment;

  final double spacing;

  final WrapAlignment runAlignment;

  final double runSpacing;

  final WrapCrossAlignment crossAxisAlignment;

  final TextDirection textDirection;

  final VerticalDirection verticalDirection;

  @override
  CustomRenderWrap createRenderObject(BuildContext context) {
    return CustomRenderWrap(
      column: column,
      symmetry: symmetry,
      direction: direction,
      alignment: alignment,
      spacing: spacing,
      runAlignment: runAlignment,
      runSpacing: runSpacing,
      crossAxisAlignment: crossAxisAlignment,
      textDirection: textDirection ?? Directionality.of(context),
      verticalDirection: verticalDirection,
    );
  }

  @override
  void updateRenderObject(BuildContext context, CustomRenderWrap renderObject) {
    renderObject
      ..column = column
      ..symmetry = symmetry
      ..direction = direction
      ..alignment = alignment
      ..spacing = spacing
      ..runAlignment = runAlignment
      ..runSpacing = runSpacing
      ..crossAxisAlignment = crossAxisAlignment
      ..textDirection = textDirection ?? Directionality.of(context)
      ..verticalDirection = verticalDirection;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(EnumProperty<Axis>('direction', direction));
    properties.add(EnumProperty<WrapAlignment>('alignment', alignment));
    properties.add(DoubleProperty('spacing', spacing));
    properties.add(EnumProperty<WrapAlignment>('runAlignment', runAlignment));
    properties.add(DoubleProperty('runSpacing', runSpacing));
    properties.add(DoubleProperty('crossAxisAlignment', runSpacing));
    properties.add(EnumProperty<TextDirection>('textDirection', textDirection,
        defaultValue: null));
    properties.add(EnumProperty<VerticalDirection>(
        'verticalDirection', verticalDirection,
        defaultValue: VerticalDirection.down));
  }
}

/// Displays its children in multiple horizontal or vertical runs.
class CustomRenderWrap extends RenderBox
    with
        ContainerRenderObjectMixin<RenderBox, WrapParentData>,
        RenderBoxContainerDefaultsMixin<RenderBox, WrapParentData> {
  CustomRenderWrap({
    List<RenderBox> children,
    int column,
    bool symmetry,
    Axis direction = Axis.horizontal,
    WrapAlignment alignment = WrapAlignment.start,
    double spacing = 0.0,
    WrapAlignment runAlignment = WrapAlignment.start,
    double runSpacing = 0.0,
    WrapCrossAlignment crossAxisAlignment = WrapCrossAlignment.start,
    TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
  })  : assert(direction != null),
        assert(alignment != null),
        assert(spacing != null),
        assert(runAlignment != null),
        assert(runSpacing != null),
        assert(crossAxisAlignment != null),
        _column = column,
        _symmetry = symmetry,
        _direction = direction,
        _alignment = alignment,
        _spacing = spacing,
        _runAlignment = runAlignment,
        _runSpacing = runSpacing,
        _crossAxisAlignment = crossAxisAlignment,
        _textDirection = textDirection,
        _verticalDirection = verticalDirection {
    addAll(children);
  }

  int get column => _column;
  int _column;
  set column(int value) {
    if (column == value) return;
    _column = value;
    markNeedsLayout();
  }

  bool get symmetry => _symmetry;
  bool _symmetry;
  set symmetry(bool value) {
    if (symmetry == value) return;
    _symmetry = value;
    markNeedsLayout();
  }

  Axis get direction => _direction;
  Axis _direction;
  set direction(Axis value) {
    assert(value != null);
    if (_direction == value) return;
    _direction = value;
    markNeedsLayout();
  }

  WrapAlignment get alignment => _alignment;
  WrapAlignment _alignment;
  set alignment(WrapAlignment value) {
    assert(value != null);
    if (_alignment == value) return;
    _alignment = value;
    markNeedsLayout();
  }

  double get spacing => _spacing;
  double _spacing;
  set spacing(double value) {
    assert(value != null);
    if (_spacing == value) return;
    _spacing = value;
    markNeedsLayout();
  }

  WrapAlignment get runAlignment => _runAlignment;
  WrapAlignment _runAlignment;
  set runAlignment(WrapAlignment value) {
    assert(value != null);
    if (_runAlignment == value) return;
    _runAlignment = value;
    markNeedsLayout();
  }

  double get runSpacing => _runSpacing;
  double _runSpacing;
  set runSpacing(double value) {
    assert(value != null);
    if (_runSpacing == value) return;
    _runSpacing = value;
    markNeedsLayout();
  }

  WrapCrossAlignment get crossAxisAlignment => _crossAxisAlignment;
  WrapCrossAlignment _crossAxisAlignment;
  set crossAxisAlignment(WrapCrossAlignment value) {
    assert(value != null);
    if (_crossAxisAlignment == value) return;
    _crossAxisAlignment = value;
    markNeedsLayout();
  }

  TextDirection get textDirection => _textDirection;
  TextDirection _textDirection;
  set textDirection(TextDirection value) {
    if (_textDirection != value) {
      _textDirection = value;
      markNeedsLayout();
    }
  }

  VerticalDirection get verticalDirection => _verticalDirection;
  VerticalDirection _verticalDirection;
  set verticalDirection(VerticalDirection value) {
    if (_verticalDirection != value) {
      _verticalDirection = value;
      markNeedsLayout();
    }
  }

  bool get _debugHasNecessaryDirections {
    assert(direction != null);
    assert(alignment != null);
    assert(runAlignment != null);
    assert(crossAxisAlignment != null);
    if (firstChild != null && lastChild != firstChild) {
      // i.e. there's more than one child
      switch (direction) {
        case Axis.horizontal:
          assert(textDirection != null,
              'Horizontal $runtimeType with multiple children has a null textDirection, so the layout order is undefined.');
          break;
        case Axis.vertical:
          assert(verticalDirection != null,
              'Vertical $runtimeType with multiple children has a null verticalDirection, so the layout order is undefined.');
          break;
      }
    }
    if (alignment == WrapAlignment.start || alignment == WrapAlignment.end) {
      switch (direction) {
        case Axis.horizontal:
          assert(textDirection != null,
              'Horizontal $runtimeType with alignment $alignment has a null textDirection, so the alignment cannot be resolved.');
          break;
        case Axis.vertical:
          assert(verticalDirection != null,
              'Vertical $runtimeType with alignment $alignment has a null verticalDirection, so the alignment cannot be resolved.');
          break;
      }
    }
    if (runAlignment == WrapAlignment.start ||
        runAlignment == WrapAlignment.end) {
      switch (direction) {
        case Axis.horizontal:
          assert(verticalDirection != null,
              'Horizontal $runtimeType with runAlignment $runAlignment has a null verticalDirection, so the alignment cannot be resolved.');
          break;
        case Axis.vertical:
          assert(textDirection != null,
              'Vertical $runtimeType with runAlignment $runAlignment has a null textDirection, so the alignment cannot be resolved.');
          break;
      }
    }
    if (crossAxisAlignment == WrapCrossAlignment.start ||
        crossAxisAlignment == WrapCrossAlignment.end) {
      switch (direction) {
        case Axis.horizontal:
          assert(verticalDirection != null,
              'Horizontal $runtimeType with crossAxisAlignment $crossAxisAlignment has a null verticalDirection, so the alignment cannot be resolved.');
          break;
        case Axis.vertical:
          assert(textDirection != null,
              'Vertical $runtimeType with crossAxisAlignment $crossAxisAlignment has a null textDirection, so the alignment cannot be resolved.');
          break;
      }
    }
    return true;
  }

  @override
  void setupParentData(RenderBox child) {
    if (child.parentData is! WrapParentData)
      child.parentData = WrapParentData();
  }

  double _computeIntrinsicHeightForWidth(double width) {
    assert(direction == Axis.horizontal);
    int runCount = 0;
    double height = 0.0;
    double runWidth = 0.0;
    double runHeight = 0.0;
    int childCount = 0;
    RenderBox child = firstChild;
    while (child != null) {
      final double childWidth = child.getMaxIntrinsicWidth(double.infinity);
      final double childHeight = child.getMaxIntrinsicHeight(childWidth);
      if (runWidth + childWidth > width) {
        height += runHeight;
        if (runCount > 0) height += runSpacing;
        runCount += 1;
        runWidth = 0.0;
        runHeight = 0.0;
        childCount = 0;
      }
      runWidth += childWidth;
      runHeight = math.max(runHeight, childHeight);
      if (childCount > 0) runWidth += spacing;
      childCount += 1;
      child = childAfter(child);
    }
    if (childCount > 0) height += runHeight + runSpacing;
    return height;
  }

  double _computeIntrinsicWidthForHeight(double height) {
    assert(direction == Axis.vertical);
    int runCount = 0;
    double width = 0.0;
    double runHeight = 0.0;
    double runWidth = 0.0;
    int childCount = 0;
    RenderBox child = firstChild;
    while (child != null) {
      final double childHeight = child.getMaxIntrinsicHeight(double.infinity);
      final double childWidth = child.getMaxIntrinsicWidth(childHeight);
      if (runHeight + childHeight > height) {
        width += runWidth;
        if (runCount > 0) width += runSpacing;
        runCount += 1;
        runHeight = 0.0;
        runWidth = 0.0;
        childCount = 0;
      }
      runHeight += childHeight;
      runWidth = math.max(runWidth, childWidth);
      if (childCount > 0) runHeight += spacing;
      childCount += 1;
      child = childAfter(child);
    }
    if (childCount > 0) width += runWidth + runSpacing;
    return width;
  }

  @override
  double computeMinIntrinsicWidth(double height) {
    switch (direction) {
      case Axis.horizontal:
        double width = 0.0;
        RenderBox child = firstChild;
        while (child != null) {
          width = math.max(width, child.getMinIntrinsicWidth(double.infinity));
          child = childAfter(child);
        }
        return width;
      case Axis.vertical:
        return _computeIntrinsicWidthForHeight(height);
    }
    return null;
  }

  @override
  double computeMaxIntrinsicWidth(double height) {
    switch (direction) {
      case Axis.horizontal:
        double width = 0.0;
        RenderBox child = firstChild;
        while (child != null) {
          width += child.getMaxIntrinsicWidth(double.infinity);
          child = childAfter(child);
        }
        return width;
      case Axis.vertical:
        return _computeIntrinsicWidthForHeight(height);
    }
    return null;
  }

  @override
  double computeMinIntrinsicHeight(double width) {
    switch (direction) {
      case Axis.horizontal:
        return _computeIntrinsicHeightForWidth(width);
      case Axis.vertical:
        double height = 0.0;
        RenderBox child = firstChild;
        while (child != null) {
          height =
              math.max(height, child.getMinIntrinsicHeight(double.infinity));
          child = childAfter(child);
        }
        return height;
    }
    return null;
  }

  @override
  double computeMaxIntrinsicHeight(double width) {
    switch (direction) {
      case Axis.horizontal:
        return _computeIntrinsicHeightForWidth(width);
      case Axis.vertical:
        double height = 0.0;
        RenderBox child = firstChild;
        while (child != null) {
          height += child.getMaxIntrinsicHeight(double.infinity);
          child = childAfter(child);
        }
        return height;
    }
    return null;
  }

  @override
  double computeDistanceToActualBaseline(TextBaseline baseline) {
    return defaultComputeDistanceToHighestActualBaseline(baseline);
  }

  double _getMainAxisExtent(RenderBox child) {
    switch (direction) {
      case Axis.horizontal:
        return child.size.width;
      case Axis.vertical:
        return child.size.height;
    }
    return 0.0;
  }

  double _getCrossAxisExtent(RenderBox child) {
    switch (direction) {
      case Axis.horizontal:
        return child.size.height;
      case Axis.vertical:
        return child.size.width;
    }
    return 0.0;
  }

  Offset _getOffset(double mainAxisOffset, double crossAxisOffset) {
    switch (direction) {
      case Axis.horizontal:
        return Offset(mainAxisOffset, crossAxisOffset);
      case Axis.vertical:
        return Offset(crossAxisOffset, mainAxisOffset);
    }
    return Offset.zero;
  }

  double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxisExtent,
      double childCrossAxisExtent) {
    final double freeSpace = runCrossAxisExtent - childCrossAxisExtent;
    switch (crossAxisAlignment) {
      case WrapCrossAlignment.start:
        return flipCrossAxis ? freeSpace : 0.0;
      case WrapCrossAlignment.end:
        return flipCrossAxis ? 0.0 : freeSpace;
      case WrapCrossAlignment.center:
        return freeSpace / 2.0;
    }
    return 0.0;
  }

  bool _hasVisualOverflow = false;

  @override
  void performLayout() {
    assert(_debugHasNecessaryDirections);
    _hasVisualOverflow = false;
    RenderBox child = firstChild;
    if (child == null) {
      size = constraints.smallest;
      return;
    }
    BoxConstraints childConstraints;
    double mainAxisLimit = 0.0;
    bool flipMainAxis = false;
    bool flipCrossAxis = false;
    switch (direction) {
      case Axis.horizontal:
        childConstraints = BoxConstraints(maxWidth: constraints.maxWidth);
        mainAxisLimit = constraints.maxWidth;
        if (textDirection == TextDirection.rtl) flipMainAxis = true;
        if (verticalDirection == VerticalDirection.up) flipCrossAxis = true;
        break;
      case Axis.vertical:
        childConstraints = BoxConstraints(maxHeight: constraints.maxHeight);
        mainAxisLimit = constraints.maxHeight;
        if (verticalDirection == VerticalDirection.up) flipMainAxis = true;
        if (textDirection == TextDirection.rtl) flipCrossAxis = true;
        break;
    }
    assert(childConstraints != null);
    assert(mainAxisLimit != null);
    final double spacing = this.spacing;
    final double runSpacing = this.runSpacing;
    final List<_RunMetrics> runMetrics = <_RunMetrics>[];
    double mainAxisExtent = 0.0;
    double crossAxisExtent = 0.0;
    double runMainAxisExtent = 0.0;
    double runCrossAxisExtent = 0.0;
    int childCount = 0;

    int cnt = 0;
    while (child != null) {
      child.layout(childConstraints, parentUsesSize: true);
      final double childMainAxisExtent = _getMainAxisExtent(child);
      final double childCrossAxisExtent = _getCrossAxisExtent(child);
      if ((childCount > 0 &&
              runMainAxisExtent + spacing + childMainAxisExtent >
                  mainAxisLimit) ||
          (_column != null && _column != 0 && cnt == _column)) {
        cnt = 0;
        mainAxisExtent = math.max(mainAxisExtent, runMainAxisExtent);
        crossAxisExtent += runCrossAxisExtent;
        if (runMetrics.isNotEmpty) crossAxisExtent += runSpacing;
        runMetrics.add(
            _RunMetrics(runMainAxisExtent, runCrossAxisExtent, childCount));
        runMainAxisExtent = 0.0;
        runCrossAxisExtent = 0.0;
        childCount = 0;
      }
      cnt++;
      runMainAxisExtent += childMainAxisExtent;
      if (childCount > 0) runMainAxisExtent += spacing;
      runCrossAxisExtent = math.max(runCrossAxisExtent, childCrossAxisExtent);
      childCount += 1;
      final WrapParentData childParentData = child.parentData;
      childParentData._runIndex = runMetrics.length;
      child = childParentData.nextSibling;
    }
    if (childCount > 0) {
      mainAxisExtent = math.max(mainAxisExtent, runMainAxisExtent);
      crossAxisExtent += runCrossAxisExtent;
      if (runMetrics.isNotEmpty) crossAxisExtent += runSpacing;
      runMetrics
          .add(_RunMetrics(runMainAxisExtent, runCrossAxisExtent, childCount));
    }

    final int runCount = runMetrics.length;
    assert(runCount > 0);

    double containerMainAxisExtent = 0.0;
    double containerCrossAxisExtent = 0.0;

    switch (direction) {
      case Axis.horizontal:
        size = constraints.constrain(Size(mainAxisExtent, crossAxisExtent));
        containerMainAxisExtent = size.width;
        containerCrossAxisExtent = size.height;
        break;
      case Axis.vertical:
        size = constraints.constrain(Size(crossAxisExtent, mainAxisExtent));
        containerMainAxisExtent = size.height;
        containerCrossAxisExtent = size.width;
        break;
    }

    _hasVisualOverflow = containerMainAxisExtent < mainAxisExtent ||
        containerCrossAxisExtent < crossAxisExtent;

    final double crossAxisFreeSpace =
        math.max(0.0, containerCrossAxisExtent - crossAxisExtent);
    double runLeadingSpace = 0.0;
    double runBetweenSpace = 0.0;
    switch (runAlignment) {
      case WrapAlignment.start:
        break;
      case WrapAlignment.end:
        runLeadingSpace = crossAxisFreeSpace;
        break;
      case WrapAlignment.center:
        runLeadingSpace = crossAxisFreeSpace / 2.0;
        break;
      case WrapAlignment.spaceBetween:
        runBetweenSpace =
            runCount > 1 ? crossAxisFreeSpace / (runCount - 1) : 0.0;
        break;
      case WrapAlignment.spaceAround:
        runBetweenSpace = crossAxisFreeSpace / runCount;
        runLeadingSpace = runBetweenSpace / 2.0;
        break;
      case WrapAlignment.spaceEvenly:
        runBetweenSpace = crossAxisFreeSpace / (runCount + 1);
        runLeadingSpace = runBetweenSpace;
        break;
    }

    runBetweenSpace += runSpacing;
    double crossAxisOffset = flipCrossAxis
        ? containerCrossAxisExtent - runLeadingSpace
        : runLeadingSpace;

    child = firstChild;
    for (int i = 0; i < runCount; ++i) {
      final _RunMetrics metrics = runMetrics[i];
      final double runMainAxisExtent = metrics.mainAxisExtent;
      final double runCrossAxisExtent = metrics.crossAxisExtent;
      final int childCount = metrics.childCount;

      final double mainAxisFreeSpace =
          math.max(0.0, containerMainAxisExtent - runMainAxisExtent);
      double childLeadingSpace = 0.0;
      double childBetweenSpace = 0.0;

      //print(symmetry);
      switch (alignment) {
        case WrapAlignment.start:
          if (symmetry) childLeadingSpace = spacing / 2;
          break;
        case WrapAlignment.end:
          childLeadingSpace = mainAxisFreeSpace;
          if (symmetry) childLeadingSpace = mainAxisFreeSpace - spacing / 2;
          break;
        case WrapAlignment.center:
          childLeadingSpace = mainAxisFreeSpace / 2.0;
          break;
        case WrapAlignment.spaceBetween:
          childBetweenSpace =
              childCount > 1 ? mainAxisFreeSpace / (childCount - 1) : 0.0;
          break;
        case WrapAlignment.spaceAround:
          childBetweenSpace = mainAxisFreeSpace / childCount;
          childLeadingSpace = childBetweenSpace / 2.0;
          break;
        case WrapAlignment.spaceEvenly:
          childBetweenSpace = mainAxisFreeSpace / (childCount + 1);
          childLeadingSpace = childBetweenSpace;
          break;
      }

      childBetweenSpace += spacing;
      double childMainPosition = flipMainAxis
          ? containerMainAxisExtent - childLeadingSpace
          : childLeadingSpace;

      if (flipCrossAxis) crossAxisOffset -= runCrossAxisExtent;

      while (child != null) {
        final WrapParentData childParentData = child.parentData;
        if (childParentData._runIndex != i) break;
        final double childMainAxisExtent = _getMainAxisExtent(child);
        final double childCrossAxisExtent = _getCrossAxisExtent(child);
        final double childCrossAxisOffset = _getChildCrossAxisOffset(
            flipCrossAxis, runCrossAxisExtent, childCrossAxisExtent);
        if (flipMainAxis) childMainPosition -= childMainAxisExtent;
        childParentData.offset = _getOffset(
            childMainPosition, crossAxisOffset + childCrossAxisOffset);
        if (flipMainAxis)
          childMainPosition -= childBetweenSpace;
        else
          childMainPosition += childMainAxisExtent + childBetweenSpace;
        child = childParentData.nextSibling;
      }

      if (flipCrossAxis)
        crossAxisOffset -= runBetweenSpace;
      else
        crossAxisOffset += runCrossAxisExtent + runBetweenSpace;
    }
  }

  @override
  bool hitTestChildren(HitTestResult result, {Offset position}) {
    return defaultHitTestChildren(result, position: position);
  }

  @override
  void paint(PaintingContext context, Offset offset) {
    // TODO(ianh): move the debug flex overflow paint logic somewhere common so
    // it can be reused here
    if (_hasVisualOverflow)
      context.pushClipRect(
          needsCompositing, offset, Offset.zero & size, defaultPaint);
    else
      defaultPaint(context, offset);
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(EnumProperty<Axis>('direction', direction));
    properties.add(EnumProperty<WrapAlignment>('alignment', alignment));
    properties.add(DoubleProperty('spacing', spacing));
    properties.add(EnumProperty<WrapAlignment>('runAlignment', runAlignment));
    properties.add(DoubleProperty('runSpacing', runSpacing));
    properties.add(DoubleProperty('crossAxisAlignment', runSpacing));
    properties.add(EnumProperty<TextDirection>('textDirection', textDirection,
        defaultValue: null));
    properties.add(EnumProperty<VerticalDirection>(
        'verticalDirection', verticalDirection,
        defaultValue: VerticalDirection.down));
  }
}

class _RunMetrics {
  _RunMetrics(this.mainAxisExtent, this.crossAxisExtent, this.childCount);

  final double mainAxisExtent;
  final double crossAxisExtent;
  final int childCount;
}

/// Parent data for use with [CustomRenderWrap].
class WrapParentData extends ContainerBoxParentData<RenderBox> {
  int _runIndex = 0;
}


================================================
FILE: pubspec.yaml
================================================
name: flutter_tags
description: Creating selectable and input tags (TextField) has never been easier.
version: 0.4.9+1
author: Antonino Di Natale <gyorgio88@gmail.com>
homepage: https://github.com/Dn-a/flutter_tags

environment:
  sdk: ">=2.0.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

dev_dependencies:
  flutter_test:
    sdk: flutter


================================================
FILE: test/flutter_tags_test.dart
================================================
import 'package:flutter_test/flutter_test.dart';

void main() {}
Download .txt
gitextract_ehrk8p54/

├── .gitignore
├── .metadata
├── CHANGELOG.md
├── LICENSE
├── README.md
├── example/
│   ├── .gitignore
│   ├── .metadata
│   ├── README.md
│   ├── ios/
│   │   ├── Flutter/
│   │   │   ├── AppFrameworkInfo.plist
│   │   │   ├── Debug.xcconfig
│   │   │   ├── Release.xcconfig
│   │   │   └── flutter_export_environment.sh
│   │   ├── Runner/
│   │   │   ├── AppDelegate.swift
│   │   │   ├── Assets.xcassets/
│   │   │   │   ├── AppIcon.appiconset/
│   │   │   │   │   └── Contents.json
│   │   │   │   └── LaunchImage.imageset/
│   │   │   │       ├── Contents.json
│   │   │   │       └── README.md
│   │   │   ├── Base.lproj/
│   │   │   │   ├── LaunchScreen.storyboard
│   │   │   │   └── Main.storyboard
│   │   │   ├── Info.plist
│   │   │   └── Runner-Bridging-Header.h
│   │   ├── Runner.xcodeproj/
│   │   │   ├── project.pbxproj
│   │   │   ├── project.xcworkspace/
│   │   │   │   └── contents.xcworkspacedata
│   │   │   └── xcshareddata/
│   │   │       └── xcschemes/
│   │   │           └── Runner.xcscheme
│   │   └── Runner.xcworkspace/
│   │       └── contents.xcworkspacedata
│   ├── lib/
│   │   └── main.dart
│   ├── pubspec.yaml
│   └── test/
│       └── widget_test.dart
├── flutter_tags.iml
├── lib/
│   ├── flutter_tags.dart
│   └── src/
│       ├── item_tags.dart
│       ├── suggestions_textfield.dart
│       ├── tags.dart
│       └── util/
│           └── custom_wrap.dart
├── pubspec.yaml
└── test/
    └── flutter_tags_test.dart
Download .txt
SYMBOL INDEX (73 symbols across 7 files)

FILE: example/lib/main.dart
  function main (line 7) | void main()
  class MyApp (line 9) | class MyApp extends StatelessWidget {
    method build (line 12) | Widget build(BuildContext context)
  class MyHomePage (line 23) | class MyHomePage extends StatefulWidget {
    method createState (line 28) | _MyHomePageState createState()
  class _MyHomePageState (line 31) | class _MyHomePageState extends State<MyHomePage>
    method initState (line 87) | void initState()
    method build (line 100) | Widget build(BuildContext context)
    method _buildItems (line 694) | List<DropdownMenuItem> _buildItems()
    method _buildItems2 (line 717) | List<DropdownMenuItem> _buildItems2()

FILE: example/test/widget_test.dart
  function main (line 3) | void main()

FILE: lib/src/item_tags.dart
  type OnPressedCallback (line 6) | typedef OnPressedCallback = void Function(Item i);
  type OnLongPressedCallback (line 9) | typedef OnLongPressedCallback = void Function(Item i);
  type OnRemovedCallback (line 12) | typedef OnRemovedCallback = bool Function();
  type ItemTagsCombine (line 15) | enum ItemTagsCombine {
  class ItemTags (line 24) | class ItemTags extends StatefulWidget {
    method createState (line 140) | _ItemTagsState createState()
  class _ItemTagsState (line 143) | class _ItemTagsState extends State<ItemTags> {
    method _setDataList (line 149) | void _setDataList()
    method dispose (line 207) | void dispose()
    method build (line 213) | Widget build(BuildContext context)
    method _singleItem (line 437) | void _singleItem(DataListInherited dataSetIn, DataList dataSet)
  class Item (line 447) | class Item {
    method toString (line 455) | String toString()
  class ItemTagsImage (line 461) | class ItemTagsImage {
  class ItemTagsIcon (line 471) | class ItemTagsIcon {
  class ItemTagsRemoveButton (line 479) | class ItemTagsRemoveButton {

FILE: lib/src/suggestions_textfield.dart
  type OnChangedCallback (line 9) | typedef OnChangedCallback = void Function(String string);
  type OnSubmittedCallback (line 12) | typedef OnSubmittedCallback = void Function(String string);
  class SuggestionsTextField (line 14) | class SuggestionsTextField extends StatefulWidget {
    method createState (line 24) | _SuggestionsTextFieldState createState()
  class _SuggestionsTextFieldState (line 27) | class _SuggestionsTextFieldState extends State<SuggestionsTextField> {
    method initState (line 40) | void initState()
    method build (line 45) | Widget build(BuildContext context)
    method _onSubmitted (line 128) | void _onSubmitted(String str)
    method _checkOnChanged (line 152) | void _checkOnChanged(String str)
  class TagsTextField (line 176) | class TagsTextField {

FILE: lib/src/tags.dart
  type Widget (line 8) | typedef Widget ItemBuilder(int index);
  class Tags (line 10) | class Tags extends StatefulWidget {
    method createState (line 82) | TagsState createState()
  class TagsState (line 85) | class TagsState extends State<Tags> {
    method _getWidthContext (line 95) | void _getWidthContext()
    method build (line 109) | Widget build(BuildContext context)
    method _buildItems (line 154) | List<Widget> _buildItems()
    method _widthCalc (line 222) | double _widthCalc()
  class DataListInherited (line 234) | class DataListInherited extends InheritedWidget {
    method updateShouldNotify (line 244) | bool updateShouldNotify(DataListInherited old)
    method of (line 251) | DataListInherited of(BuildContext context)
  class DataList (line 256) | class DataList extends ValueNotifier implements Item {

FILE: lib/src/util/custom_wrap.dart
  class CustomWrap (line 6) | class CustomWrap extends MultiChildRenderObjectWidget {
    method createRenderObject (line 43) | CustomRenderWrap createRenderObject(BuildContext context)
    method updateRenderObject (line 59) | void updateRenderObject(BuildContext context, CustomRenderWrap renderO...
    method debugFillProperties (line 74) | void debugFillProperties(DiagnosticPropertiesBuilder properties)
  class CustomRenderWrap (line 91) | class CustomRenderWrap extends RenderBox
    method setupParentData (line 274) | void setupParentData(RenderBox child)
    method _computeIntrinsicHeightForWidth (line 279) | double _computeIntrinsicHeightForWidth(double width)
    method _computeIntrinsicWidthForHeight (line 308) | double _computeIntrinsicWidthForHeight(double height)
    method computeMinIntrinsicWidth (line 338) | double computeMinIntrinsicWidth(double height)
    method computeMaxIntrinsicWidth (line 355) | double computeMaxIntrinsicWidth(double height)
    method computeMinIntrinsicHeight (line 372) | double computeMinIntrinsicHeight(double width)
    method computeMaxIntrinsicHeight (line 390) | double computeMaxIntrinsicHeight(double width)
    method computeDistanceToActualBaseline (line 407) | double computeDistanceToActualBaseline(TextBaseline baseline)
    method _getMainAxisExtent (line 411) | double _getMainAxisExtent(RenderBox child)
    method _getCrossAxisExtent (line 421) | double _getCrossAxisExtent(RenderBox child)
    method _getOffset (line 431) | Offset _getOffset(double mainAxisOffset, double crossAxisOffset)
    method _getChildCrossAxisOffset (line 441) | double _getChildCrossAxisOffset(bool flipCrossAxis, double runCrossAxi...
    method performLayout (line 458) | void performLayout()
    method hitTestChildren (line 655) | bool hitTestChildren(HitTestResult result, {Offset position})
    method paint (line 660) | void paint(PaintingContext context, Offset offset)
    method debugFillProperties (line 671) | void debugFillProperties(DiagnosticPropertiesBuilder properties)
  class _RunMetrics (line 687) | class _RunMetrics {
  class WrapParentData (line 696) | class WrapParentData extends ContainerBoxParentData<RenderBox> {

FILE: test/flutter_tags_test.dart
  function main (line 3) | void main()
Condensed preview — 35 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (172K chars).
[
  {
    "path": ".gitignore",
    "chars": 228,
    "preview": ".DS_Store\n.dart_tool/\n\n.packages\n.pub/\n\nbuild/\nios/.generated/\nios/Flutter/Generated.xcconfig\nios/Runner/GeneratedPlugin"
  },
  {
    "path": ".metadata",
    "chars": 307,
    "preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 4363,
    "preview": "## [0.4.9+1] - 2020-11-11.\n\n* `[Fixed]` - Issue #66.\n* `[Fixed]` - `DataList` null id.\n\n## [0.4.9] - 2020-09-15.\n\n* `[Ad"
  },
  {
    "path": "LICENSE",
    "chars": 1083,
    "preview": "The MIT License (MIT)\n\nCopyright (c) 2018 Antonino Di Natale\n\nPermission is hereby granted, free of charge, to any perso"
  },
  {
    "path": "README.md",
    "chars": 6499,
    "preview": "# flutter_tags\n[![pub package](https://img.shields.io/badge/pub-0.4.9+1-orange.svg)](https://pub.dartlang.org/packages/f"
  },
  {
    "path": "example/.gitignore",
    "chars": 1294,
    "preview": "# Miscellaneous\n*.class\n*.lock\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*."
  },
  {
    "path": "example/.metadata",
    "chars": 303,
    "preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
  },
  {
    "path": "example/README.md",
    "chars": 27633,
    "preview": "# Example Flutter Tags\n\nAn example of how you could implement it.\n\n## Getting Started - Selectable Tags\n```dart\nimport '"
  },
  {
    "path": "example/ios/Flutter/AppFrameworkInfo.plist",
    "chars": 773,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "example/ios/Flutter/Debug.xcconfig",
    "chars": 30,
    "preview": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Flutter/Release.xcconfig",
    "chars": 30,
    "preview": "#include \"Generated.xcconfig\"\n"
  },
  {
    "path": "example/ios/Flutter/flutter_export_environment.sh",
    "chars": 641,
    "preview": "#!/bin/sh\n# This is a generated file; do not edit or check into version control.\nexport \"FLUTTER_ROOT=C:\\flutter\"\nexport"
  },
  {
    "path": "example/ios/Runner/AppDelegate.swift",
    "chars": 403,
    "preview": "import UIKit\nimport Flutter\n\n@UIApplicationMain\n@objc class AppDelegate: FlutterAppDelegate {\n  override func applicatio"
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json",
    "chars": 2519,
    "preview": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"Icon-App-20x20@2x.png\",\n   "
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json",
    "chars": 391,
    "preview": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"LaunchImage.png\",\n      \"scale\" : \"1x\"\n    },\n  "
  },
  {
    "path": "example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md",
    "chars": 336,
    "preview": "# Launch Screen Assets\n\nYou can customize the launch screen with your own desired assets by replacing the image files in"
  },
  {
    "path": "example/ios/Runner/Base.lproj/LaunchScreen.storyboard",
    "chars": 2377,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
  },
  {
    "path": "example/ios/Runner/Base.lproj/Main.storyboard",
    "chars": 1605,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
  },
  {
    "path": "example/ios/Runner/Info.plist",
    "chars": 1518,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
  },
  {
    "path": "example/ios/Runner/Runner-Bridging-Header.h",
    "chars": 37,
    "preview": "#import \"GeneratedPluginRegistrant.h\""
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.pbxproj",
    "chars": 21251,
    "preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 46;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
  },
  {
    "path": "example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
    "chars": 152,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodepr"
  },
  {
    "path": "example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme",
    "chars": 3331,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"0910\"\n   version = \"1.3\">\n   <BuildAction\n      "
  },
  {
    "path": "example/ios/Runner.xcworkspace/contents.xcworkspacedata",
    "chars": 152,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n   version = \"1.0\">\n   <FileRef\n      location = \"group:Runner.xcodepr"
  },
  {
    "path": "example/lib/main.dart",
    "chars": 26929,
    "preview": "import 'dart:convert';\nimport 'package:flutter/material.dart';\nimport 'package:flutter/services.dart';\n\nimport 'package:"
  },
  {
    "path": "example/pubspec.yaml",
    "chars": 2315,
    "preview": "name: example_flutter_tags\ndescription: A new Flutter application.\n\n# The following defines the version and build number"
  },
  {
    "path": "example/test/widget_test.dart",
    "chars": 56,
    "preview": "import 'package:flutter/material.dart';\n\nvoid main() {}\n"
  },
  {
    "path": "flutter_tags.iml",
    "chars": 1742,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <fa"
  },
  {
    "path": "lib/flutter_tags.dart",
    "chars": 117,
    "preview": "library flutter_tags;\n\nexport 'src/suggestions_textfield.dart';\nexport 'src/item_tags.dart';\nexport 'src/tags.dart';\n"
  },
  {
    "path": "lib/src/item_tags.dart",
    "chars": 15434,
    "preview": "import 'package:flutter/material.dart';\nimport 'package:flutter/widgets.dart';\nimport 'package:flutter_tags/src/tags.dar"
  },
  {
    "path": "lib/src/suggestions_textfield.dart",
    "chars": 7083,
    "preview": "import 'package:flutter/material.dart';\n\n// InputSuggestions version 0.0.1\n// currently yield inline suggestions\n// I wi"
  },
  {
    "path": "lib/src/tags.dart",
    "chars": 8057,
    "preview": "import 'package:flutter/material.dart';\n\nimport '../flutter_tags.dart';\nimport 'util/custom_wrap.dart';\nimport 'package:"
  },
  {
    "path": "lib/src/util/custom_wrap.dart",
    "chars": 23068,
    "preview": "import 'dart:math' as math;\nimport 'package:flutter/rendering.dart';\nimport 'package:flutter/widgets.dart';\n\n/// Custom "
  },
  {
    "path": "pubspec.yaml",
    "chars": 348,
    "preview": "name: flutter_tags\ndescription: Creating selectable and input tags (TextField) has never been easier.\nversion: 0.4.9+1\na"
  },
  {
    "path": "test/flutter_tags_test.dart",
    "chars": 65,
    "preview": "import 'package:flutter_test/flutter_test.dart';\n\nvoid main() {}\n"
  }
]

About this extraction

This page contains the full source code of the Dn-a/flutter_tags GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 35 files (158.7 KB), approximately 37.3k tokens, and a symbol index with 73 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!