material_segmented_control в сочетании с фьючерсами

#flutter

#флаттер

Вопрос:

я создал страницу друзей, где я хочу показать пользователю в правильном сегменте правильные данные. итак, я создал 3 фьючерса (запросы, подписчики и подписки)

на мой взгляд, обработка с помощью if над фьючерсами не самая лучшая, но я не знаю лучшего способа..

проблема в том, что если я переключаюсь с вкладки на вкладку, в будущих значениях будут данные из предыдущей вкладки..

есть ли какое-то четкое указание, которое я должен сделать перед переключением вкладки, или есть более элегантный способ решить эту проблему без большого содержимого if?

 import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:material_segmented_control/material_segmented_control.dart';
//Screens
import '../screens/friendssearch.dart';
//Services
import '../services/api_friends.dart';
//Models
import '../models/friendspending.dart';
import '../models/friendsapproved.dart';
import '../models/friendsuser.dart';

class FriendsPage extends StatefulWidget {
  @override
  _MyFriendsPageState createState() => _MyFriendsPageState();
}

class _MyFriendsPageState extends State<FriendsPage> {
  Future<List<FriendsPending>> myFriendsPending;
  Future<List<FriendsApproved>> mySubscriptions;
  Future<List<FriendsUser>> mySubscribers;
  int _currentSelection = 0;

  void initState() {
    super.initState();
    myFriendsPending = FriendsApi().getFriendRequests();
    mySubscriptions = FriendsApi().getSubscriptions();
    mySubscribers = FriendsApi().getSubscribers();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text('Friends'), actions: <Widget>[
          IconButton(
            icon: Icon(
              Icons.search,
              color: Colors.white,
            ),
            onPressed: () => {
              Navigator.push(context, MaterialPageRoute(builder: (context) => FriendsSearchPage()))
            },
          )
        ]),
        body: Center(
            child: Column(
                mainAxisAlignment: MainAxisAlignment.start,
                crossAxisAlignment: CrossAxisAlignment.center,
                children: [
              MaterialSegmentedControl(
                horizontalPadding: EdgeInsets.all(10),
                verticalOffset: 12,
                children: _children,
                selectionIndex: _currentSelection,
                borderColor: Colors.grey,
                selectedColor: Colors.green,
                unselectedColor: Colors.white,
                borderRadius: 8.0,
                disabledChildren: _disabledIndices,
                onSegmentChosen: (index) {
                  setState(() {
                    _currentSelection = index;
                  });
                },
              ),
              if (_currentSelection == 0) ...[
                FutureBuilder<List>(
                    future: myFriendsPending,
                    builder: (context, snapshot) {
                      if (!snapshot.hasData) {
                        return CircularProgressIndicator();
                      } else if (snapshot.hasError) {
                        return Text('Error, while loading friends');
                      }
                      List friendspending = snapshot.data ?? []; <-- here are the wrong values of the tab before in the snapshot
                      return Expanded(
                          child: ListView.builder(
                              shrinkWrap: true,
                              physics: NeverScrollableScrollPhysics(),
                              itemCount: friendspending.length,
                              itemBuilder: (context, index) {
                                FriendsPending friend = friendspending[index];
                                return new ListTile(
                                    onTap: () {},
                                    title: new Text(friend.user),
                                    subtitle: new Text(
                                        friend.userdata.firstname   ' '   friend.userdata.lastname),
                                    leading: ClipOval(
                                      child: friend.userdata.image == '' ||
                                              friend.userdata.image == null
                                          ? CircleAvatar(
                                              radius: 28,
                                              backgroundColor: Colors.white,
                                              backgroundImage:
                                                  AssetImage('assets/images/avatar.png'))
                                          : CachedNetworkImage(
                                              width: 56,
                                              height: 56,
                                              imageUrl: friend.userdata.image   '?w=200amp;h=200',
                                              placeholder: (context, url) =>
                                                  CircularProgressIndicator(),
                                              errorWidget: (context, url, error) =>
                                                  Icon(Icons.error),
                                            ),
                                    ),
                                    trailing: SizedBox(
                                        height: 35,
                                        child: FlatButton(
                                            onPressed: () => pressAddFriendButton(friend.user),
                                            child: Text('Accept',
                                                style: TextStyle(color: Colors.black87)),
                                            shape: RoundedRectangleBorder(
                                                borderRadius: BorderRadius.circular(18.0),
                                                side: BorderSide(color: Colors.black87)))),
                                    dense: false);
                              }));
                    })
              ] else if (_currentSelection == 1) ...[
                FutureBuilder<List>(
                    future: mySubscriptions,
                    builder: (context, snapshot) {
                      List subscriptions = snapshot.data ?? []; <-- here are the wrong values of the tab before in the snapshot
                      return Expanded(
                          child: ListView.builder(
                              shrinkWrap: true,
                              physics: NeverScrollableScrollPhysics(),
                              itemCount: subscriptions.length,
                              itemBuilder: (context, index) {
                                FriendsApproved friend = subscriptions[index];
                                return new ListTile(
                                    title: new Text(friend.userdata.sId),
                                    subtitle: new Text(
                                        friend.userdata.firstname   ' '   friend.userdata.lastname),
                                    leading: ClipOval(
                                      child: friend.userdata.image == '' ||
                                              friend.userdata.image == null
                                          ? CircleAvatar(
                                              radius: 28,
                                              backgroundColor: Colors.white,
                                              backgroundImage:
                                                  AssetImage('assets/images/avatar.png'))
                                          : CachedNetworkImage(
                                              width: 56,
                                              height: 56,
                                              imageUrl: friend.userdata.image   '?w=200amp;h=200',
                                              placeholder: (context, url) =>
                                                  CircularProgressIndicator(),
                                              errorWidget: (context, url, error) =>
                                                  Icon(Icons.error),
                                            ),
                                    ),
                                    trailing: SizedBox(
                                        height: 35,
                                        child: FlatButton(
                                            onPressed: () =>
                                                pressRemoveSubscriptionButton(friend.userdata.sId),
                                            child: Text('Remove',
                                                style: TextStyle(color: Colors.black87)),
                                            shape: RoundedRectangleBorder(
                                                borderRadius: BorderRadius.circular(18.0),
                                                side: BorderSide(color: Colors.black87)))),
                                    dense: false);
                              }));
                    }),
              ] else if (_currentSelection == 2) ...[
                FutureBuilder<List>(
                    future: mySubscribers,
                    builder: (context, snapshot) {
                      List subscribers = snapshot.data ?? []; <-- here are the wrong values of the tab before in the snapshot
                      return Expanded(
                          child: ListView.builder(
                              shrinkWrap: true,
                              physics: NeverScrollableScrollPhysics(),
                              itemCount: subscribers.length,
                              itemBuilder: (context, index) {
                                FriendsUser friend = subscribers[index];
                                return new ListTile(
                                    title: new Text(friend.userdata.sId),
                                    subtitle: new Text(
                                        friend.userdata.firstname   ' '   friend.userdata.lastname),
                                    leading: ClipOval(
                                      child: friend.userdata.image == '' ||
                                              friend.userdata.image == null
                                          ? CircleAvatar(
                                              radius: 28,
                                              backgroundColor: Colors.white,
                                              backgroundImage:
                                                  AssetImage('assets/images/avatar.png'))
                                          : CachedNetworkImage(
                                              width: 56,
                                              height: 56,
                                              imageUrl: friend.userdata.image   '?w=200amp;h=200',
                                              placeholder: (context, url) =>
                                                  CircularProgressIndicator(),
                                              errorWidget: (context, url, error) =>
                                                  Icon(Icons.error),
                                            ),
                                    ),
                                    trailing: SizedBox(
                                        height: 35,
                                        child: FlatButton(
                                            onPressed: () =>
                                                pressRemoveSubscriberButton(friend.userdata.sId),
                                            child: Text('Remove',
                                                style: TextStyle(color: Colors.black87)),
                                            shape: RoundedRectangleBorder(
                                                borderRadius: BorderRadius.circular(18.0),
                                                side: BorderSide(color: Colors.black87)))),
                                    dense: false);
                              }));
                    })
              ]
            ])));
  }

  Map<int, Widget> _children = {
    0: Text('  Requests  '),
    1: Text('  Subscriptions  '),
    2: Text('  Subscribers  '),
  };

  List<int> _disabledIndices = [];
}
 

Ответ №1:

Вы можете поместить a Key в FutureBuilder , чтобы flutter знал, что вы ссылаетесь на другой экземпляр builder . Без ключа он видит виджет того же типа и использует кэшированную версию, чтобы сократить время перестройки (поскольку считает, что она не изменилась). С ключом он будет знать, что каждый FutureBuilder отличается.

 if (_currentSelection == 0) ...[
    FutureBuilder<List>(
        key: ValueKey(0),
        future: myFriendsPending,
        ...
    )]
else if (_currentSelection == 1) ...[
    FutureBuilder<List>(
        key: ValueKey(1),
        future: mySubscriptions,
        ...
    )]
else if (_currentSelection == 2) ...[
    FutureBuilder<List>(
        key: ValueKey(2),
        future: mySubscribers,
        ...
    )]
 

Комментарии:

1. спасибо, я тоже попробую это.. тем временем я нашел решение с помощью Visibility() .. я создаю все 3 виджета и управляю 3 логическими переменными, которые контролируют видимость 3 фьючерсов