expanded_wrap 1.0.1 copy "expanded_wrap: ^1.0.1" to clipboard
expanded_wrap: ^1.0.1 copied to clipboard

A expanded wrap.

example/lib/main.dart

import 'dart:math';

import 'package:expanded_wrap/expanded_wrap.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  const MyApp({super.key});

  @override
  State<StatefulWidget> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  List<String> textList = [];

  int minLines = 2;
  int? maxLines;

  //ExpandedWrapController controller = ExpandedWrapController();
  ExpandedWrapNotifier notifier = ExpandedWrapNotifier();

  void _randomMinLines() {
    setState(() {
      minLines = Random().nextInt(10);
    });
  }

  void _randomMaxLines() {
    setState(() {
      final bool hasMaxLines = Random().nextDouble() > 0.2 ? true : false;
      maxLines = hasMaxLines ? ((minLines - 1) + Random().nextInt(10)) : null;
    });
  }

  @override
  void dispose() {
    notifier.dispose();
    super.dispose();
  }

  void _randomChildren() {
    final int u_a = 'a'.codeUnitAt(0);
    final int u_z = 'z'.codeUnitAt(0);
    final int u_A = 'A'.codeUnitAt(0);
    final int u_Z = 'Z'.codeUnitAt(0);
    final List<String> all =
        List.generate(u_z - u_a, (i) => String.fromCharCode(u_a + i)) +
            List.generate(u_Z - u_A, (i) => String.fromCharCode(u_A + i));
    final int length = all.length;
    int count = 4 + Random().nextInt(50);
    final list = <String>[];
    while (count-- > 0) {
      int rLength = Random().nextInt(10);
      final List<String> strList = [];
      while (rLength-- > 0) {
        final int index = Random().nextInt(length);
        strList.add(all[index]);
      }
      list.add(strList.join());
    }
    setState(() {
      textList = list;
    });
  }

  Widget b(String str) {
    return Container(
      decoration: BoxDecoration(
        color: Colors.red.withValues(alpha: 0.01),
        border: Border.all(color: Colors.red, width: 0.5),
        borderRadius: BorderRadius.circular(12),
      ),
      padding: EdgeInsets.symmetric(horizontal: 12),
      height: 24,
      child: Align(
        heightFactor: 1.0,
        widthFactor: 1.0,
        child: Text(
          str,
          textAlign: TextAlign.start,
          maxLines: 2,
          //overflow: TextOverflow.ellipsis,
        ),
      ),
    );
  }

  Widget _button(
    String str,
    VoidCallback? onTap, {
    EdgeInsetsGeometry? margin,
    Color? color,
    Color? textColor,
    double? height,
    double? width,
  }) {
    final Widget child = Material(
      child: Ink(
        color: color ?? Colors.red.withValues(alpha: 0.1),
        width: width,
        height: height ?? 34,
        child: InkWell(
          onTap: onTap,
          child: Center(
            child: Text(
              str,
              textAlign: TextAlign.center,
              style: TextStyle(
                fontSize: 18,
                color: textColor,
              ),
              maxLines: 1,
            ),
          ),
        ),
      ),
    );

    return margin == null
        ? child
        : Padding(
            padding: margin,
            child: child,
          );
  }

  Widget buildReset(VoidCallback? onTap, {String? str}) {
    return _button(
      str ?? 'reset',
      onTap,
      margin: EdgeInsets.symmetric(horizontal: 48),
    );
  }

  Widget v(double space) {
    return SizedBox(height: space);
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('ExpandedWrap test'),
        ),
        body: Directionality(
          textDirection: TextDirection.rtl,
          child: SingleChildScrollView(
            child: Column(
              children: [
                v(20),
                Text('count: ${textList.length}'),
                v(12),
                // ExpandedWrap
                Container(
                  color: Colors.green.withValues(alpha: 0.1),
                  width: double.infinity,
                  child: ExpandedWrap(
                      spacing: 0,
                      runSpacing: 24,
                      minLines: minLines,
                      maxLines: maxLines,
                      verticalDirection: VerticalDirection.down,
                      crossAxisAlignment: WrapMoreCrossAlignment.center,
                      alignment: WrapMoreAlignment.start,
                      nearChild: GestureDetector(
                        onTap: () {
                          print("near");
                        },
                        child: AnimatedBuilder(
                            animation: notifier,
                            builder: (_, __) {
                              return _button(
                                notifier.isExpanded ? 'collapse' : 'expand',
                                notifier.toggle,
                                height: 24,
                                width: 100,
                                color: Colors.white,
                              );
                            }),
                      ),
                      nearAlignment: WrapMoreNearAlignment.stretch,
                      alwaysShowNearChild:
                          false, // When set to false, it means that [nearChild] will only be displayed when there is more unfinished data
                      nearSpacing: 20,
                      nearDirection: AxisDirection.right,
                      notifier: notifier,
                      separate: Container(
                        width: 1,
                        height: 60,
                        margin: EdgeInsets.symmetric(horizontal: 4),
                        color: Colors.red,
                      ),
                      dropBuilder: (BuildContext context,
                          ExpandedWrapController controller, Widget? child) {
                        return _button(
                          controller.isExpanded ? 'collapse' : 'expand',
                          controller.toggle,
                          width: 100,
                          height: 24,
                          textColor: Colors.white,
                          color: Colors.grey,
                        );
                      },
                      children: textList.indexed
                          .map((s) => b('${s.$1}#${s.$2}'))
                          .toList()
                      // ..add(
                      //   Container(
                      //     width: double.infinity,
                      //     height: 40,
                      //     color: Colors.red.withValues(alpha: 0.4),
                      //     child: Align(
                      //       alignment: AlignmentDirectional.centerEnd,
                      //       child: Text('last'),
                      //     ),
                      //   ),
                      // ),
                      ),
                ),
                v(24),
                buildReset(_randomChildren),
                v(20),
                Text('minLines: $minLines'),
                buildReset(_randomMinLines),
                v(20),
                Text('maxLines: $maxLines'),
                buildReset(_randomMaxLines),
                v(6),
                AnimatedBuilder(
                    animation: notifier,
                    builder: (_, __) {
                      return buildReset(
                        notifier.expandable ? notifier.toggle : null,
                        str: notifier.isExpanded ? 'collapse' : 'expand',
                      );
                    }),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
2
likes
150
points
161
downloads

Publisher

unverified uploader

Weekly Downloads

A expanded wrap.

Repository (GitHub)

Documentation

API reference

License

BSD-3-Clause (license)

Dependencies

flutter

More

Packages that depend on expanded_wrap