从Flutter中的子卡重新加载ListView

dpiehjr4  于 2023-03-03  发布在  Flutter
关注(0)|答案(2)|浏览(170)

我我开发了一个应用程序,其中有一个LisView与卡。我想重新加载/刷新整个ListView时,用户点击ListView中的一个项目。

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> itemsList = [
    "item0",
    "item1",
    "item2",
    "item3",
    "item4",
    "item5"
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: ListView.builder(
              itemCount: itemsList.length,
              itemBuilder: (context, index) {
                return ListItemCard(item: itemsList[index]);
              })),
    );
  }
}

class ListItemCard extends StatefulWidget {
  final String item;
  ListItemCard({this.item});
  _ListItemCardState createState() => _ListItemCardState();
}

class _ListItemCardState extends State<ListItemCard> {
  @override
  Widget build(BuildContext context) {
    return Card(
        elevation: 10,
        child: Padding(
            padding: EdgeInsets.all(0.0),
            child: Container(
                child:
              Align(
              alignment: Alignment.centerRight,
              child:Text(
                  widget.item,
                  style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                ),),
                width: 100,
                height: 100,
                color: Colors.red)));
  }
}

我正在使用Flutter 1.17。我想在用户点击时选择一个项目。我的问题是,在选择第二个项目时,应该取消选择已经选择的项目。为此,我需要更新整个列表。我的点击事件处理程序位于_ListItemCardState类中,调用setState()将仅更新我所理解的特定卡片。

o2gm4chl

o2gm4chl1#

要解决这个问题,您可以在使用ListView. builder时为每张卡片指定一个唯一的id。
第一张卡的ID为0,
第二张卡具有ID 1,
第三张卡的ID为2,......依此类推。

body: Center(
      child: ListView.builder(
          itemCount: itemsList.length,
          itemBuilder: (context, index) {
            return ListItemCard(item: itemsList[index],id:index);
          })),
);

现在,当点击一张卡片时,你可以在_MyHomePageState类中有一个回调函数,它可以从_ListItemCardState类调用,并将卡片的id作为参数传递。
所以,你的主类知道哪张卡片被点击了,因此使用setState重新构建UI,并向ListItemCard传递一个布尔值,表示卡片是否被点击了(true)或没有被点击(false)。

child: ListView.builder(
          itemCount: itemsList.length,
          itemBuilder: (context, index) {
            bool amIclicked = false;
            if (index == clickedCardId) {
              amIclicked = true;
            }
            return ListItemCard(
              item: itemsList[index],
              id: index,
              callbackFunction: this.callbackFunction,
              amIClicked: amIclicked,
            );
          })

和回调函数如下:

int clickedCardId = -1;
void callbackFunction(cardId) {
setState(() {
  clickedCardId = cardId;
});

}
完整的代码为这个参考:

import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  List<String> itemsList = [
    "item0",
    "item1",
    "item2",
    "item3",
    "item4",
    "item5"
  ];
  int clickedCardId = -1;
  void callbackFunction(cardId) {
    setState(() {
      clickedCardId = cardId;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: ListView.builder(
              itemCount: itemsList.length,
              itemBuilder: (context, index) {
                bool amIclicked = false;
                if (index == clickedCardId) {
                  amIclicked = true;
                }
                return ListItemCard(
                  item: itemsList[index],
                  id: index,
                  callbackFunction: this.callbackFunction,
                  amIClicked: amIclicked,
                );
              })),
    );
  }
}

class ListItemCard extends StatefulWidget {
  final String item;
  int id;
  var callbackFunction;
  bool amIClicked;
  ListItemCard(
      {this.item, this.id, this.callbackFunction, this.amIClicked = false});
  _ListItemCardState createState() => _ListItemCardState(
      callbackFunction: callbackFunction, id: id, amIClicked: amIClicked);
}

class _ListItemCardState extends State<ListItemCard> {
  int id;
  var callbackFunction;
  bool amIClicked;
  _ListItemCardState({this.callbackFunction, this.id, this.amIClicked = false});
  //here you finally get "amIClicked" variable with either false or true
  //Based on that , you can show different colors to your card clicked and 
  //-non-clicked
  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: callbackFunction(id),
      child: Card(
          elevation: 10,
          child: Padding(
              padding: EdgeInsets.all(0.0),
              child: Container(
                  child: Align(
                    alignment: Alignment.centerRight,
                    child: Text(
                      widget.item,
                      style:
                          TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
                    ),
                  ),
                  width: 100,
                  height: 100,
                  color: Colors.red))),
    );
  }
}

希望这有帮助!

g2ieeal7

g2ieeal72#

使用提供者从子卡所有你的改变将请求这父列表到redraw.如果任何事物改变在卡片这列表将通知

相关问题