web-dev-qa-db-ja.com

listViewでビルド中に呼び出されたsetstate()またはmarkneedsbuild()

だから私は私のListViewロジックをリファクタリングしようとしています。基本的に私のListViewはUIロジックと面倒になっているので、私は決定されたのですが、UIロジックの特定の部分を別のクラスに移動しないのです。

これは私のコードlistpage.dartです

import 'package:flutter/material.Dart';
import 'package:flutter/services.Dart';
import 'package:flutter/widgets.Dart';
import 'package:sample_flutter_works/ListTextArea.Dart';
import 'package:sample_flutter_works/Model.Dart';
import 'Dart:convert';
import 'package:sample_flutter_works/RefreshTableContainer.Dart';

class ListPage extends StatefulWidget {
  @override
  MyListPage createState() => MyListPage();
}

class MyListPage extends State<ListPage> {
  MessageList messageList;
  List<int> viewTimeInfo;
  ScrollController _controller;

  _scrollListener() {

  }

  @override
  void initState() {
     super.initState();
    SystemChrome.setPreferredOrientations(
        [DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]);

    _controller = ScrollController();
    _controller.addListener(_scrollListener);

    loadMessages(
        completionBlock: (dataSet) => {
              setState(() {
                messageList = dataSet;
              })
            });
  }

  void loadMessages({completionBlock}) async {
    var jsonString = await rootBundle.loadString('assets/Chat.json');
    final jsonResponse = json.decode(jsonString);
    if (jsonResponse != null) {
      completionBlock(MessageList.fromJSON(jsonResponse));
    } else {
      completionBlock(null);
    }
  }

  Widget listLayout() {
    return ListView.separated(
        padding: const EdgeInsets.all(8.0),
        itemCount: (messageList != null && messageList.msgList != null)
            ? messageList.msgList.length
            : 0,
        separatorBuilder: (context, index) => Divider(
              color: Colors.black,
              height: 4.0,
            ),
        itemBuilder: (BuildContext context, int index) {
          var msgValToSend =
              (messageList != null && messageList.msgList != null)
                  ? messageList.msgList[index]
                  : null;

          return Stack(
            children: <Widget>[
              IntrinsicHeight(
                child: Row(
                  children: <Widget>[
                    getTheImageLayout(msgValToSend),
                    new ListTextArea(
                        msg: msgValToSend,
                        didTapOnTextArea: tappedOnTextArea,
                        visibilityCheck: checkForVisibility)
                  ],
                ),
              )
            ],
          );
        });
  }


  tappedOnTextArea(Message msg) {
    var viewedInfo = this.viewTimeInfo;
    if (viewedInfo != null) {
      var indexOfTappedElement = viewedInfo.indexOf(msg.messageID);

      if (indexOfTappedElement != null && indexOfTappedElement != -1) {
        viewedInfo.removeAt(indexOfTappedElement);
      } else {
        viewedInfo.add(msg.messageID);
      }
    } else {
      viewedInfo = [msg.messageID];
    }

    setState(() {
              viewTimeInfo = viewedInfo;
            });
  }

  checkForVisibility(bool _visible, Message msg) {
    if (msg != null && this.viewTimeInfo != null) {
      var checkForIndex = this.viewTimeInfo.indexOf(msg.messageID);
      if (checkForIndex != null && checkForIndex != -1) {
        _visible = true;
      }
    }
  }


  Widget getTheImageLayout(Message msg) {
    return Expanded(
        flex: 2,
        child: Align(
            alignment: Alignment.topLeft,
            child: Padding(
              padding: EdgeInsets.fromLTRB(5, 2.5, 0, 0),
              child: Container(
                  color: Colors.red,
                  height: 50,
                  child: Row(
                    children: <Widget>[
                      userImageView(msg),
                    ],
                  )),
            )));
  }

  Widget userImageView(Message msg) {
    return Expanded(
        flex: 8,
        child: Align(
            alignment: Alignment.centerLeft,
            child: Container(
                width: 40.0,
                height: 40.0,
                decoration:
                    BoxDecoration(shape: BoxShape.circle, color: Colors.green),
                child: ClipOval(
                  child: Image.network(
                    (msg.msgUser.userPicUrl != null)
                        ? msg.msgUser.userPicUrl
                        : 'https://picsum.photos/250?image=9',
                    fit: BoxFit.fill,
                  ),
                ))));
  }

  Future<void> refreshTheChatTable() async {
    print(" This is where the logic of pulll 2 refresh must be written ");

    loadMessages(
        completionBlock: (dataSet) => {
              setState(() {
                messageList = dataSet;
              })
            });
  }

  @override
  Widget build(BuildContext context) {
    return new RefreshTableContainer(
      listLayout: listLayout(),
      pull2RefreshAction: refreshTheChatTable,
    );
  }
}
 _

ListTextarea.dart.

import 'package:flutter/material.Dart';
import 'package:flutter/widgets.Dart';
import 'package:sample_flutter_works/Model.Dart';

class ListTextArea extends StatelessWidget {

  Message msg;
  Function didTapOnTextArea;
  Function visibilityCheck;

  ListTextArea({
    this.msg,
    this.didTapOnTextArea,
    this.visibilityCheck
  });

  @override
  Widget build(BuildContext context) {
    return Expanded(
        flex: 8,
        child: GestureDetector(
          onTap: didTapOnTextArea(msg),
          child: Padding(
            padding: EdgeInsets.fromLTRB(0, 2.5, 10, 0),
            child: Column(
              children: getChildWidgetArray(msg) ,
            ),
          ),
        ));
  }

  List<Widget> getChildWidgetArray(Message msg) {

    var elementalArray = [
      Align(
        alignment: Alignment.topLeft,
        child: Text(
          (msg != null) ? msg.msgContent.content : "Data Loading",
          style: TextStyle(
            background: Paint()..color = Colors.orange,
          ),
        ),
      ),
      Spacer(), // Defaults to a flex of one.
      Align(
        alignment: Alignment.bottomRight,
        child: Text(
          'Date of sending',
          textDirection: TextDirection.rtl,
          style: TextStyle(
            background: Paint()..color = Colors.blue,
          ),
        ),
      )
    ];

    var _visible = false;
    visibilityCheck(_visible,msg);

    var timeInfo = AnimatedOpacity (
          opacity: _visible ? 1.0 : 0.0,
          duration: Duration(milliseconds: 500),
          child: Align(
            child: _visible ? (Align(alignment: Alignment.topLeft,child:Column(children: <Widget>[Text("Last Read :" + (msg.msgTimeInfo.lastReadInfo)),
                                      Text("Delievered :" + (msg.msgTimeInfo.deliveredInfo))],))): null));
        elementalArray.add(timeInfo);

    return elementalArray;
  }
}
 _

エラーは次のとおりです. enter image description here

私がListViewで動的に計算されたセルで、私がしようとしているのはListViewで動的に計算されたセルでした。各セルは、より多くのデータに表示されるタップアクションに応答しました。私はここで何が悪いのか理解できません。

私はSetStateをinitにin initで呼び出しましたが、コールバック関数内です。 StatelessWidget ListTextAreaはまったく状態を処理しませんが、TapActionをStateFulWidget ListPage.dartに返します。

だからなぜ私はこのエラーを得ています。どんな洞察も役に立ちます。

InkWell(
    onTap: () => Navigator.Push(context,
        MaterialPageRoute(builder: (context) =>
            ChangeNotifierProvider<AlertHistoryProvider>(
                create: (_) => AlertHistoryProvider(),
                child: AlertsHistory()
            ),
        )
    ),
    child : Text('Alerts History')),
 _

私は上記のようにしましたが、私はまだsetStateエラーを得ます。皮肉なことはこの流れの中でのみ問題を引き起こし、他のすべての流れでうまく機能します...混乱しています

0
sujith sa