android - 如何根据另一个小部件中的操作更新 UI 或更改小部件中的状态?

标签 android ios flutter

我正在尝试使用 flutter 开发音乐应用程序。当点击项目/音乐卡时,图标会变为暂停图标以表明其正在播放。但是当我点击卡 1 时,图标会发生变化(应该如此),但是当我点击卡 2 或任何其他卡时,该卡也会更改图标,但卡 1 仍然具有暂停图标。当点击任何其他卡时,如何将卡 1 的图标更改为默认图标?

目前我正在使用 ListView.builder() 列出所有音乐卡。实际的卡是使用另一个文件中的有状态小部件构建的。状态管理是在该文件中完成的。

main.dart 中的 ListView

ListView.builder(
  shrinkWrap: true,
  controller: ScrollController(),
  itemCount: allPodcasts.length,
  itemBuilder: (BuildContext context, index){
    return LongCard(podcast: allPodcasts[index]);
  },
)

longcard.dart

class LongCard extends StatefulWidget {

  final Podcast podcast;

  LongCard({this.podcast});

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

class _LongCardState extends State<LongCard> {

  bool playingState;

  @override
  void initState() {
    super.initState();

    setState((){
      playingState = false;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(bottom: 15.0),
      child: InkWell(
        onTap: (){
          setState((){
            if(playingState){
              playingState = false;
            }else{
              playingState = true;
            }
          });
        },
        child: Card(
          margin: EdgeInsets.zero,
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10.0),
          ),
          elevation: 1.0,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.start,
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              ClipRRect(
                borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0), bottomLeft: Radius.circular(10.0) ),
                child: Image(
                  image: AssetImage(widget.podcast.image),
                  height: 100.0,
                  width: 100.0,
                  fit: BoxFit.fill
                ),
              ),
              Padding(
                padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
                child: Align(
                  alignment: Alignment.topLeft,
                                                    child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: <Widget>[
                      Text(
                        widget.podcast.date,
                        style: Theme.of(context).textTheme.body1,
                        overflow: TextOverflow.ellipsis,
                      ),
                      SizedBox(height:5.0),
                      Text(
                        widget.podcast.title,
                        style: Theme.of(context).textTheme.display1,
                        overflow: TextOverflow.ellipsis,
                      ),
                    ],
                  ),
                )
              ),
              Expanded(
                child: SizedBox()
              ),
              Container(
                alignment: Alignment.centerRight,
                height: 100.0,
                width: 70.0,
                decoration: BoxDecoration(
                  color: lightCoral,
                  borderRadius: BorderRadius.only(topRight: Radius.circular(10.0), bottomRight: Radius.circular(10.0) ),
                ),
                child: Center(
                  child: Icon(
                    (playingState == true ) ? Icons.pause : Icons.headset,
                    size: 40.0
                  )
                )
              ),
            ],
          )
        ),
      ),
    );
}

我希望在点击一张卡时,其他卡中的图标将更改为默认图标,然后点击的卡上的图标将更改以指示其处于 Activity 状态。

最佳答案

从包含 ListView 的父窗口小部件管理列表的状态。

您的LongCard小部件应该是一个无状态小部件,仅显示数据,而不管理数据。它只会告诉父小部件在按下时切换到另一个索引。

class Page extends StatefulWidget {
  @override
  _PageState createState() => _PageState();
}

class _PageState extends State<Page> {
  // List index of the podcast that is playing right now
  int activeIndex;

  void _setActivePodcast(int index) {
    setState(() {
      activeIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Container(
      child: ListView.builder(
        shrinkWrap: true,
        controller: ScrollController(),
        itemCount: allPodcasts.length,
        itemBuilder: (BuildContext context, index) {
          return LongCard(
            podcast: allPodcasts[index],
            listIndex: index,
            isPlaying: activeIndex == index,
            onPress: _setActivePodcast,
          );
        },
      ),
    );
  }
}

class LongCard extends StatelessWidget {
  final Podcast podcast;
  final bool isPlaying;
  final int listIndex;
  final Function(int index) onPress;

  const LongCard({
    Key key,
    this.podcast,
    this.listIndex,
    this.onPress,
    this.isPlaying: false,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(bottom: 15.0),
      child: InkWell(
        onTap: () => onPress(listIndex),
        child: Card(
            margin: EdgeInsets.zero,
            shape: RoundedRectangleBorder(
              borderRadius: BorderRadius.circular(10.0),
            ),
            elevation: 1.0,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                ClipRRect(
                  borderRadius: BorderRadius.only(
                      topLeft: Radius.circular(10.0),
                      bottomLeft: Radius.circular(10.0)),
                  child: Image(
                      image: AssetImage(podcast.image),
                      height: 100.0,
                      width: 100.0,
                      fit: BoxFit.fill),
                ),
                Padding(
                    padding:
                        EdgeInsets.symmetric(horizontal: 15.0, vertical: 20.0),
                    child: Align(
                      alignment: Alignment.topLeft,
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        mainAxisAlignment: MainAxisAlignment.start,
                        children: <Widget>[
                          Text(
                            podcast.date,
                            style: Theme.of(context).textTheme.body1,
                            overflow: TextOverflow.ellipsis,
                          ),
                          SizedBox(height: 5.0),
                          Text(
                            podcast.title,
                            style: Theme.of(context).textTheme.display1,
                            overflow: TextOverflow.ellipsis,
                          ),
                        ],
                      ),
                    )),
                Expanded(child: SizedBox()),
                Container(
                  alignment: Alignment.centerRight,
                  height: 100.0,
                  width: 70.0,
                  decoration: BoxDecoration(
                    color: lightCoral,
                    borderRadius: BorderRadius.only(
                        topRight: Radius.circular(10.0),
                        bottomRight: Radius.circular(10.0)),
                  ),
                  child: Center(
                    child: Icon(
                      isPlaying ? Icons.pause : Icons.headset,
                      size: 40.0,
                    ),
                  ),
                ),
              ],
            )),
      ),
    );
  }
}

关于android - 如何根据另一个小部件中的操作更新 UI 或更改小部件中的状态?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56864591/

相关文章:

dart - Flutter 中的特殊字符

Flutter - 上传 csv 文件

javascript - 使用 3rd 方推送服务的 Nativescript 推送通知

java - 通过category_name从PHP获取到Android

IOS9 voip通讯

iOS 强制 subview 具有灵活的高度

flutter :如何发现对继承的小部件的依赖?

安卓打开Image onclick like Whatsapp Profile Picture

java - Android Studio Sql Server 连接

ios - NSData -> UIImage -> NSData?