flutter ExpandContentWidget展开列表

2021-09-15  本文已影响0人  银弹星空
外层列表
import 'package:date_format/date_format.dart';
import 'package:flutter/material.dart';
import 'package:flutter_huiben/dao/comment_dao.dart';
import 'package:flutter_huiben/models/base/base_model.dart';
import 'package:flutter_huiben/models/book_model.dart';
import 'package:flutter_huiben/models/request/get_aud_request.dart';
import 'package:flutter_huiben/models/response/get_audio_chapter_response.dart';
import 'package:flutter_huiben/widget/bookdetail/expand_content_widget.dart';
import 'package:flutter_screenutil/screen_util.dart';
import 'package:fluttertoast/fluttertoast.dart';

/// 书本评论列表
class BookContentPage extends StatefulWidget {
  final int bookID;

  const BookContentPage({Key key, this.bookID}) : super(key: key);

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

class _BookContentPageState extends State<BookContentPage>
    with WidgetsBindingObserver {
  List<AudComment> _audCommentList = [];
  TextEditingController _editingController = new TextEditingController();
  FocusNode _focusNode = FocusNode();
  String hintTextString = '来吧有感而发';
  bool isRespond = false;
  int respondID;

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _getBookContent();
    WidgetsBinding.instance.addObserver(this);
    _editingController.addListener(() {});
  }

  @override
  void didChangeMetrics() {
    // TODO: implement didChangeMetrics
    super.didChangeMetrics();
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      setState(() {
        if (MediaQuery.of(context).viewInsets.bottom == 0) {
          //关闭键盘
          hintTextString = '来吧有感而发';
          isRespond = false;
          _focusNode.unfocus();
        } else {
          //打开键盘
        }
      });
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedPadding(
      padding: MediaQuery.of(context).viewInsets,
      duration: const Duration(milliseconds: 160),
      child: DraggableScrollableSheet(
          initialChildSize: 0.4,
          maxChildSize: 1,
          expand: false,
          builder: (BuildContext context, ScrollController scrollController) {
            return Container(
              decoration: BoxDecoration(
                color: Colors.white,
                borderRadius: BorderRadius.only(
                  topRight: Radius.circular(7),
                  topLeft: Radius.circular(7),
                ),
              ),
              child: Column(
                children: <Widget>[
                  Container(
                    alignment: Alignment.center,
                    height: ScreenUtil().setHeight(84),
                    child: RichText(
                      text: TextSpan(
                        text: '评论',
                        style: TextStyle(
                            color: Color(0xff333333),
                            fontSize: ScreenUtil().setSp(28)),
                        children: [
                          TextSpan(
                            text: '(${_audCommentList.length})',
                            style: TextStyle(
                                color: Color(0xff999999),
                                fontSize: ScreenUtil().setSp(26),
                                fontWeight: FontWeight.bold),
                          ),
                        ],
                      ),
                    ),
                    decoration: BoxDecoration(
                      border: Border(
                          bottom: BorderSide(
                              color: Color(0xffe8e8e8),
                              width: ScreenUtil().setHeight(1))),
                    ),
                  ),
                  Expanded(
                      flex: 1,
                      child: ListView.separated(
                        itemBuilder: (context, index) {
                          return ExpandContentWidget(
                            list: List.generate(3, (index) => '小王$index')
                                .toList(),
                            audComment: _audCommentList[index],
                            getFocus: (String text, int respondID) {
                              hintTextString = '回复@$text:';
                              this.respondID = respondID;
                              isRespond = true;
                              FocusScope.of(context).requestFocus(_focusNode);
                            },
                          );
                        },
                        separatorBuilder: (BuildContext context, int index) {
                          return Container(
                            margin: EdgeInsets.only(
                                left: ScreenUtil().setWidth(145)),
                            color: Color(0XFFE8E8E8),
                            height: ScreenUtil().setHeight(1),
                          );
                        },
                        itemCount: _audCommentList.length,
                        controller: scrollController,
                      )),
                  _inputContentWidget(),
                ],
              ),
            );
          }),
    );
  }

  _inputContentWidget() {
    return Container(
      alignment: Alignment.center,
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border(
            top: BorderSide(
                color: Color(0xffe8e8e8), width: ScreenUtil().setHeight(1))),
      ),
      padding: EdgeInsets.symmetric(
          horizontal: ScreenUtil().setWidth(30),
          vertical: ScreenUtil().setHeight(10)),
      constraints: BoxConstraints(minHeight: ScreenUtil().setHeight(85)),
      child: Row(
        children: [
          Expanded(
            flex: 1,
            child: TextField(
              controller: _editingController,
              focusNode: _focusNode,
              maxLines: 3,
              minLines: 1,
              cursorColor: Color(0xffFCB605),
              textInputAction: TextInputAction.send,
              onEditingComplete: () {
                print('onEditingComplete ');
              },
              onSubmitted: (text) {
                print('onSubmitted text$text');
                if (isRespond) {
                  _respondCommentFunction(text, respondID);
                } else {
                  _commentFunction(text);
                }
              },
              decoration: InputDecoration(
                filled: true,
                isDense: true,
                hintText: hintTextString,
                hintStyle: TextStyle(
                    color: Color(0xff999999), fontSize: ScreenUtil().setSp(26)),
                contentPadding:
                    EdgeInsets.symmetric(vertical: 8, horizontal: 10),
                border: OutlineInputBorder(
                  borderRadius:
                      BorderRadius.circular(ScreenUtil().setWidth(33)),
                ),
                enabledBorder: OutlineInputBorder(
                  borderRadius:
                      BorderRadius.circular(ScreenUtil().setWidth(33)),
                  borderSide: BorderSide(color: Color(0xfff7f7f7), width: 0),
                ),
                focusedBorder: OutlineInputBorder(
                  borderRadius:
                      BorderRadius.circular(ScreenUtil().setWidth(33)),
                  borderSide: BorderSide(color: Color(0xfff7f7f7), width: 0),
                ),
              ),
              keyboardType: TextInputType.multiline,
            ),
          ),
          Container(
            margin: EdgeInsets.only(left: ScreenUtil().setWidth(12)),
            child: InkWell(
              child: Icon(Icons.sentiment_satisfied_rounded),
              onTap: () {},
            ),
          ),
        ],
      ),
    );
  }

  // 获取某个书籍的评论
  void _getBookContent() async {
    AudCommentRequest audCommentRequest = AudCommentRequest();
    audCommentRequest.bookID = widget.bookID;
    audCommentRequest.type = 1;
    audCommentRequest.page = 1;
    audCommentRequest.size = 30;
    GetAudCommentModel getAudCommentModel =
        await CommentDao.getBookComment(audCommentRequest);
    if (getAudCommentModel.success) {
      _audCommentList = getAudCommentModel.data.items;
      setState(() {});
    }
  }

  /**
   * 评论
   */
  void _commentFunction(String text) async {
    BaseModel baseModel = await CommentDao.postAddComment(
        bookID: widget.bookID, isRemind: true, comment: text);
    if (baseModel.success) {
      Fluttertoast.showToast(msg: '评论成功');
      _getBookContent();
    } else {
      Fluttertoast.showToast(msg: '评论失败');
    }
  }

  /**
   * 回复一条评论
   */
  void _respondCommentFunction(String text, int respondID) async {
    BaseModel baseModel = await CommentDao.postRespondComment(
        comment: text, respondID: respondID);
    if (baseModel.success) {
      Fluttertoast.showToast(msg: '评论成功');
      _getBookContent();
    } else {
      Fluttertoast.showToast(msg: '评论失败');
    }
  }
}

内层列表
import 'package:date_format/date_format.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_huiben/dao/comment_dao.dart';
import 'package:flutter_huiben/models/base/base_model.dart';
import 'package:flutter_huiben/models/book_model.dart';
import 'package:flutter_huiben/models/request/get_aud_request.dart';
import 'package:flutter_huiben/pages/report/report_page.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:time_machine/time_machine.dart';

///展开关闭多人评论
class ExpandContentWidget extends StatefulWidget {
  final List<String> list;
  final Function(String userName, int respondID) getFocus;
  final AudComment audComment;

  const ExpandContentWidget(
      {Key key, this.list, this.getFocus, this.audComment})
      : super(key: key);

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

class _ExpandContentWidgetState extends State<ExpandContentWidget> {
  bool expand = false;
  List<AudComment> _audCommentList = [];
  final TextStyle style = TextStyle(fontSize: ScreenUtil().setSp(30));

  @override
  Widget build(BuildContext context) {
    return Container(
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: <Widget>[
          _contentItem(index: 0, audComment: widget.audComment),
          !expand
              ? Container()
              : Container(
                  constraints:
                      BoxConstraints(minHeight: ScreenUtil().setHeight(85)),
                  child: Column(
                    children: _audCommentList
                        .map<Widget>((e) => Container(
                              margin: EdgeInsets.only(
                                left: ScreenUtil().setWidth(108),
                              ),
                              child: _contentItem(index: 0, audComment: e),
                            ))
                        .toList(),
                  )),
          widget.audComment.respondNum > 0
              ? GestureDetector(
                  behavior: HitTestBehavior.translucent,
                  onTap: () {
                    _getRespondComment();
                  },
                  child: Container(
                    margin: EdgeInsets.only(left: ScreenUtil().setWidth(145)),
                    child: Text(
                        expand ? '收起' : '${widget.audComment.respondNum}条回复>',
                        style: TextStyle(
                            fontSize: style != null ? style.fontSize : null,
                            color: Color(0xFF32689A))),
                  ),
                )
              : Container(),
        ],
      ),
    );
  }

  _contentItem({int index, AudComment audComment}) {
    return InkWell(
      child: Container(
        // height: ScreenUtil().setHeight(160),
        padding: EdgeInsets.symmetric(
            vertical: ScreenUtil().setHeight(25),
            horizontal: ScreenUtil().setWidth(37)),
        child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: <
            Widget>[
          Container(
            width: ScreenUtil().setWidth(74),
            height: ScreenUtil().setWidth(74),
            decoration: BoxDecoration(
              borderRadius: BorderRadius.circular(ScreenUtil().setWidth(37)),
            ),
            child: PhysicalModel(
              color: Colors.transparent,
              clipBehavior: Clip.antiAlias,
              borderRadius: BorderRadius.circular(ScreenUtil().setWidth(37)),
              child: Image.network(
                audComment.headURL ??
                    'https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201901%2F14%2F20190114231742_cVVta.thumb.224_0.jpeg&refer=http%3A%2F%2Fb-ssl.duitang.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=jpeg?sec=1625648523&t=65e15a4089d504351c38ad3d100fafc0',
              ),
            ),
          ),
          Expanded(
            flex: 1,
            child: Container(
              margin:
                  EdgeInsets.symmetric(horizontal: ScreenUtil().setWidth(34)),
              child: Column(
                crossAxisAlignment: CrossAxisAlignment.start,
                children: <Widget>[
                  _titleWidget(index: index, audComment: audComment),
                  _subTitleWidget(index: index, audComment: audComment),
                ],
              ),
            ),
          ),
          _trailing(index: index, audComment: audComment),
        ]),
      ),
      onTap: () {
        if (widget.getFocus != null) {
          widget.getFocus(audComment.nickName ?? '小王', audComment.id);
        }
      },
      onLongPress: () {
        Fluttertoast.showToast(msg: '举报');
        _showReport(index);
      },
    );
  }

  _titleWidget({int index, AudComment audComment}) {
    return Container(
      // height: ScreenUtil().setHeight(71),
      alignment: Alignment.topLeft,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            audComment.nickName ?? '小王',
            style: TextStyle(
                fontSize: 14, color: Color.fromRGBO(118, 118, 118, 1)),
            textAlign: TextAlign.left,
          ),
          _date(index: index, audComment: audComment),
        ],
      ),
    );
  }

  Widget _date({int index, AudComment audComment}) {
    var createdAt_DateTime = DateTime.parse(
        audComment.createdAt ?? '2021-08-16T09:25:48.930926+08:00');
    LocalDateTime createdAt = LocalDateTime.dateTime(createdAt_DateTime);
    LocalDateTime now = LocalDateTime.now();
    Period diff = now.periodSince(createdAt);

    String date;
    if (diff.years >= 1 || (createdAt.year != now.year)) {
      date = formatDate(createdAt_DateTime, [yyyy, "年", mm, "月", dd, "日"]);
    } else if (diff.months >= 1 || (createdAt.monthOfYear != now.monthOfYear)) {
      date = formatDate(createdAt_DateTime, [mm, "月", dd, "日"]);
    } else if (diff.days >= 1 || (createdAt.dayOfMonth != now.dayOfMonth)) {
      if (createdAt.dayOfMonth != now.dayOfMonth && diff.days == 0) {
        date = "${(diff.days + 1).toString()}天前";
      } else {
        date = "${diff.days.toString()}天前";
      }
      ;
    } else {
      date = "${diff.hours.toString()}小时前";
    }

    return Text(
      date,
      style: TextStyle(fontSize: 11, color: Color.fromRGBO(159, 159, 159, 1)),
    );
  }

  _subTitleWidget({int index, AudComment audComment}) {
    return Text(
      audComment.comment ?? '',
      maxLines: 3,
      overflow: TextOverflow.ellipsis,
      style: TextStyle(color: Colors.black),
    );
  }

  _trailing({int index, AudComment audComment}) {
    return Container(
      width: ScreenUtil().setWidth(70),
      // height: ScreenUtil().setHeight(30),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.end,
        children: [
          Text(audComment.praiseNum.toString() ?? '赞'),
          InkWell(
            child: Icon(
              Icons.thumb_up_outlined,
              color: Color(0xFF666666),
            ),
            onTap: () {
              Fluttertoast.showToast(msg: '赞赞');
              praiseComment(audComment);
              setState(() {
                // audCommentList[index].isPraise = 1;
              });
            },
          )
        ],
      ),
    );
  }

  void _showReport(index) {
    showDialog(
        context: context,
        builder: (context) {
          return SimpleDialog(
            contentPadding: EdgeInsets.all(ScreenUtil().setWidth(30)),
            children: <Widget>[
              InkWell(
                child: Container(
                  alignment: Alignment.centerLeft,
                  height: ScreenUtil().setHeight(80),
                  child: Text('回复'),
                ),
                onTap: () {
                  Navigator.pop(context);
                  if (widget.getFocus != null) {
                    widget.getFocus(widget.list[index], 1);
                  }
                },
              ),
              InkWell(
                child: Container(
                  alignment: Alignment.centerLeft,
                  height: ScreenUtil().setHeight(80),
                  child: Text('举报'),
                ),
                onTap: () {
                  Navigator.pop(context);
                  ReportPage.show(context, bookId: index);
                },
              ),
              InkWell(
                child: Container(
                  alignment: Alignment.centerLeft,
                  height: ScreenUtil().setHeight(80),
                  child: Text('复制'),
                ),
                onTap: () {
                  setData(widget.list[index]);
                  Navigator.pop(context);
                },
              ),
            ],
          );
        });
  }

  //复制内容
  static setData(String data) {
    if (data != null && data != '') {
      Clipboard.setData(ClipboardData(text: data));
    }
  }

//获取某条评论的回复
  void _getRespondComment() async {
    if (!expand) {
      GetAudCommentModel getAudCommentModel =
          await CommentDao.getRespondComment(widget.audComment.id);
      if (getAudCommentModel.success) {
        _audCommentList = getAudCommentModel.data.items;
        Fluttertoast.showToast(msg: '获取某条评论的回复');
      } else {
        Fluttertoast.showToast(msg: '获取某条评论的回复失败');
      }
    }
    setState(() {
      expand = !expand;
    });
  }

  /**
   * 点赞
   */
  void praiseComment(AudComment audComment) async {
    BaseModel baseModel = await CommentDao.postPraiseComment(
        commentID: audComment.id, isPraise: audComment.isPraise ?? true);
    if(baseModel.success){
      Fluttertoast.showToast(msg: '点赞成功');
      audComment.isPraise = true;
    }
    setState(() {

    });
  }
}

上一篇下一篇

猜你喜欢

热点阅读