robert-luoqing / flutter_list_view

MIT License
45 stars 17 forks source link

Activate the keyboard, then manually scroll down the list to the bottom, and then lose the keyboard, as if it would appear #10

Closed ghost closed 6 months ago

ghost commented 2 years ago

════════ Exception caught by rendering library ═════════════════════════════════ RenderIndexedSemantics does not meet its constraints. The relevant error-causing widget was FlutterSliverList ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ Invalid argument(s): 0.0 The relevant error-causing widget was SmartRefresher ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ BoxConstraints has non-normalized width constraints. The relevant error-causing widget was Container ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ BoxConstraints has non-normalized width constraints. The relevant error-causing widget was Container ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ BoxConstraints has both width and height constraints non-normalized. The relevant error-causing widget was Column ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ BoxConstraints has both width and height constraints non-normalized. The relevant error-causing widget was GestureDetector ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ BoxConstraints has both width and height constraints non-normalized. The relevant error-causing widget was GestureDetector ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════ 'package:flutter/src/semantics/semantics.dart': Failed assertion: line 3995 pos 12: 'value != null && value >= 0.0': is not true. ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by scheduler library ═════════════════════════════════ 'package:flutter/src/animation/animation_controller.dart': Failed assertion: line 822 pos 12: 'elapsedInSeconds >= 0.0': is not true. ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════ flutter: (at_bottom_tab.dart line:159): bottomTab dispose 840232081

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#205b3 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/rendering/object.dart': Failed assertion: line 1601 pos 12: '_debugCanPerformMutations': is not true. ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#bb69f parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#6ff6b parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#ec916 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#6bdd9 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#027b9 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#34c80 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#dcd0f parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#5401c parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#0947a parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#6d344 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#9bbb1 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#2c4d7 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by widgets library ═══════════════════════════════════ 'package:flutter/src/material/button_theme.dart': Failed assertion: line 219 pos 15: 'minWidth != null && minWidth >= 0.0': is not true. The relevant error-causing widget was MaterialApp ════════════════════════════════════════════════════════════════════════════════

════════ Exception caught by rendering library ═════════════════════════════════ RenderBox.size accessed beyond the scope of resize, layout, or permitted parent access. RenderBox can always access its own size, otherwise, the only object that is allowed to read RenderBox.size is its parent, if they have said they will. It you hit this assert trying to access a child's size, pass "parentUsesSize: true" to that child's layout(). 'package:flutter/src/rendering/box.dart': Failed assertion: line 1935 pos 13: 'debugDoingThisResize || debugDoingThisLayout || _computingThisDryLayout || (RenderObject.debugActiveLayout == parent && _size._canBeUsedByParent)'

The relevant error-causing widget was MaterialApp The following RenderObject was being processed when the exception was fired: RenderCustomPaint#5e339 RenderObject: RenderCustomPaint#5e339 parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) child: RenderErrorBox#3ff2b parentData: (can use size) constraints: BoxConstraints(w=428.0, h=926.0) size: Size(428.0, 926.0) ════════════════════════════════════════════════════════════════════════════════

robert-bitguild commented 2 years ago

@fujiekai Thanks for your feedback. Did you put textfield in the list item then focus it and scroll out of the list view?

robert-luoqing commented 2 years ago

Hi @fujiekai, I can't get your issue. Would you please paste your code fragment to me to identifer the issue? Thanks.

ghost commented 2 years ago

import 'dart:async'; import 'dart:io';

import 'package:anttone_flutter/apis/contacts/at_friends_sql.dart'; import 'package:anttone_flutter/at_main_config.dart'; import 'package:anttone_flutter/pages/find/widget/at_bottom_sheet.dart'; import 'package:anttone_flutter/pages/find/widget/at_photo_browser.dart'; import 'package:anttone_flutter/pages/find/widget/at_toast.dart'; import 'package:anttone_flutter/pages/message/model/at_chat_data.dart'; import 'package:anttone_flutter/pages/message/model/handle/at_message_detail_handler.dart'; import 'package:anttone_flutter/pages/message/view/room/at_room_bottom_input.dart'; import 'package:anttone_flutter/pages/message/view/room/at_room_chat_body.dart'; import 'package:anttone_flutter/pages/user/model/at_user_model.dart'; import 'package:anttone_flutter/util/at_color_tool.dart'; import 'package:anttone_flutter/util/at_image_tool.dart'; import 'package:anttone_flutter/util/at_object_util.dart'; import 'package:anttone_flutter/util/at_screen_tool.dart'; import 'package:anttone_flutter/util/kvo/public/at_noti_model.dart'; import 'package:anttone_flutter/util/langu/at_language_tool.dart'; import 'package:anttone_flutter/util/at_tools.dart'; import 'package:anttone_flutter/util/network/socket/at_web_socket.dart'; import 'package:anttone_flutter/util/sql/entities/at_friends_entity.dart'; import 'package:anttone_flutter/util/sql/entities/at_message_entity.dart'; import 'package:anttone_flutter/util/video/at_video_tool.dart'; import 'package:anttone_flutter/widget/base/at_app_bar.dart'; import 'package:anttone_flutter/widget/video/at_video_player_page.dart'; import 'package:flutter/material.dart'; import 'package:anttone_flutter/util/kvo/at_event_bus_tool.dart'; import 'package:flutter/services.dart'; import 'package:anttone_flutter/plugs/flutter_list_view_1.1.13/flutter_list_view.dart'; import 'package:just_audio/just_audio.dart'; import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';

class ATMessageRoomPage extends StatefulWidget { final ATMessageSessionEntity parma;

ATMessageRoomPage({Key? key, required this.parma}) : super(key: key);

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

class _ATMessageRoomPageState extends State with WidgetsBindingObserver { bool showSayFlag = false; late String sayTipText; late ATRoomBottomInputUI inputUI; List? chatData; String? curPlayAudioMsgID; int curPlayAudioIndex = -1; final chatBodyScrollController = FlutterListViewController(); final focusNode = FocusNode(); final _audioPlayer = AudioPlayer(); bool canRefresh = false; AnimationController? recordAudioAnimation; late final ATMsgDetailHandler _handler = ATMsgDetailHandler(widget.parma); StreamSubscription? _refreshUINoti; ATMessageMember? _selfInfo; // 当前键盘是否是激活状态 bool isKeyboardActived = false;

@override void initState() { super.initState();

sayTipText = atLangu.lMessage_Room_Long_Click_Up_Say_Up_Tip;
initNoti();
_handler.initData();

for (var item in widget.parma.memberList!) {
  if (item.imUserId == ATUserModel.getIMUserId()) {
    _selfInfo = item;
  }
}

_audioPlayer.playerStateStream.listen((event) {

  LogUtil.log('播放音频状态->$event');
  if (event.processingState == ProcessingState.completed) {
    LogUtil.log('播放音频结束');
    setState(() {
      chatData![curPlayAudioIndex].isAudioPlaying = false;
      curPlayAudioMsgID = null;
      curPlayAudioIndex = -1;
    });
  }

});

focusNode.addListener(() {
  if (focusNode.hasFocus) {
  LogUtil.log('聚焦时候的操作'); 
  Future.delayed(const Duration(milliseconds: 400)).then((value) {
        if (chatBodyScrollController.hasClients) {
          chatBodyScrollController.jumpTo(chatBodyScrollController.position.maxScrollExtent);
        }
        // chatBodyScrollController.jumpTo(index: chatData?.length?? 0);
      });
  return;
}

LogUtil.log('失去焦点时候的操作');
isKeyboardActived = false;
});

WidgetsBinding.instance?.addObserver(this);

}

@override void didChangeMetrics() { super.didChangeMetrics();

WidgetsBinding.instance?.addPostFrameCallback((_) {
  // 当前是安卓系统并且在焦点聚焦的情况下
  if (Platform.isAndroid && focusNode.hasFocus) {
    if (isKeyboardActived) {
      isKeyboardActived = false;
      LogUtil.log('使输入框失去焦点');
      focusNode.unfocus();
      return;
    }

    LogUtil.log('输入框得到焦点');
    isKeyboardActived = true;
  }
});

}

void initNoti() { _refreshUINoti = ATNoti.onNoti((event) { if (event.refreshType == 'msg') { if (mounted) { setState(() { chatData = _handler.msgDataList;

      });
    }
    final flag = event.parames as bool;
    if (flag) {
      Future.delayed(const Duration(milliseconds: 50)).then((value) {
        if (chatBodyScrollController.hasClients) {
          chatBodyScrollController.jumpTo(chatBodyScrollController.position.maxScrollExtent);
        }
        // chatBodyScrollController.jumpTo(index: chatData?.length?? 0);
      });
    }
  } else if (event.refreshType == 'all') {
    if (mounted) {
      setState(() {});
    }
  }
});

}

@override void dispose() {

_handler.stopAll();

_refreshUINoti?.cancel();
_refreshUINoti = null;

// chatBodyScrollController.dispose();
_audioPlayer.dispose();
focusNode.dispose();
WidgetsBinding.instance?.removeObserver(this);

super.dispose();

}

@override Widget build(BuildContext context) { inputUI = ATRoomBottomInputUI( isGroupIM: widget.parma.sessionType == '2', memberList: widget.parma.memberList, color: const Color.fromARGB(255, 249, 249, 249), focusNode: focusNode, onVideoCall: (){ videoCall(widget.parma.sessionType!); }, onVoiceCall: (){ voiceCall(widget.parma.sessionType!); }, sendText: (str, {mentionedTargets, mentionedType}) { sendText(str, mentionedType!, mentionedTargets); }, sendImage: (imgs) { sendImage(imgs); }, sendVideo: (videos){ sendVideo(videos); }, sendVoice: (path, length) { sendVoice(path, length); }, startSayCallback: () { setState(() { showSayFlag = true; sayTipText = context.atLangu.lMessage_Room_Long_Click_Up_Say_Up_Tip; }); }, endSayCallback: () { setState(() { showSayFlag = false; }); }, sayForMoveFingerCallback: (isDel) { setState(() { if (isDel) { sayTipText = context.atLangu.lMessage_Room_Long_Click_Up_Say_Cancel; } else { sayTipText = context.atLangu.lMessage_Room_Long_Click_Up_Say_Up_Tip; } }); }, );

String appbarTitle = ATObjectUtil.isnEmptyStr(widget.parma.remarksName)? widget.parma.remarksName! : widget.parma.name!;
if (widget.parma.sessionType == '1') {
  for (var item in widget.parma.memberList!) {
    if (item.imUserId != ATUserModel.getIMUserId()) {
      appbarTitle = ATObjectUtil.isnEmptyStr(item.thisName)? item.thisName! : item.name!;
      break;
    }
  }
}

bool _showBG = false;
if (ATObjectUtil.isnEmptyStr(widget.parma.background)) {
  if (widget.parma.background!.contains('http')) {
    _showBG = true;
  } else {
    _showBG = ATTools.isExistsOfFile(widget.parma.background!);
  }
}

return Scaffold(
  appBar: ATAppBar(
    titles: Text(
      appbarTitle,
      style: TextStyle(color: Colors.black, fontSize: 48.atFontSize),
    ),
    actions: [
      IconButton(onPressed: (){
        LogUtil.log('点击右边的功能键');
        if (widget.parma.sessionType == '1') {
          Navigator.pushNamed(context, '/message/msg/room/detail/private', arguments: _handler);
        } else {
          Navigator.pushNamed(context, '/message/msg/room/detail/group', arguments: _handler);
        }

      }, icon: Icon(Icons.more_horiz_rounded, size: 80.atRadius, color: const Color.fromARGB(255, 64, 64, 64),))
    ],
  ),
  body: Material(
    color: const Color.fromARGB(255, 249, 249, 249),
    child: SafeArea(
      child: Stack(
        children: [
          _showBG
              ? (widget.parma.background!.contains('http')
                ? Image.network(widget.parma.background!, fit: BoxFit.fill, width: double.infinity, height: double.infinity)
                : Image.file(File(widget.parma.background!), fit: BoxFit.fill, width: double.infinity, height: double.infinity))
              : Container(),
          Column(
        children: [
          Expanded(
              child: Stack(children: [
            GestureDetector(
              behavior: HitTestBehavior.opaque,
              onTap: () {
                clickedBlankView();
              },
              child: Container(
                height: double.infinity,
                width: double.infinity,
                padding:
                    EdgeInsets.only(left: 24.atRadius, right: 24.atRadius),
                color: _showBG? null : kATNavigationBackgroud.atHexColor,
                child: ATRoomChatBodyView(
                  isGroup: widget.parma.sessionType == '2',
                  onTapPopup: (type, idx) {

                    clickedPopuEvent(type, idx);
                  },
                  clickVoiceCall: (idx){
                    LogUtil.log('点击了语音拨打');
                  },
                  clickVideoCall: (idx){
                    LogUtil.log('点击了视频拨打');
                  },
                  getCurAudioPlay: getAudioPlay,
                  scrollController: chatBodyScrollController,
                  chatDataList: chatData,
                  clickReUpload:  (idx) {

                    reUploadEvent(idx);
                  },
                  clickHeadImage: (idx) async {
                    LogUtil.log('点击了 ${idx} 位置的头像');
                    ATChatData _chat = chatData![idx];

                    bool _isStranger = _chat.uid != ATUserModel.getIMUserId();
                    ATFriendsItemEntity? _findModel;
                    if (_isStranger) {
                      final _findModelList = await ATFriendsSQL.sqlSelect(friendImUserId: _chat.uid);

                      _isStranger = _findModelList.isEmpty;
                      if (!_isStranger) {
                        _findModel = _findModelList.first;
                      }
                    }

                    Navigator.pushNamed(context,
                      '/friends/detail',
                      arguments: {
                        'model': _findModel ?? ATFriendsItemIndexModel.fromJson({'name': _chat.uName,'remarksName': _chat.uRemarksName,'avatar': _chat.uheadImg,'friendImUserId': _chat.uid, 'area':_chat.uArea}),
                        'isStranger': _isStranger,
                        'needChangeRoute':true
                      },
                    );

                  },
                  clickImage: (idx) {
                    LogUtil.log('点击了图片------$idx');
                    ATChatData curImageChatData = chatData![idx];
                    String imgMsgId = curImageChatData.msgId!;
                    int imgIdx = 0;
                    var tempImages = <String>[];
                    int tempIdx = 0;
                    for (var item in chatData!) {
                      if (item.type == 'img') {
                        tempImages.add(item.linkURL!);
                        if (item.msgId == imgMsgId) {
                          imgIdx = tempIdx;
                        }
                        tempIdx++;
                      }
                    }

                    Navigator.of(context).push(FadeRoute(
                      page: ATPhotoBrowser(
                        imgDataArr: tempImages,
                        index: imgIdx,
                        onLongPress: (idx) {
                          ATBottomSheet.showText(context,
                              dataArr: [context.atLangu.lSheet_Save_Photo],
                              clickCallback: (selectIndex, selectText) async {
                                    if (selectIndex == 1) {
                                      await ATImageTool.saveImageToPhotoLibary(tempImages[idx], context);
                                    }
                                  });
                        },
                      ),
                    ));
                  },
                  clickMp4: (idx) {
                    canRefresh = true;
                    ATChatData curMp4ChatData = chatData![idx];
                    LogUtil.log('点击了视频播放');
                    Navigator.of(context)
                        .push(MaterialPageRoute(builder: (ctx) {
                      return ATVedioPlayer(
                          linkURL: curMp4ChatData.linkURL!,
                          defaultImage: curMp4ChatData.videoHeadImageURL!,);
                    }));
                  },
                  clickPlayAudio: (idx) {
                    LogUtil.log('点击了音频--->$idx');
                    ATChatData curAudioChatData = chatData![idx];
                    playVoiceAction(chatData![idx].linkURL!);
                    setState(() {
                      if (curPlayAudioMsgID == null) {
                        chatData![idx].isAudioPlaying =
                            !(chatData![idx].isAudioPlaying);
                        curPlayAudioMsgID = curAudioChatData.msgId;
                        curPlayAudioIndex = idx;
                      } else if (curPlayAudioMsgID !=
                          curAudioChatData.msgId) {
                        chatData![curPlayAudioIndex].isAudioPlaying =
                            !(chatData![curPlayAudioIndex].isAudioPlaying);
                        chatData![idx].isAudioPlaying =
                            !(chatData![idx].isAudioPlaying);
                        curPlayAudioMsgID = curAudioChatData.msgId;
                        curPlayAudioIndex = idx;
                      } else if (curPlayAudioMsgID ==
                          curAudioChatData.msgId) {
                        chatData![curPlayAudioIndex].isAudioPlaying =
                            !(chatData![curPlayAudioIndex].isAudioPlaying);
                        curPlayAudioMsgID = null;
                        curPlayAudioIndex = -1;
                      }
                    });
                  },
                ),
              ),
            ),
            Visibility(
              visible: showSayFlag,
              child: Container(
                alignment: Alignment.center,
                height: double.infinity,
                width: double.infinity,
                color: Colors.transparent,
                child: Container(
                  padding: EdgeInsets.all(30.atRadius),
                  decoration: const BoxDecoration(
                      borderRadius: BorderRadius.all(Radius.circular(5)),
                      color: Color.fromARGB(100, 0, 0, 0)),
                  height: ATTools.getScreenSize(context).width / 4,
                  width: ATTools.getScreenSize(context).width / 2,
                  child: Column(
                    children: [
                      Expanded(
                        child: Container(),
                      ),
                      Text(
                        sayTipText,
                        style: TextStyle(
                            color: Colors.white, fontSize: 38.atFontSize),
                      )
                    ],
                  ),
                ),
              ),
            )
          ])),
          inputUI
        ],
      ),
        ],
      )
    ),
  ),
);

}

String? getAudioPlay() { if (curPlayAudioMsgID != null) { return curPlayAudioMsgID; }

return null;

}

//点击空白窗口 void clickedBlankView() { focusNode.unfocus(); inputUI.resetUIs(); }

//播放音频 void playVoiceAction(String path) async { if (_audioPlayer.playing) { _audioPlayer.stop(); }

if (path.contains('http:') || path.contains('https:')) {
  _audioPlayer.setUrl(path);
} else {
  _audioPlayer.setFilePath(path);
}

_audioPlayer.play();

}

// 发送视频 void sendVideo(List videos) {

LogUtil.log('发送视频');
for (var i = 0; i < videos.length; i++) {

  final item = videos[i];

  final sendMsg = ATMessageEntity();
  sendMsg.id = ATWebSocket.getUuid();
  sendMsg.createTime = '${int.parse(ATWebSocket.shared().getCreateTime()) + i}';
  sendMsg.sessionId = widget.parma.sessionId;
  sendMsg.content = '';
  sendMsg.fromUserId = ATUserModel.getIMUserId();
  sendMsg.fromChannelType = Platform.isIOS ? 'ios' : 'android';
  sendMsg.mentionedType = '1';
  sendMsg.msgType = '4';
  sendMsg.extras = ATMessageExtras(
    localPath: item.videoPath,
    duration: item.length.toString(),
    imgPath: item.firstImagePath,
    imgHeight: item.height.toInt().toString(),
    imgWidth: item.width.toInt().toString()
  );
  sendMsg.mentionedTargets = null;
  sendMsg.sendStatus = '2';
  sendMsg.member = _selfInfo;

  _handler.send('4',msg: sendMsg);

}

}

// 发送音频 void sendVoice(String filePath, String length) { LogUtil.log('发送音频'); if (int.parse(length) <= 0) { ATToast.showError(context, msg: context.atLangu.lTool_Msg_Recorder_Short); return; }

final sendMsg = ATMessageEntity();
sendMsg.id = ATWebSocket.getUuid();
sendMsg.createTime = ATWebSocket.shared().getCreateTime();
sendMsg.sessionId = widget.parma.sessionId;
sendMsg.content = '';
sendMsg.fromUserId = ATUserModel.getIMUserId();
sendMsg.fromChannelType = Platform.isIOS ? 'ios' : 'android';
sendMsg.mentionedType = '1';
sendMsg.msgType = '3';
sendMsg.extras = ATMessageExtras(
  localPath: filePath,
  duration: length
);
sendMsg.mentionedTargets = null;
sendMsg.sendStatus = '2';
sendMsg.member = _selfInfo;
_handler.send('3',msg: sendMsg);

}

// 发送文字 void sendText(String text, String mentionedType, List? mentionedTargets) { if (text.isNotEmpty) {

  LogUtil.log('发送文字');
  final sendMsg = ATMessageEntity();
  sendMsg.id = ATWebSocket.getUuid();
  sendMsg.createTime = ATWebSocket.shared().getCreateTime();
  sendMsg.sessionId = widget.parma.sessionId;
  sendMsg.content = text;
  sendMsg.fromUserId = ATUserModel.getIMUserId();
  sendMsg.fromChannelType = Platform.isIOS ? 'ios' : 'android';
  sendMsg.mentionedType = mentionedType;
  sendMsg.msgType = '1';
  sendMsg.extras = null;
  sendMsg.mentionedTargets = mentionedTargets;
  sendMsg.sendStatus = '1';
  sendMsg.member = _selfInfo;

  _handler.send('1',msg: sendMsg);
}

}

/// 发送图片 void sendImage(List imgPaths){ if (imgPaths.isNotEmpty) { for (var i = 0; i < imgPaths.length; i++) { LogUtil.log('发送图片');

  final sendMsg = ATMessageEntity();
  sendMsg.id = ATWebSocket.getUuid();
  sendMsg.createTime = '${int.parse(ATWebSocket.shared().getCreateTime()) + i}';
  sendMsg.sessionId = widget.parma.sessionId;
  sendMsg.content = '';
  sendMsg.fromUserId = ATUserModel.getIMUserId();
  sendMsg.fromChannelType = Platform.isIOS ? 'ios' : 'android';
  sendMsg.mentionedType = '1';
  sendMsg.msgType = '2';
  sendMsg.extras = ATMessageExtras(
    localPath: imgPaths[i]
  );
  sendMsg.mentionedTargets = null;
  sendMsg.sendStatus = '2';
  sendMsg.member = _selfInfo;

  _handler.send('2',msg: sendMsg);
  }
}

}

/// 拨打语音电话 void voiceCall(String sessionType) { if (sessionType == '1') {

  String imuserid = '';
  for (var item in widget.parma.memberList!) {
    if (item.imUserId != ATUserModel.getIMUserId()) {
      imuserid = item.imUserId!;
    }
  }
  _handler.send('5', context: context, imUserIds: [imuserid]);

} else {

}

}

/// 拨打视频电话 void videoCall(String sessionType) {

if (sessionType == '1') {

  String imuserid = '';
  for (var item in widget.parma.memberList!) {
    if (item.imUserId != ATUserModel.getIMUserId()) {
      imuserid = item.imUserId!;
    }
  }
  _handler.send('5', context: context, imUserIds: [imuserid]);

} else {
}

}

/// 重新上传 void reUploadEvent(int idx) { LogUtil.log('点击了reUpload按钮'); ATChatData chat = chatData![idx]; _handler.reUploadMsg(chat.msgId!); }

void clickedPopuEvent(int type, int idx) async { //0:拷贝,1:转发,2:收藏,3:撤回,4:删除 LogUtil.log('点击了功能按钮');

ATChatData chat = chatData![idx];

switch (type) {
  case 0:
    Clipboard.setData(ClipboardData(text: chat.textContent));
    break;
  case 1 :

    break;

  case 2 :
    await ATImageTool.saveImageToPhotoLibary(chat.linkURL!, context);
    break;

  case 3 : {
    final result = _handler.recall(chat, idx);
    if (result == 2) {
      ATToast.showText(context, msg: context.atLangu.lMessage_Room_Chat_Recall_Network_Error);

    } else if (result == 3) {
      ATToast.showText(context, msg: context.atLangu.lMessage_Room_Chat_Recall_Timeout);
    }
  }
    break;

  case 4 :
    _handler.delMsg(chat, idx);
    break;

  default:
}

} }

ghost commented 2 years ago
截屏2022-05-19 12 11 30