【问题标题】:How to save scroll position of listview while doing setstate in Flutter?在 Flutter 中设置状态时如何保存列表视图的滚动位置?
【发布时间】:2022-01-06 04:44:00
【问题描述】:

我有产品清单。在将它们添加到购物车时,我正在执行 setstate 并使用购物车中的物品数量更新 ui。在执行 setstate 时,我的列表视图将排在第一位。我希望它位于我将商品添加到购物车的相同滚动位置上?知道怎么做吗?`

getCart() async {
    Result response = await authService.fetchCart();
    loading = true;
    if (response is SuccessState) {
      if (response.value['status'] == true) {
        List tempCart = [];
        for (var i = 0; i < response.value['data'].length; i++) {
          if (response.value['data'][i]['type'] == 'Products') {
            tempCart = response.value['data'][i]['data'];
          }
        }
        loading = false;
        setState(() {
          cart = tempCart;
        });
      } else {
        loading = false;
      }
    } else {
      loading = false;
      showDialog(
          context: context,
          builder: (context) {
            return AlertDialog(
              title: Center(
                  child: Text('Server error please try after some time!!!')),
              actions: <Widget>[
                Center(
                  child: InkWell(
                    onTap: () {
                      Navigator.pop(context);
                    },
                    child: Container(
                        decoration: BoxDecoration(
                            color: AppColors.primaryColor,
                            borderRadius: BorderRadius.all(
                              Radius.circular(20.0),
                            )),
                        margin:
                            EdgeInsets.symmetric(horizontal: 0, vertical: 20),
                        child: Padding(
                          padding: EdgeInsets.only(
                              left: 40, right: 40, top: 10, bottom: 10),
                          child: Text('Ok',
                              style: TextStyle(
                                  fontWeight: FontWeight.w400,
                                  fontSize: AppStyles.SMALL_TEXTSIZE,
                                  color: Colors.white),
                              textAlign: TextAlign.center),
                        )),
                  ),
                ),
              ],
            );
          });
    }
  }`

      ListView.builder(
                  key: PageStorageKey(_globalCounter),
                  physics: NeverScrollableScrollPhysics(),
                  scrollDirection: Axis.vertical,
                  shrinkWrap: true,
                  itemCount: products.length,
                  itemBuilder: (context, i) {
                    if (products.length > 0 &&
                        i == products.length - 1 &&
                        page < total_pages) {
                      print('index equal to length');
                      loading = true;
                      return _buildProgressIndicator();
                    } else {
                      return GestureDetector(
                          onTap: () {
                            Navigator.of(context).push(
                              MaterialPageRoute(
                                builder: (context) => ProductDetail(
                                    id: products[i]['id'].toString()),
                              ),
                            );
                          },
                          child: Container(
                              decoration: BoxDecoration(
                                border: Border.all(
                                    color: Colors.grey[100], width: 1),
                                borderRadius: BorderRadius.all(
                                  Radius.circular(10.0),
                                ),
                              ),
                              child: Padding(
                                  padding: EdgeInsets.only(
                                      top: 25,
                                      bottom: 10,
                                      left: 0,
                                      right: 0),
                                  child: Row(
                                    children: [
                                      Expanded(
                                          child: Container(
                                              child:
                                              // Image.network(
                                              //     products[i]['image'] !=
                                              //             null
                                              //         ? products[i]
                                              //             ['image']
                                              //         : '')
                                              CachedNetworkImage(
                                                imageUrl: products[i]['image'],
                                                placeholder: (context, url) => Align(
                                                  alignment: Alignment.center,
                                                  child: Loader(),
                                                ),

                                                errorWidget: (context, url, error) => Icon(Icons.error),
                                              ),
                                          )),
                                      Expanded(
                                          flex: 2,
                                          child: Column(
                                            children: [
                                              Padding(
                                                  padding:
                                                      EdgeInsets.only(
                                                          top: 5,
                                                          bottom: 5,
                                                          left: 10,
                                                          right: 5),
                                                  child: Text(
                                                      products[i][
                                                          'generic_name'],
                                                      style: TextStyle(
                                                          fontWeight:
                                                              FontWeight
                                                                  .w500,
                                                          fontSize:
                                                              AppStyles
                                                                  .SMALL_TEXTSIZE))),
                                              Padding(
                                                  padding:
                                                      EdgeInsets.only(
                                                          top: 2,
                                                          bottom: 5,
                                                          left: 10,
                                                          right: 5),
                                                  child: Container(
                                                      width: double
                                                          .infinity,
                                                      child: Wrap(
                                                        children: [
                                                          Text('MRP ',
                                                              style: TextStyle(
                                                                  fontWeight: FontWeight
                                                                      .w500,
                                                                  fontSize: AppStyles
                                                                      .SMALL_TEXTSIZE,
                                                                  color: Colors
                                                                      .deepOrangeAccent,
                                                                  decoration:
                                                                      TextDecoration.lineThrough)),
                                                          Text(
                                                              'Rs. ${products[i]['mrp_amount']} ',
                                                              style: TextStyle(
                                                                  fontWeight: FontWeight
                                                                      .w500,
                                                                  fontSize: AppStyles
                                                                      .SMALL_TEXTSIZE,
                                                                  color: Colors
                                                                      .deepOrangeAccent,
                                                                  decoration:
                                                                      TextDecoration.lineThrough)),
                                                          Text(
                                                              ' Rs. ${products[i]['chemist_amount']}',
                                                              style: TextStyle(
                                                                  fontWeight: FontWeight
                                                                      .w500,
                                                                  fontSize: AppStyles
                                                                      .SMALL_TEXTSIZE,
                                                                  color:
                                                                      Colors.lightGreen))
                                                        ],
                                                      ))),
                                              Padding(
                                                  padding:
                                                      EdgeInsets.only(
                                                          top: 2,
                                                          bottom: 5,
                                                          left: 10,
                                                          right: 5),
                                                  child: Row(
                                                    children: [
                                                      Expanded(
                                                          child:
                                                              Container(
                                                        width: double
                                                            .infinity,
                                                        child: Text(
                                                            ('${products[i]['package']}' !=
                                                                    null)
                                                                ? '${products[i]['package']}'
                                                                : '',
                                                            style: TextStyle(
                                                                fontWeight:
                                                                    FontWeight
                                                                        .w500,
                                                                fontSize:
                                                                    AppStyles
                                                                        .SMALL_TEXTSIZE,
                                                                color: Colors
                                                                    .grey)),
                                                      )),
                                                    ],
                                                  )),
                                              if (products[i] != null &&
                                                  isProductExistInCart(
                                                          products[i]
                                                              ['id']) !=
                                                      null)
                                                Row(
                                                  children: [
                                                    Expanded(
                                                        child: Row(
                                                      children: [
                                                        Expanded(
                                                            flex: 1,
                                                            child: Container(
                                                                width: double.infinity,
                                                                child: RawMaterialButton(
                                                                  onPressed:
                                                                      () {
                                                                    addItemToCart(products[i]['id'],
                                                                        'remove');
                                                                  },
                                                                  elevation:
                                                                      2.0,
                                                                  fillColor:
                                                                      Colors.white,
                                                                  child: Text(
                                                                      '-',
                                                                      style: TextStyle(fontSize: AppStyles.SMALL_TEXTSIZE, fontWeight: FontWeight.bold)),
                                                                  padding:
                                                                      EdgeInsets.all(1.0),
                                                                  shape:
                                                                      CircleBorder(),
                                                                ))),
                                                        Expanded(
                                                            flex: 1,
                                                            child: Container(
                                                                width: double
                                                                    .infinity,
                                                                child: Text(
                                                                    getCartCount(products[i][
                                                                        'id']),
                                                                    textAlign:
                                                                        TextAlign.center,
                                                                    style: TextStyle(fontSize: AppStyles.SMALL_TEXTSIZE, fontWeight: FontWeight.bold)))),
                                                        Expanded(
                                                          flex: 1,
                                                          child:
                                                              RawMaterialButton(
                                                            onPressed:
                                                                () {
                                                              //check Stock qty
                                                              if (isAvailableInStock(
                                                                  products[
                                                                      i])) {
                                                                addItemToCart(
                                                                    products[i]['id'],
                                                                    'add');
                                                                _globalCounter=i;
                                                              } else {
                                                                final snackBar =
                                                                    SnackBar(
                                                                  content: Text("This product is limited with" +
                                                                      products[i]['stock_in'] +
                                                                      " items"),
                                                                  duration:
                                                                      Duration(seconds: 2),
                                                                );
                                                                _scaffoldKey
                                                                    .currentState
                                                                    .showSnackBar(snackBar);
                                                              }
                                                            },
                                                            elevation:
                                                                2.0,
                                                            fillColor:
                                                                Colors
                                                                    .white,
                                                            child: Text(
                                                                '+',
                                                                style: TextStyle(
                                                                    fontSize:
                                                                        AppStyles.SMALL_TEXTSIZE,
                                                                    fontWeight: FontWeight.bold)),
                                                            padding:
                                                                EdgeInsets.all(
                                                                    1.0),
                                                            shape:
                                                                CircleBorder(),
                                                          ),
                                                        ),
                                                        Expanded(
                                                            child:
                                                                Container())
                                                      ],
                                                    )),
                                                  ],
                                                ),
                                              getBuyNowButton(
                                                  products[i])
                                            ],
                                          ))
                                    ],
                                  ))));
                    }
                  },
                )

【问题讨论】:

    标签: flutter


    【解决方案1】:

    你能显示一些代码吗?似乎您正在更新整个屏幕,重置滚动小部件及其值,也许通过在 StatefulWidget 中创建自己的 ScrollController 可以解决问题,但再次显示一些代码,以便人们可以更好地理解您的问题。 ...

    更新

    您似乎在将商品添加到购物车时更新了变量 _globalCounter,并且您还使用此变量作为键。当键不同时,Widget 本身会重新创建,失去所有内部状态(滚动等)

    if (isAvailableInStock(products[i])) {
        addItemToCart(products[i]['id'], 'add');
        _globalCounter=i; ///
    }
    
    ListView.builder(key: PageStorageKey(_globalCounter), ...);
    

    我建议在修改列表时提供静态键名并且不要更改它,或者至少在您完全确定 ListView 必须创建不同类型的列表时更改 ig

    ListView.builder(key: PageStorageKey('const name here'), ...);
    

    作为旁注,您可以尝试将构建方法与 StatelessWidgets 分开,以便更容易阅读和查找错误

    【讨论】:

    • 我添加了一个代码,我在成功调用 api 后更新列表。我需要知道什么时候 setstate 它将如何保存最后一个滚动激情。我的列表视图在项目中有一个按钮,单击按钮会触发 API 调用。
    • 我使用 singlechildscrollview 作为 listview 的父小部件。 Pagestoragekey 无法正常工作。
    • 我自己解决了这个问题,将 key 作为 pagestoragekey 给我的 singlechildscrollview 和一个 static pagestorageke 给我的 Listview 。它终于奏效了。感谢您的回复,虽然它确实帮助了我。
    【解决方案2】:

    您可以随时使用this 库转到特定索引

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-08-15
      • 1970-01-01
      • 1970-01-01
      • 2016-12-03
      • 1970-01-01
      • 2020-02-13
      相关资源
      最近更新 更多