Как сделать Tree Select Box с DropdownButton в флаттере - PullRequest
0 голосов
/ 04 марта 2020

Я хочу сделать поле выбора с DropDownButton во флаттере. но я не могу сделать идеальный алгоритм для этого. Я надеюсь получить большую помощь от экспертов Flutter. Спасибо.

Снимок экрана текущей реализации

Ответы [ 2 ]

0 голосов
/ 21 апреля 2020

Для всех, кто сталкивается с этой проблемой и не получает ответов на вопросы здесь ... Я написал простое приложение, которое делает именно это, выбирая элемент из дерева с помощью динамических c кнопок выпадающего списка. Вот весь код:

import 'package:flutter/material.dart';

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

class Node {
  final String name;
  final List<Node> children;

  Node({this.name, this.children});
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: MyHomePage(title: 'Animal Classification'),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> treeLevels = ['Phylum', 'Class', 'Species'];
  List<Node> selectedNodes = [
    Node(name: 'Animal Kingdom', children: <Node>[
      Node(name: 'Vertebrates', children: <Node>[
        Node(name: 'Fish'),
        Node(name: 'Amphibians'),
        Node(name: 'Reptiles'),
        Node(name: 'Birds'),
        Node(name: 'Mammals', children: <Node>[
          Node(name: 'Bats'),
          Node(name: 'Carnivores'),
          Node(name: 'Birds'),
        ]),
      ]),
      Node(name: 'Annelids'),
      Node(name: 'Molluscs'),
      Node(name: 'Nematodes'),
      Node(name: 'Arthropods', children: <Node>[
        Node(name: 'Crustaceans'),
        Node(name: 'Arachnids'),
        Node(name: 'Insects'),
        Node(name: 'Myriapods'),
      ]),
    ]),
  ];

  @override
  Widget build(BuildContext context) {
    List<Widget> items = [];
    for (var i = 0; i < selectedNodes.length; i++) {
      if (selectedNodes[i] != null &&
          (selectedNodes[i].children?.isNotEmpty ?? false)) {
        items.add(
            Text(treeLevels[i], style: Theme.of(context).textTheme.headline5));

        items.add(DropdownButtonFormField(
          value: selectedNodes.length > i + 1 ? selectedNodes[i + 1] : null,
          items: selectedNodes[i]
              .children
              .map((node) => DropdownMenuItem(
                    value: node,
                    child: Text(node.name),
                  ))
              .toList(),
          onChanged: (selected) => setState(() {
            selectedNodes.removeRange(i + 1, selectedNodes.length);
            selectedNodes.add(selected);
          }),
        ));

        items.add(SizedBox(height: 16.0)); // Padding
      }
    }

    return Scaffold(
        appBar: AppBar(
          title: Center(child: Text(widget.title)),
        ),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: ListView(
            children: items,
          ),
        ));
  }
}
0 голосов
/ 08 марта 2020

Я уже решил эту проблему сам. Вот мой код Но я ожидаю лучшего решения от экспертов Flutter.

  addTaskList(){
taskChildrenList.clear();
print(selectedTaskList.length);
selectedTaskList.forEach((task){
  taskChildrenList.add(Card(
    margin: EdgeInsets.symmetric(vertical: 5),
    child: Padding(
      padding: const EdgeInsets.symmetric(horizontal: 8),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: <Widget>[
          Text("${AppLanguage.selectTaskLabel()} ${task[0].label}",style: TextStyle(fontSize: 15,fontWeight: FontWeight.bold),),
          Flexible(
            child: FittedBox(
              child: DropdownButton<JustificationTask>(
                value: selectedTasks.length==task[0].label-1?null:selectedTasks[task[0].label-1],
                icon: Icon(Icons.chevron_right),
                iconSize: 25,
                elevation: 16,
                style: TextStyle(color: Colors.black),
                underline: Container(height: 1, color: Colors.transparent,),
                onChanged: (JustificationTask value) {
                  setState(() {
                    selectedTaskList.removeRange(value.label, selectedTaskList.length);
                    selectedTasks.removeRange(value.label-1, selectedTasks.length);
                    selectedTasks.add(value);
                    if(value.children.isNotEmpty){
                      selectedTaskList.add(value.children);
                      selectedTask=null;
                    }else{
                      selectedTask=value;
                      equipment=null;
                    }
                  });
                },
                items: task.map<DropdownMenuItem<JustificationTask>>((JustificationTask value) {
                  return DropdownMenuItem<JustificationTask>(
                    value: value,
                    child: SizedBox(width:MediaQuery.of(context).size.width*0.4,child: Text("${taskName(value)}",style: TextStyle(fontSize: 20),)),
                  );
                }).toList(),
                hint: SizedBox(width:MediaQuery.of(context).size.width*0.4,child: Text(AppLanguage.task(),style: TextStyle(fontSize: 20))),
                isExpanded: false,
              ),
            ),
          ),
        ],
      ),
    ),
  ),);
});

}

...