【问题标题】:How to add Progress Indicator on Cards while tap in Flutter?在 Flutter 中点击时如何在卡片上添加进度指示器?
【发布时间】:2020-07-31 07:50:52
【问题描述】:

我在 Flutter 中使用卡片,希望进度指示器在左下位置 2 秒,同时点击卡片,以便成功加载另一个页面。 有人知道怎么加吗?

 Container(
           height: 130,
           child: Card(
             child: Row(
               children: <Widget>[
                 Expanded(
                   child: ListTile(
                       title: Text(
                         'My card Location',
                         style: TextStyle(
                             fontSize: 15, fontWeight: FontWeight.w700),
                       ),

                       leading: Icon(Icons.setting),
                       // color: Colors.blueAccent, size: mediumIconSize),
                       trailing: Icon(Icons.keyboard_arrow_right),
                       selected: true,

                       onTap: () async {

                    //   I try this one but not working
                         //  Flushbar(
                    // 
                       //    showProgressIndicator: true,
                       //    duration:  Duration(seconds: 2),
                       //  );
               getDetails().then((myCardlocations) {
                 Navigator
                     .of(context)
                     .pushNamed('/myCardlocations',
                     arguments: ObjectLocations(locations, 'myCardlocations'));
               }
               );
                       }
                      
                  
                   ),
                 ),
               ],
             ),
           ),
         ),

【问题讨论】:

  • 看看我的回答,让我知道,如果这对你有用:)

标签: flutter flutter-layout


【解决方案1】:

在给出实际答案之前,我想提一下某些事情。

  • 了解Flutter.delayed constructor,通过提供Duration 让某些东西等待一段时间并执行操作非常有用。在这段时间之后,无论您想做什么,它都会在 callback 函数中实现
Future.delayed(Duration(seconds: your_time, (){
   //it will perform this operation after that much of seconds
}));
  • 您始终可以使用bool value 显示/隐藏Widget,并进行相应的更改
  • 使用列并将LinearProgressIndicator 添加到Widget 的末尾。根据数据显示/隐藏它
  • 另外,使用MediaQuery 给出高度。这是根据所有手机尺寸提供尺寸的更有效方法。就像match-parent 中的Android Studio。相应地做数学,我也在代码中显示了
Column(
  children: [
    Row(),
    bool val ? LinearProgressIndicator() : Container() // Container() is nothing but an empty widget which shows nothing
  ]
)

请注意:我没有使用过getData,因为它没有正确定义,但您可以将其称为in 函数,我将在代码中向您展示,即pageTransit() .跟着 cmets 走就可以了

 class _MyHomePageState extends State<MyHomePage> {
  // this takes care of the show/hide of your progress indicator
  bool _showProgress = false;
  
  // this takes care of the operation
  void pageTransit(){
    // first show when the ListTile is clicked
    setState(() => _showProgress = true);
    Future.delayed(Duration(seconds: 2), (){
      // hide it after 2 seconds
      setState(() => _showProgress = false);
      
      // do the page trnasition here
      //getDetails().then((myCardlocations) {
        //Navigator.of(context).pushNamed('/myCardlocations',
          //arguments: ObjectLocations(locations, 'myCardlocations'));
       //}
    });  
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Container(
         height: MediaQuery.of(context).size.height * 0.1,
         child: Card(
           child: Column(
             crossAxisAlignment: CrossAxisAlignment.start,
             children: [
               // use your items here, based upon the bool value show hide your 
               // progress indicator
               Row(
                 children: <Widget>[
                   Expanded(
                     child: ListTile(
                         title: Text(
                           'My card Location',
                           style: TextStyle(
                               fontSize: 15, fontWeight: FontWeight.w700),
                         ),                       
                         leading: Icon(Icons.settings),
                         // color: Colors.blueAccent, size: mediumIconSize),
                         trailing: Icon(Icons.keyboard_arrow_right),
                         selected: true,
                         onTap: () => pageTransit() 
                     )
                   )
                 ]
               ),
               // show/hide in the card
               _showProgress ? LinearProgressIndicator() : Container()
             ]
           )
         )
       )
    );
  }
}

结果

ProgressIndicator,它会在那里停留2秒,然后消失

【讨论】:

    【解决方案2】:

    您可以使用 StackCircularProgressIndicator.. 执行类似操作。

    class _MyWidgetState extends State<MyWidget> {
      bool isLoading = false;
    
      @override
      Widget build(BuildContext context) {
        return Container(
          height: 130,
          child: Stack(
            children: [
              Container(
                height: 130,
                child: Card(
                  child: Row(
                    children: <Widget>[
                      Expanded(
                        child: ListTile(
                          title: Text(
                            'My card Location',
                            style: TextStyle(
                                fontSize: 15, fontWeight: FontWeight.w700),
                          ),
                          leading: Icon(Icons.settings),
                          // color: Colors.blueAccent, size: mediumIconSize),
                          trailing: Icon(Icons.keyboard_arrow_right),
                          selected: true,
                          onTap: () async {
                            
                            setState(() {
                              isLoading = true;
                            });
    
                            getDetails().then((myCardLocations) {
                              setState(() {
                                isLoading = false;
                              });
                              // navigation code here
                            });
    
                          },
                        ),
                      ),
                    ],
                  ),
                ),
              ),
              Align(
                alignment: Alignment.bottomLeft,
                child: isLoading
                    ? Padding(
                      padding: EdgeInsets.fromLTRB(15,0,0,15),
                      child: SizedBox(
                          width: 20,
                          height: 20,
                          child: CircularProgressIndicator(),
                        ),
                    )
                    : SizedBox(),
              ),
            ],
          ),
        );
      }
    
    }
    

    编辑:

    看起来我有点误解了这个问题。具体来说,显示进度指示器的位置。无论如何,如果你明白了,你可以根据你的要求把指标放在不同的地方。

    【讨论】:

      【解决方案3】:

      1.您需要为Scaffold 定义一个GlobalKey,以便您可以使用SnackBar(您可以在页面的State 中定义GloablKey)。

      final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
      

      2.您需要为Scaffold设置密钥。

      @override
        Widget build(BuildContext context) {
          return Scaffold(
            key: _scaffoldKey,
      ...
      

      3. 您需要用GestureDetector 包裹Card 并将onTap 函数设置为调用showLoading,在屏幕底部显示SnackBar。在showLoading 中调用getDetails 函数。完整代码(定义键步骤除外):

      void _showLoading() {
          _scaffoldKey.currentState.showSnackBar(new SnackBar(
            duration: new Duration(seconds: 2),
            content: new Row(
              children: <Widget>[
                new CircularProgressIndicator(),
                new Text("Loading...")
              ],
            ),
          ));
          // call to your getDetails and its steps should be here
        }
      
        @override
        Widget build(BuildContext context) {
          return Scaffold(
            key: _scaffoldKey,
            appBar: AppBar(
              title: Text("My app"),
            ),
            body: Center(
                child: GestureDetector(
                  child: Card(
                      child: Row(children: <Widget>[
                          Expanded(
                              child: ListTile(
                                  title: Text(
                                    'My card Location',
                                    style: TextStyle(fontSize: 15, fontWeight: FontWeight.w700),
                                  ),
      
                                  leading: Icon(Icons.settings),
                                  // color: Colors.blueAccent, size: mediumIconSize),
                                  trailing: Icon(Icons.keyboard_arrow_right),
                                  selected: true,
                            )),
                  ])),
              onTap: () => _showLoading(),
            )),
          );
        }
      }
      

      注意:您还可以设置SnackBar 的样式。

      结果:

      【讨论】:

      • 哦,好的,我现在明白了。所以 OP 的意思是在页面的左下角显示一个指示器。我太傻了,我写了一个答案,在Card 的左下角显示一个指标,哈哈。我想我会在我的回答中记下这一点。 :D
      • 没关系,它可能对以后遇到同样问题的人仍然有帮助。 @JigarPatel
      猜你喜欢
      • 2021-07-25
      • 1970-01-01
      • 2020-01-13
      • 2018-10-02
      • 2021-11-28
      • 2019-04-01
      • 2017-12-30
      • 1970-01-01
      相关资源
      最近更新 更多