Flutter Visibility with Condition(如何只隐藏一个有条件的小部件)

Posted

技术标签:

【中文标题】Flutter Visibility with Condition(如何只隐藏一个有条件的小部件)【英文标题】:Flutter Visibility with Condition (How can I hide only one widget with condition) 【发布时间】:2021-10-11 09:16:31 【问题描述】:

我在使用可见性小部件时遇到问题。

我想要做的是通过依赖用户点击我的行来隐藏某些列表视图。但是当用户点击行时,所有的 Listview 都会显示出来。再次单击时,所有列表视图小部件都将消失。

我想做的是图片:This is how my page looksThis is what happens when I click on arrow button or "Sezon 1" TextThis is what I want to do when I click on arrow button or "Sezon 1" Text

我想要做的是,当我点击第 2 季时,它会显示第 2 季的剧集。当我点击第 3 季时,它将显示第 3 季剧集等。

这是我的代码(我知道现在有点乱,对此深表歉意): GestureDetector 每次点击都一样。

bool viewVisible = false;
void hideWidget() 
setState(() 
  viewVisible = !viewVisible;
  print(viewVisible);
);

StreamBuilder<QuerySnapshot>(
                stream: seasons.snapshots(),
                builder:
                    (BuildContext context, AsyncSnapshot asyncSnapshot) 
                  if (asyncSnapshot.hasError) 
                    return Center(
                        child:
                            Text('Error'));
                   else 
                    if (asyncSnapshot.hasData) 
                      List<DocumentSnapshot> listOfDocumentSnap =
                          asyncSnapshot.data.docs;

                      return Padding(
                        padding: const EdgeInsets.only(top: 0, left: 0),
                        child: Align(
                          alignment: Alignment.topLeft,
                          child: Column(
                            children: [
                              ListView.builder(
                                shrinkWrap: true,
                                itemCount: listOfDocumentSnap.length,
                                itemBuilder: (context, index) 
                                  var episodes = firestore
                                      .collection('shows')
                                      .doc(data.id)
                                      .collection('Seasons')
                                      .doc(listOfDocumentSnap[index].id)
                                      .collection('Episodes');

                                  return Column(
                                    crossAxisAlignment:
                                        CrossAxisAlignment.start,
                                    mainAxisAlignment:
                                        MainAxisAlignment.start,
                                    children: [
                                      Padding(
                                        padding: const EdgeInsets.only(
                                            top: 0, left: 18, right: 18),
                                        child: GestureDetector(
                                          onTap: () 
                                            hideWidget();
                                          ,
                                          child: Container(
                                            decoration: BoxDecoration(
                                                borderRadius:
                                                    BorderRadius.circular(
                                                        8),
                                                border: Border.all(
                                                    color: Colors.pink)),
                                            child: Row(
                                              children: [
                                                SizedBox(
                                                  width: 20,
                                                ),
                                                Text(
                                                  listOfDocumentSnap[index]
                                                      .get('name')
                                                      .toString()
                                                      .toUpperCase(),
                                                  style: TextStyle(
                                                      fontSize: 20,
                                                      color:
                                                          Colors.grey[800],
                                                      fontWeight:
                                                          FontWeight.w700),
                                                ),
                                                Spacer(flex: 1),
                                                Icon(
                                                  Icons.arrow_drop_down,
                                                  size: 45,
                                                  color: Colors.pink,
                                                ),
                                              ],
                                            ),
                                          ),
                                        ),
                                      ),
                                      StreamBuilder<QuerySnapshot>(
                                        stream: episodes.snapshots(),
                                        builder: (BuildContext context,
                                            AsyncSnapshot asyncSnapshot) 
                                          if (asyncSnapshot.hasError) 
                                            return Center(
                                                child: Text(
                                                    'Error'));
                                           else 
                                            if (asyncSnapshot.hasData) 
                                              List<DocumentSnapshot>
                                                  listOfDocumentSnap =
                                                  asyncSnapshot.data.docs;

                                              return Padding(
                                                padding:
                                                    const EdgeInsets.only(
                                                        top: 5, left: 18.0),
                                                child: Visibility(
                                                  visible: viewVisible,
                                                  child: Align(
                                                    alignment:
                                                        Alignment.topLeft,
                                                    child: Column(
                                                      children: [
                                                        ListView.builder(
                                                          shrinkWrap: true,
                                                          itemCount:
                                                              listOfDocumentSnap
                                                                  .length,
                                                          itemBuilder:
                                                              (context,
                                                                  index) 
                                                            return ListTile(
                                                              onTap: () 
                                                                setState(
                                                                    () 
                                                                  selectedIndex =
                                                                      index;
                                                                );
                                                              ,
                                                              trailing:
                                                                  Icon(Icons
                                                                      .play_arrow),
                                                              title: Text(listOfDocumentSnap[
                                                                      index]
                                                                  .id
                                                                  .toString()),
                                                            );

                                                            /*   return Text(
                                                                listOfDocumentSnap[
                                                                        index]
                                                                    .get(
                                                                        'name'));*/
                                                          ,
                                                        ),
                                                      ],
                                                    ),
                                                  ),
                                                ),
                                              );
                                             else 
                                              return Center(
                                                  child:
                                                      CircularProgressIndicator());
                                            
                                          
                                        ,
                                      ),
                                      SizedBox(
                                        height: 30,
                                      )
                                    ],
                                  );
                                ,
                              ),
                            ],
                          ),
                        ),
                      );
                     else 
                      return Center(child: CircularProgressIndicator());
                    
                  
                ,
              ),

【问题讨论】:

【参考方案1】:

我知道有两种不同的方式来处理小部件的可见性。创建一个 bool 来切换可见性。我正在使用_show

使用 if 条件 内部(列或任何小部件)

if (_show) Container(),

使用可见性小部件

  Column(
        children: [
          Visibility(
            visible: _show,
            child: Container(),
          ),
      )

【讨论】:

是的,我正在使用类似 _show 的东西。但它会关闭每个项目,而不是只显示一个。我尝试使用 if (_show) Container(),但它不接受 if 条件在小部​​件之前 为每个 show 创建单独的 statefullWidget,或者制作一个 bool 列表并使用像 show[0] 这样的放置索引.. 是的,创建布尔列表也很有效。我更喜欢使用扩展瓷砖小部件,这是一个很棒的小部件!不过也谢谢你的回答!【参考方案2】:

抱歉,我没有检查您的代码有什么问题。但是,不要为每一行编写自己的隐藏/显示逻辑,而是尝试使用 Flutter 的 ExpansionTile 小部件。它将为您处理展开/折叠状态:

https://medium.com/flutterdevs/expansion-tile-in-flutter-d2b7ba4a1f4b

【讨论】:

你好,我不知道有一个小部件。而且效果很棒!谢谢你。 (Teşekkürler :D)

以上是关于Flutter Visibility with Condition(如何只隐藏一个有条件的小部件)的主要内容,如果未能解决你的问题,请参考以下文章

如何解决错误 FAILURE: Build failed with an exception。 * 其中:脚本 'C:\flutter\packages\flutter_tools\gradle\fl

Flutter通过Visibility来实现视频和图片的轮流切换

Flutter OffstageVisibility隐藏/可见

Flutter 中extends、implements、with

software with plugin

[Mise] Toggle visibility and styles based on state with `x-show` and `x-bind` in Alpine JS