【问题标题】:How to avoid getting repeated list in flutter如何避免在颤动中获得重复列表
【发布时间】:2020-05-02 02:09:03
【问题描述】:

我已经创建了带有未来构建器的列表视图构建器,当我到达页面末尾时,我会在其中获取下一页详细信息,但列表会重复。例如,当我再次到达第一页的末尾时,我得到了第一页列表,当我到达页面末尾时,它再次显示第二页列表。谁能帮我避免重复列表。

class Herbs extends StatefulWidget {
  final String title;
  Herbs(this.title);

  @override
  _HerbsState createState() => new _HerbsState();
}

class _HerbsState extends State<Herbs> {
  ScrollController _scrollController = new ScrollController();
  var cname;
  String gcm;
  List pages;

  @override
  void initState() {
    super.initState();
    pages = [];
    if (gcm == null) {
      gcm = '';
      this.fetchPost(gcm);
    } else {
      this.fetchPost(gcm);
    }
    _scrollController.addListener(() {
      if (_scrollController.position.pixels ==
          _scrollController.position.maxScrollExtent) {
        setState(() {
          print('Page reached end of page');
          fetchPost(gcm);
        });
      }
    });
  }


  Future<Herbslist> fetchPost(gcm) async {
    String url =
        'https://example.org/api.php?action=query&gcmtitle=Category:$cname&pilimit=max&prop=pageimages&pithumbsize=200&generator=categorymembers&format=json&gcmcontinue=$gcm';
    final response = await http.get(url);
    print(url);
    if (response.statusCode == 200) {
      var data = Herbslist.fromJson(json.decode(response.body));
      return data;
    } else {
      throw (e) {
        print("Exception thrown: $e");
        Exception(e);
      };
    }
  }

  @override
  void dispose() {
    _scrollController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    cname = widget.title;
    return new Scaffold(
      appBar: AppBar(
        title: Align(
          alignment: Alignment(-0.2, 0.3),
          child: Text(
            cname,
          ),
        ),
      ),
      body: Center(
        child: FutureBuilder<Herbslist>(
          future: fetchPost(gcm),
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              // List pages = snapshot.data.query.pages.values.toList();
              pages.addAll(snapshot.data.query.pages.values);
              return Scrollbar(
                child: ListView.builder(
                  controller: _scrollController,
                  shrinkWrap: true,
                  itemCount: pages.length,
                  itemBuilder: (BuildContext context, int index) {
                    gcm = snapshot.data.herbslistContinue.gcmcontinue;
                    var img = pages[index].thumbnail.source;
                    return Container(
                        child: Card(
                            child: GestureDetector(
                              onTap: () {
                                Navigator.push(
                                    context,
                                    MaterialPageRoute(
                                      builder: (context) => Detailpage(
                                        pages[index].title,
                                      ),
                                    ));
                              },
                              child: ListTile(
                                contentPadding: EdgeInsets.symmetric(
                                    horizontal: 8.0, vertical: 8.0),
                                leading: Container(
                                    padding: EdgeInsets.only(right: 10.0),
                                    decoration: new BoxDecoration(
                                      border: new Border(
                                          right: new BorderSide(
                                              width: 1.5, color: Colors.grey)),
                                    ),
                                    // ignore: unrelated_type_equality_checks
                                    child: img == img.isEmpty
                                        ? SizedBox(
                                      height: 50.0,
                                      width: 50.0,
                                      child: Image.asset('image.png'),
                                    )
                                        : SizedBox(
                                      height: 50.0,
                                      width: 50.0,
                                      child: FadeInImage.assetNetwork(
                                        placeholder: 'image.png',
                                        image: img,
                                        fit: BoxFit.fill,
                                      ),
                                    )),
                                title: Text(pages[index].title),
                              ),
                            )));
                  },
                ),
              );
            } else {
              return Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ),
      ),
    );
  }
}

JSON

{
    "batchcomplete": "",
    "continue": {
        "gcmcontinue": "page|41434143494120464552525547494e4541202d204152494d45444148|3704",
        "continue": "gcmcontinue||"
    },
    "query": {
        "pages": {
            "225": {
                "pageid": 225,
                "ns": 0,
                "title": "Abrus precatorius - Gunja",
                "thumbnail": {
                    "source": "https://example.org/images/thumb/c/cb/Abrus_precatorius_%281463017430%29.jpg/600px-Abrus_precatorius_%281463017430%29.jpg",
                    "width": 600,
                    "height": 450
                },
                "pageimage": "Abrus_precatorius_(1463017430).jpg"
            },
            "625": {
                "pageid": 625,
                "ns": 0,
                "title": "Abies webbiana - Talispatra",
                "thumbnail": {
                    "source": "https://example.org/images/thumb/b/b1/Red_fir.jpg/397px-Red_fir.jpg",
                    "width": 397,
                    "height": 600
                },
                "pageimage": "Red_fir.jpg"
            },
            "15995": {
                "pageid": 15995,
                "ns": 0,
                "title": "Abelmoschus esculentus - Bhenda",
                "thumbnail": {
                    "source": "https://upload.wikimedia.org/wikipedia/commons/thumb/d/d0/India_-_Koyambedu_Market_-_Ladies_Finger_03_%283986242135%29.jpg/600px-India_-_Koyambedu_Market_-_Ladies_Finger_03_%283986242135%29.jpg",
                    "width": 600,
                    "height": 450
                },
                "pageimage": "India_-_Koyambedu_Market_-_Ladies_Finger_03_(3986242135).jpg"
            }
        }
    },
    "limits": {
        "pageimages": 500
    }
}

class.dart

class Herbslist {
    String batchcomplete;
    Continue herbslistContinue;
    Query query;
    Limits limits;

    Herbslist({
        this.batchcomplete,
        this.herbslistContinue,
        this.query,
        this.limits,
    });

    factory Herbslist.fromJson(Map<String, dynamic> json) => Herbslist(
        batchcomplete: json["batchcomplete"] == null ? null : json["batchcomplete"],
        herbslistContinue: json["continue"] == null ? Continue(gcmcontinue:'0',continueContinue: '') : Continue.fromJson(json["continue"]),
        query: json["query"] == null ? null : Query.fromJson(json["query"]),
        limits: json["limits"] == null ? null : Limits.fromJson(json["limits"]),
    );

    Map<String, dynamic> toJson() => {
        "batchcomplete": batchcomplete == null ? null : batchcomplete,
        "continue": herbslistContinue == null ? null : herbslistContinue.toJson(),
        "query": query == null ? null : query.toJson(),
        "limits": limits == null ? null : limits.toJson(),
    };
}

class Continue {
    String gcmcontinue;
    String continueContinue;

    Continue({
        this.gcmcontinue,
        this.continueContinue,
    });

    factory Continue.fromJson(Map<String, dynamic> json) => Continue(
        gcmcontinue: json["gcmcontinue"] == null ? null : json["gcmcontinue"],
        continueContinue: json["continue"] == null ? null : json["continue"],
    );

    Map<String, dynamic> toJson() => {
        "gcmcontinue": gcmcontinue == null ? null : gcmcontinue,
        "continue": continueContinue == null ? null : continueContinue,
    };
}

class Limits {
    int pageimages;

    Limits({
        this.pageimages,
    });

    factory Limits.fromJson(Map<String, dynamic> json) => Limits(
        pageimages: json["pageimages"] == null ? null : json["pageimages"],
    );

    Map<String, dynamic> toJson() => {
        "pageimages": pageimages == null ? null : pageimages,
    };
}

class Query {
    Map<String, Page> pages;

    Query({
        this.pages,
    });

    factory Query.fromJson(Map<String, dynamic> json) => Query(
        pages: json["pages"] == null ? null : Map.from(json["pages"]).map((k, v) => MapEntry<String, Page>(k, Page.fromJson(v))),
    );

    Map<String, dynamic> toJson() => {
        "pages": pages == null ? null : Map.from(pages).map((k, v) => MapEntry<String, dynamic>(k, v.toJson())),
    };
}

class Page {
    int pageid;
    int ns;
    String title;
    Thumbnail thumbnail;
    String pageimage;

    Page({
        this.pageid,
        this.ns,
        this.title,
        this.thumbnail,
        this.pageimage,
    });

    factory Page.fromJson(Map<String, dynamic> json) => Page(
        pageid: json["pageid"] == null ? null : json["pageid"],
        ns: json["ns"] == null ? null : json["ns"],
        title: json["title"] == null ? null : json["title"],
        thumbnail: json["thumbnail"] == null ? Thumbnail(source:'',width:0,height:0) : Thumbnail.fromJson(json["thumbnail"]),
        pageimage: json["pageimage"] == null ? null : json["pageimage"],
    );

    Map<String, dynamic> toJson() => {
        "pageid": pageid == null ? null : pageid,
        "ns": ns == null ? null : ns,
        "title": title == null ? null : title,
        "thumbnail": thumbnail == null ? null : thumbnail.toJson(),
        "pageimage": pageimage == null ? null : pageimage,
    };
}

class Thumbnail {
    String source;
    int width;
    int height;

    Thumbnail({
        this.source,
        this.width,
        this.height,
    });

    factory Thumbnail.fromJson(Map<String, dynamic> json) => Thumbnail(
        source: json["source"] == null ? null : json["source"],
        width: json["width"] == null ? null : json["width"],
        height: json["height"] == null ? null : json["height"],
    );

    Map<String, dynamic> toJson() => {
        "source": source == null ? null : source,
        "width": width == null ? null : width,
        "height": height == null ? null : height,
    };
}

【问题讨论】:

  • 使用密钥防止重复

标签: listview flutter dart scroll


【解决方案1】:

我不确定我是否正确理解了您的问题,但我认为这是因为这条线:

pages.addAll(snapshot.data.query.pages.values);

出现错误是因为每次 FutureBuilder 运行时,数据都会附加到 pages 数组中,包含重复的内容。 你应该每次都这样做:

pages = [];

【讨论】:

    【解决方案2】:

    我看到的第一个问题是在您的 initState 方法中。在 initState super.InitState 应该是第一行。不过,这可能不会导致您遇到的问题。

    其次,您在滚动控制器上的侦听器正在调用 setState,并运行网络请求,这也重建了整个 FutureBuilder - 由于您将函数直接传递给“未来”参数,因此它还会再次运行您的网络请求。

    尝试将您的小部件分成更小的块,这样可能会更清楚问题出在哪里。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-05-19
      • 2023-02-06
      • 2017-11-30
      • 1970-01-01
      • 1970-01-01
      • 2017-02-05
      • 2023-03-08
      • 2020-09-07
      相关资源
      最近更新 更多