刷新指示器在flutter中不与ListView一起工作

ecbunoof  于 2023-03-04  发布在  Flutter
关注(0)|答案(2)|浏览(124)

平台:Flutter web嗨,我在让列表视图调用refreshindicator时遇到了困难。问题是我无法使用指示器刷新屏幕上的数据。奇怪的是,我的列表视图对我的鼠标拖动没有响应,但它可以使用鼠标中的滚轮滚动。不确定这是否相关。下面是代码:

class QuestionListPage extends StatefulWidget {
  final int id;
  QuestionListPage(this.id);

  @override
  createState() => _QuestionListPageState(this.id);
}

class _QuestionListPageState extends State<QuestionListPage> {
  final int id;
  List<Question> questions = [];

  _QuestionListPageState(this.id);

  final GlobalKey<RefreshIndicatorState> _refreshIndicatorKey =
      GlobalKey<RefreshIndicatorState>();

  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback(((timeStamp) {
      showDialog(
        context: context,
        builder: (context) {
          return const Center(
              child: CircularProgressIndicator(
            strokeWidth: 10, //strokewidth makes it fatter.
            backgroundColor: Colors.white,
            color: Colors.blue,
          ));
        },
      );
    }));
    loadData();
  }

  loadData() async {
    dynamic questionsList;
    try {
      questionsList = await QuestionController.fetchByModule(id);
    } catch (e) {
      await alertDialogShow("Error", "$e");
    }
    if (mounted) {
      Navigator.of(context).pop();
      setState(() {
        this.questions = questionsList;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          "Questions",
          style: TextStyle(color: Colors.white),
          textAlign: TextAlign.left,
        ),
        actions: [
          Padding(
              padding: const EdgeInsets.only(right: 20.0),
              child: GestureDetector(
                onTap: () {
                  //moved to question type
                  // _navigateQuestionTypePage(context);
                  _navigateNewQuestionPage(context);
                },
                child: const Icon(
                  // Icons.fiber_new_outlined,
                  Icons.add_box_outlined,
                  size: 26.0,
                ),
              )),
        ],
      ),
      body: RefreshIndicator(
        key: _refreshIndicatorKey,
        triggerMode: RefreshIndicatorTriggerMode.anywhere,
        edgeOffset: 40,
        displacement: 200,
        strokeWidth: 10,
        color: Colors.white,
        backgroundColor: Colors.blue,
        onRefresh: () async {
          await loadData();
        },
        child: Stack(
          children: <Widget>[
            ListView.builder(
              physics: AlwaysScrollableScrollPhysics(),
              itemCount: questions.length,
              itemBuilder: _listViewItemBuilder,
            ),
          ],
        ),
      ),
    );
  }

  void _navigateNewQuestionPage(BuildContext context) {
    Navigator.push(
        context, MaterialPageRoute(builder: (context) => NewQuestionPage(id)));
  }

  Widget _listViewItemBuilder(BuildContext context, int index) {
    final question = questions[index];
    return ListTile(
      contentPadding: const EdgeInsets.all(10.0),
      title: Text('Question: ${question.question_text}',
          maxLines: 2,
          style: const TextStyle(
              fontWeight: FontWeight.bold, fontSize: 12, color: Colors.black),
          textAlign: TextAlign.left),
      subtitle: Text(
        'Type: ${question.type}',
        style: const TextStyle(
            fontWeight: FontWeight.normal, fontSize: 12, color: Colors.black),
      ),
      trailing: IconButton(
          icon: const Icon(Icons.info_outline_rounded),
          onPressed: () =>
              _navigateToModuleDetail(context, questions[index].id!)),
    );
  }

  void _navigateToModuleDetail(BuildContext context, int questionID) {
    Navigator.push(
        context,
        MaterialPageRoute(
            builder: (context) => QuestionDetailPage(questionID)));
  }

  alertDialogShow(String titleString, String detailString) async {
    return await showDialog<String>(
      context: context,
      builder: (BuildContext context) => AlertDialog(
        title: Text(titleString),
        content: Text(detailString),
        actions: <Widget>[
          TextButton(
            style: ButtonStyle(
                backgroundColor: MaterialStateProperty.all(HexColor("0039A6"))),
            onPressed: () => Navigator.pop(context, 'OK'),
            child: const Text(
              'OK',
              style: TextStyle(color: Colors.white),
            ),
          ),
        ],
      ),
    );
  }
}
xoshrz7s

xoshrz7s1#

您正在使用不可滚动的stack小工具。根据documentationRefreshIndicator需要可滚动的子项,如SingleChildViewListView等。
所以试试这个代码

SingleChildScrollView(
    physics:NeverScrollable(),
    shrink: true.
    child: Stack(
              children: <Widget>[
                ListView.builder(
                  physics: AlwaysScrollableScrollPhysics(),
                  itemCount: questions.length,
                  itemBuilder: _listViewItemBuilder,
                ),
              ],
            )),
fae0ux8s

fae0ux8s2#

所以我的问题是专门针对Flutter web的。这是一个已知的bug,对于那些不知道的人来说。另一种选择是使用dart包之一:https://pub.dev/packages/liquid_pull_to_refresh
我更新了代码以使用:

body: LiquidPullToRefresh(
        key: _refreshIndicatorKey,
        color: Colors.white,
        backgroundColor: Colors.blue,
        onRefresh: () async {
          await loadData();
        },
        child: Stack(
          children: <Widget>[
            ListView.builder(
              scrollDirection: Axis.vertical,
              physics: AlwaysScrollableScrollPhysics(),
              itemCount: questions.length,
              itemBuilder: _listViewItemBuilder,
            ),
          ],
        ),
      ),

效果很好。

相关问题