Home > Net >  Flutter : scrollController.isAttached is always false
Flutter : scrollController.isAttached is always false

Time:09-17

How can I scroll to a special widget in a ListView? For example, I want to automatically scroll to some container in ListView if I press a certain button on a previous screen. I will pass to the next screen an Id (from id I will know the index) and when I navigate to the next screen I want to automatically scroll to this widget. the code in main screen : Navigator.push(context, MaterialPageRoute(builder: (_) => CreatedEstatesScreen(estateId: id))); the code in the next screen :

class RecentEstateOrdersScreen extends StatefulWidget {
  static const String id = "RecentEstateOrdersScreen";

  String? estateId;

  RecentEstateOrdersScreen({Key? key, this.estateId}) : super(key: key);

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

class _RecentEstateOrdersScreenState extends State<RecentEstateOrdersScreen> {
  late RecentEstatesOrdersBloc _recentEstatesOrdersBloc;
  late ItemScrollController scrollController;
  late ItemPositionsListener itemPositionsListener;
  String? userToken;
  List<EstateOrder> orders = [];

  @override
  void initState() {
    super.initState();
    _recentEstatesOrdersBloc = RecentEstatesOrdersBloc(EstateOrderRepository());
    _onRefresh();
    User? user = BlocProvider.of<UserLoginBloc>(context).user;
    if (user != null && user.token != null) {
      userToken = user.token;
    }
    
    scrollController = ItemScrollController();
    itemPositionsListener = ItemPositionsListener.create();
  }

  _onRefresh() {
    if (BlocProvider.of<UserLoginBloc>(context).user!.token != null) {
      _recentEstatesOrdersBloc.add(
        RecentEstatesOrdersFetchStarted(
            token: BlocProvider.of<UserLoginBloc>(context).user!.token!),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Scaffold(
        appBar: AppBar(
          title: Text(
            AppLocalizations.of(context)!.recent_created_orders,
          ),
        ),
        body: BlocConsumer<RecentEstatesOrdersBloc, RecentEstatesOrdersState>(
          bloc: _recentEstatesOrdersBloc,
          listener: (context, recentOrdersState) async {
            if (recentOrdersState is RecentEstatesOrdersFetchError) {
              var error = recentOrdersState.isConnectionError
                  ? AppLocalizations.of(context)!.no_internet_connection
                  : recentOrdersState.error;
              await showWonderfulAlertDialog(
                  context, AppLocalizations.of(context)!.error, error);
            }
          },
          builder: (BuildContext context, recentOrdersState) {
            if (recentOrdersState is RecentEstatesOrdersFetchProgress) {
              return const ClientsOrdersShimmer();
            }
            if (recentOrdersState is! RecentEstatesOrdersFetchComplete) {
              return Container();
            }

            orders = recentOrdersState.estateOrders;
            if (orders.isEmpty) {
              return Center(
                child: Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    SvgPicture.asset(
                      documentOutlineIconPath,
                      width: 0.5.sw,
                      height: 0.5.sw,
                      color: Theme.of(context)
                          .colorScheme
                          .onBackground
                          .withOpacity(0.42),
                    ),
                    48.verticalSpace,
                    Text(
                      AppLocalizations.of(context)!.have_not_recent_orders,
                      style: Theme.of(context).textTheme.headline4,
                    ),
                  ],
                ),
              );
            }

            if (widget.estateId != null) {
              SchedulerBinding.instance!.addPostFrameCallback((_) {
                jumpToOrder(orders);
              });
            }
            return RefreshIndicator(
              color: Theme.of(context).colorScheme.primary,
              onRefresh: () async {
                _onRefresh();
              },
              child: ListView.builder(
                  itemCount: orders.length,
                  itemBuilder: (_, index) {
                    return EstateOrderCard(
                      estateOrder: orders.elementAt(index),
                    );
                  }),
            );
          },
        ),
      ),
    );
  }
  jumpToOrder(List<EstateOrder> orders) {
    int index = getIndexFromId(orders);
    if (index != -1) {
      if (scrollController.isAttached) {
        scrollController.scrollTo(
            index: index,
            duration: const Duration(seconds: 2),
            curve: Curves.easeInOutCubic);
      }
    }
  }

  getIndexFromId(List<EstateOrder> orders) {
    for (int i = 0; i < orders.length; i  ) {
      if (orders.elementAt(i).id == int.parse(widget.estateId!)) {
        return i;
      }
    }
    return -1;
  }
}```

CodePudding user response:

If you are using the library then you have to use ScrollablePositionedList.builder, not the normal ListView.builder.

  • Related