如何在 Flutter 的 AlertDialog 中实现 Slider? [英] How to implement a Slider within an AlertDialog in Flutter?

查看:22
本文介绍了如何在 Flutter 的 AlertDialog 中实现 Slider?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 Flutter 上的应用程序开发,但无法让我的 Slider 在 AlertDialog 中工作.它不会改变它的价值.
我确实搜索了这个问题,并在 StackOverFlow 上看到了这篇文章:
Flutter - 为什么滑块不会在 AlertDialog 中更新?
我读了它并且有点理解它.接受的 answer 表示:

I am learning app development on Flutter and can't get my Slider to work within the AlertDialog. It won't change it's value.
I did search the problem and came across this post on StackOverFlow:
Flutter - Why slider doesn't update in AlertDialog?
I read it and have kind of understood it. The accepted answer says that:

问题是,对话框不是在 build 方法中构建的.它们位于不同的小部件树上.所以当对话创建者更新时,对话不会.

The problem is, dialogs are not built inside build method. They are on a different widget tree. So when the dialog creator updates, the dialog won't.

但是,由于没有提供足够的后台代码,我无法理解它究竟是如何实现的.

However I am not able to understand how exactly does it have to be implemented as not enough background code is provided.

这是我当前的实现的样子:

This is what my current implementation looks like:

double _fontSize = 1.0;

@override
Widget build(BuildContext context) {
  return Scaffold(
      appBar: AppBar(
        title: Text(qt.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.format_size),
            onPressed: () {
              getFontSize(context);
            },
          ),
        ],
      ),
      body: ListView.builder(
          padding: EdgeInsets.symmetric(vertical: 15.0),
          itemCount: 3,
          itemBuilder: (context, index) {
            if (index == 0) {
              return _getListTile(qt.scripture, qt.reading);
            } else if (index == 1) {
              return _getListTile('Reflection:', qt.reflection);
            } else {
              return _getListTile('Prayer:', qt.prayer);
            }
          })
  );
}

void getFontSize(BuildContext context) {
  showDialog(context: context,builder: (context){
    return AlertDialog(
      title: Text("Font Size"),
      content: Slider(
        value: _fontSize,
        min: 0,
        max: 100,
        divisions: 5,
        onChanged: (value){
          setState(() {
            _fontSize = value;
          });
        },
      ),
      actions: <Widget>[
        RaisedButton(
          child: Text("Done"),
          onPressed: (){},
        )
      ],
    );
  });
}


Widget parseLargeText(String text) {...}

Widget _getListTile(String title, String subtitle) {...}

我知道我需要使用 async 和 await 和 Future.但我无法理解到底是怎么回事.我已经在这个问题上花了一个多小时,而且不能再多了.如果这个问题既愚蠢又愚蠢,请原谅我.但是相信我,我已经尽力了.

I understand that I will need to make use of async and await and Future. But I am not able to understand how exactly. I've spent more than an hour on this problem and can't any more. Please forgive me if this question is stupid and noobish. But trust me, I tried my best.

推荐答案

这是一个最小的可运行示例.要点:

Here is a minimal runnable example. Key points:

  • 对话框是一个有状态的小部件,它将当前值存储在其 State 中.这很重要,因为从技术上讲,对话框在您的应用中是独立的页面",插入到层次结构的较高位置
  • Navigator.pop(...) 关闭对话框并返回结果
  • async/await
  • 的使用
  • The dialog is a stateful widget that stores the current value in its State. This is important because dialogs are technically separate "pages" on your app, inserted higher up in the hierarchy
  • Navigator.pop(...) to close the dialog and return the result
  • Usage of async/await
import 'package:flutter/material.dart';

void main() => runApp(App());

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: HomePage(),
    );
  }
}

class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  double _fontSize = 20.0;

  void _showFontSizePickerDialog() async {
    // <-- note the async keyword here

    // this will contain the result from Navigator.pop(context, result)
    final selectedFontSize = await showDialog<double>(
      context: context,
      builder: (context) => FontSizePickerDialog(initialFontSize: _fontSize),
    );

    // execution of this code continues when the dialog was closed (popped)

    // note that the result can also be null, so check it
    // (back button or pressed outside of the dialog)
    if (selectedFontSize != null) {
      setState(() {
        _fontSize = selectedFontSize;
      });
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisSize: MainAxisSize.min,
          children: <Widget>[
            Text('Font Size: ${_fontSize}'),
            RaisedButton(
              onPressed: _showFontSizePickerDialog,
              child: Text('Select Font Size'),
            )
          ],
        ),
      ),
    );
  }
}

// move the dialog into it's own stateful widget.
// It's completely independent from your page
// this is good practice
class FontSizePickerDialog extends StatefulWidget {
  /// initial selection for the slider
  final double initialFontSize;

  const FontSizePickerDialog({Key key, this.initialFontSize}) : super(key: key);

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

class _FontSizePickerDialogState extends State<FontSizePickerDialog> {
  /// current selection of the slider
  double _fontSize;

  @override
  void initState() {
    super.initState();
    _fontSize = widget.initialFontSize;
  }

  @override
  Widget build(BuildContext context) {
    return AlertDialog(
      title: Text('Font Size'),
      content: Container(
        child: Slider(
          value: _fontSize,
          min: 10,
          max: 100,
          divisions: 9,
          onChanged: (value) {
            setState(() {
              _fontSize = value;
            });
          },
        ),
      ),
      actions: <Widget>[
        FlatButton(
          onPressed: () {
            // Use the second argument of Navigator.pop(...) to pass
            // back a result to the page that opened the dialog
            Navigator.pop(context, _fontSize);
          },
          child: Text('DONE'),
        )
      ],
    );
  }
}

这篇关于如何在 Flutter 的 AlertDialog 中实现 Slider?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆