Экран не может обновляться в режиме реального времени, пока не прокрутится до нижней части

#flutter #dart

#трепетание #dart

Вопрос:

В настоящее время я изучаю Flutter и хочу создать динамические кнопки переключения, но я не знаю, почему он не может обновиться после нажатия кнопки переключения прокрутки вниз.
Это страница кода:

 import 'dart:convert';

import 'package:flutter/material.dart';


class TestArea extends StatefulWidget {
  @override
  _TestArea createState() => _TestArea();
}

class _TestArea extends State<TestArea> {
  List<List<bool>> boo=[[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false],[true,false,false]];
  var _myPets = List<Widget>();

  int _index = 0;

  void _add(String name) {
    int keyValue = _index;
    _myPets = List.from(_myPets)
      ..add(
        Column(
        children: <Widget>[
          ListTile(
            leading: Text(name),
          ),
          Container(
            alignment: Alignment.center,
            margin: EdgeInsets.all(10),
            padding: EdgeInsets.all(10),
            child: ToggleButtons(
                children: <Widget>[
                  Icon(Icons.ac_unit),
                  Icon(Icons.call),
                  Icon(Icons.cake),
              ],
              onPressed: (int index) {
              setState(() {
                  boo[keyValue][index] = !boo[keyValue][index];
                });
              },
              isSelected: boo[keyValue],
            ),
          )
        ],
      ));

    setState(() =>   _index);
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    for(int i=0;i<10;i  ){
      _add(i.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () => print(json.encode(boo)),
        child: Text('Save'),
      ),
      appBar: AppBar(
        title: Text('Add your pets'),
        actions: <Widget>[
        ],
      ),
      body: ListView(
        children: _myPets,
      ),
    );
  }
}
  

Еще одна вещь, я создал больше красивых переключателей, но это покажет ошибку.
Например:

    children: <Widget>[
      Container(width: (MediaQuery.of(context).size.width - 49)/3, child: new Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[new Icon(Icons.whatshot,size: 16.0,color: Colors.red,),new SizedBox(width: 4.0,), new Text("滿意",style: TextStyle(color: Colors.red),)],)),
      Container(width: (MediaQuery.of(context).size.width - 49)/3, child: new Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[new Icon(Icons.invert_colors,size: 16.0,color: Colors.yellow[800],),new SizedBox(width: 4.0,), new Text("要翻執",style: TextStyle(color: Colors.yellow[800]))],)),
      Container(width: (MediaQuery.of(context).size.width - 49)/3, child: new Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[new Icon(Icons.ac_unit,size: 16.0,color: Colors.blue,),new SizedBox(width: 4.0,), new Text("翻執滿意",style: TextStyle(color: Colors.blue))],)),
    ],
  

Спасибо!

Ответ №1:

Вы должны позволить кнопкам переключения управлять своим собственным состоянием.

 import 'dart:convert';

import 'package:flutter/material.dart';

void main() {
  runApp(MaterialApp(
    home: TestArea(),
  ));
}

class TB extends StatefulWidget {
  final List<bool> value;
  final int keyValue;
  final String name;
  final Function onPressed;

  TB(this.value, this.keyValue, {this.name, this.onPressed});

  _TB createState() => _TB();
}

class _TB extends State<TB> {
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        ListTile(
          leading: Text(widget.name ?? ""),
        ),
        Container(
          alignment: Alignment.center,
          margin: EdgeInsets.all(10),
          padding: EdgeInsets.all(10),
          child: ToggleButtons(
            children: <Widget>[
              Icon(Icons.ac_unit),
              Icon(Icons.call),
              Icon(Icons.cake),
            ],
            onPressed: (index) {
              widget.onPressed(widget.keyValue, index);
              setState(() {});
            },
            isSelected: widget.value,
          ),
        )
      ],
    );
  }
}

class TestArea extends StatefulWidget {
  @override
  _TestArea createState() => _TestArea();
}

class _TestArea extends State<TestArea> {
  List<List<bool>> boo = [
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false]
  ];
  var _myPets = List<Widget>();

  int _index = 0;

  void _add(String name) {
    _myPets.add(TB(boo[_index], _index, name: name, onPressed: _onPressed));

      _index;
  }

  void _onPressed(int key, int index) {
    boo[key][index] = !boo[key][index];
  }

  @override
  void initState() {
    super.initState();
    for (int i = 0; i < 10; i  ) {
      _add(i.toString());
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () => print(json.encode(boo)),
        child: Text('Save'),
      ),
      appBar: AppBar(
        title: Text('Add your pets'),
        actions: <Widget>[],
      ),
      body: ListView.builder(
        itemCount: _myPets.length,
        itemBuilder: (context, index) {
          return _myPets[index];
        },
      ),
    );
  }
}
  

Комментарии:

1. Спасибо, брат. Еще одна вещь, которую я хотел бы знать, как установить только 1 выбор, нажата?

2. Я исправляю это для изменения _onPressed функции.

Ответ №2:

Я изменил ваш код, что вы хотите сделать.

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: TestArea(),
    );
  }
}

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

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: TestArea(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {},
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class TestArea extends StatefulWidget {
  @override
  _TestArea createState() => _TestArea();
}

class _TestArea extends State<TestArea> {
  List<List<bool>> boo = [
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false],
    [true, false, false]
  ];

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      floatingActionButton: FloatingActionButton(
        onPressed: () => print(json.encode(boo)),
        child: Text('Save'),
      ),
      appBar: AppBar(
        title: Text('Add your pets'),
        actions: <Widget>[],
      ),
      body: ListView.builder(
        itemBuilder: (context, index) {
          return Column(
            children: <Widget>[
              ListTile(
                leading: Text('$index'),
              ),
              Container(
                alignment: Alignment.center,
                margin: EdgeInsets.all(10),
                padding: EdgeInsets.all(10),
                child: ToggleButtons(
                  children: <Widget>[
                    Icon(Icons.ac_unit),
                    Icon(Icons.call),
                    Icon(Icons.cake),
                  ],
                  onPressed: (int itemIndex) {
                    setState(() {
                      boo[index][itemIndex] = !boo[index][itemIndex];
                    });
                  },
                  isSelected: boo[index],
                ),
              )
            ],
          );
        },
      ),
    );
  }
}