Flutter 개발 상자

이주의 위젯 - Wrap 본문

Flutter

이주의 위젯 - Wrap

망고상자 2022. 7. 17. 01:34
728x90

아이템 크기에 따라 한줄에 표시되는 개수가 달라진다.

위와 같은 해시태그를 만들기위해서 wrap 이라는 위젯을 사용한다.

 

속성

spacing : 아이템간의 간격, 음수값도 집어넣어짐

runSpacing : 한줄의 간격

direction : 가로, 세로 방향 결정, 기본값 가로 ex) Axis.vertical

clipBehavior : 튀어나온부분을 잘라내는 속성?... 정확히 어떻게 쓰이는지는 모르겠다

textDirection : 아이템이 생성되는 방향을 바꿔준다. 기본값 ltr ex) TextDirection.ltr

verticalDirection : 아이템이 생성되는 줄 방향을 바꿔준다. textDirection와 수직으로 반대되는 개념

alignment : 아이템 정렬 방식  ex) Wrapalignment.center

runAlignment : 아이템 줄 정렬 방식

crossAxisAlignment : 아이템의 교차축 길이가 제각각일때 교차축에 대한 정렬방식

https://terry1213.github.io/flutter/flutter-widget-of-the-week-wrap/

 

[Flutter/Widget of the Week] Wrap

Widget of the Week 유튜브 영상

terry1213.github.io

 

여기보면 이해가 쉬운듯

 

 

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key}) : super(key: key);

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<User> userList = [
    User(initials: "AB", name: "Aaron Burr"),
    User(initials: "AH", name: "Alexander Hamilton"),
    User(initials: "EH", name: "Eliza Hamilton"),
    User(initials: "JM", name: "James Madison"),
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("wrap"),
      ),
      body: SizedBox(
        width: double.infinity,
        child: Wrap(
          clipBehavior: Clip.antiAlias,
          direction: Axis.horizontal,
          spacing: 8.0,
          // gap between adjacent chips
          runSpacing: 4.0,
          // gap between lines
          alignment: WrapAlignment.center,
          children: createWrapList(),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: const Icon(
          Icons.add,
        ),
        onPressed: () {
          showAddDialog();
        },
      ),
    );
  }

  void showAddDialog() {
    TextEditingController controller = TextEditingController();
    showDialog(
      context: context,
      builder: (context) {
        return AlertDialog(
          title: const Text("아이템 추가"),
          content: TextField(
            autofocus: true,
            controller: controller,
          ),
          actions: [
            TextButton(
              onPressed: () {
                String initials = "";
                controller.text.split(" ").forEach((element) {
                  initials += element.substring(0, 1);
                });
                setState(() {
                  userList.add(
                      User(initials: initials, name: controller.text,)
                  );
                });
                Navigator.of(context).pop();
              },
              child: const Text(
                "확인"
              ),
            ),
          ],
        );
      },
    );
  }

  List<Widget> createWrapList() {
    List<Widget> widgetList = [];
    for (var element in userList) {
      Widget widget = Chip(
        avatar: CircleAvatar(backgroundColor: Colors.blue.shade900, child: Text(element.initials)),
        label: Text(element.name),
        onDeleted: () {
          setState(() {
            userList.removeWhere((item) => item.name == element.name);
          });
        },
      );
      widgetList.add(widget);
    }
    return widgetList;
  }
}

class User {
  String initials;
  String name;

  User({
    required this.initials,
    required this.name,
  });
}

x를 누르면 사라지고, 플로팅 버튼으로 아이디를 추가하는 UI를 만들어 보았다.

728x90