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

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

问题描述

我正在学习Flutter上的应用开发,无法在AlertDialog中使用我的Slider.它不会改变它的值.
我确实搜索了问题,并在StackOverFlow上遇到了这篇文章:
Flutter-为什么滑块在AlertDialog中不更新?
我读了一下,对它有点理解.接受的答案表示:

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) {...}

我了解我将需要利用异步,等待和未来.但是我不知道到底是怎么做到的.我在这个问题上花了一个多小时,不能再花了.如果这个问题愚蠢无礼,请原谅我.但是请相信我,我已经尽力了.

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天全站免登陆