【问题标题】:Not able to display initial data from server using provider无法使用提供程序显示来自服务器的初始数据
【发布时间】:2021-10-12 14:14:00
【问题描述】:

我试图在我的应用程序中显示一些从服务器中提取的初始数据,我得到了数据,但我无法显示它。这是我的代码,请帮忙

必须显示数据的类

import 'package:deep_pocket/models/data_feed.dart';
import 'package:deep_pocket/models/mock_data.dart';
import 'package:deep_pocket/widgets/menu_buttons.dart';
import 'package:deep_pocket/widgets/post_widget.dart';
import 'package:deep_pocket/screens/user_input.dart';
import 'package:flutter/material.dart';
import 'package:flutter/cupertino.dart';
import 'package:provider/provider.dart';

class feedScreen extends StatefulWidget {
  static const route = '/feed-screen';

  @override
  State<feedScreen> createState() => _feedScreenState();
}

class _feedScreenState extends State<feedScreen> {
  int filter = 0;
  var _intstate = true;

  void updateFilter(tx, context) {
    setState(() {
      filter = tx;
    });

    Navigator.of(context).pop();
  }

  @override
  void initState() {
    // TODO: implement initState

    super.initState();
  }

  @override
  void didChangeDependencies() {
    if (_intstate) {
      Provider.of<mockData>(context).fetchandAddPost();
    }
    _intstate = false;
    // TODO: implement didChangeDependencies
    super.didChangeDependencies();
  }

  void filterSheet(ctx) {
    showModalBottomSheet(
        context: ctx,
        builder: (ctx) => Container(
              height: 300,
              child: SingleChildScrollView(
                  child: Container(
                height: 280,
                child: ListView.builder(
                    itemCount: Tag.length,
                    itemBuilder: (ctx, i) => TextButton(
                          onPressed: () {
                            return updateFilter(i, context);
                          },
                          child: Text(Tag[i]),
                        )),
              )),
            ));
  }

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<mockData>(
        create: (context) => mockData(),
        builder: (context, child) {
          var posts = context.select((mockData m) => m.items);
          print(posts.length);
          if (filter != 0) {
            posts = posts.where((i) => i.tag == filter).toList();
          }
          return Scaffold(
            // drawer: Drawer(
            //     // Populate the Drawer in the next step.
            //     ),
            appBar: AppBar(
              title: const Text("Home"),
              actions: [
                TextButton(
                    onPressed: () => {filterSheet(context)},
                    child: const Text(
                      "Filters",
                      style: TextStyle(color: Colors.white),
                    ))
              ],
            ),
            body: SingleChildScrollView(
              child: Column(
                children: [
                  menuButtons(),
                  Container(
                    padding: const EdgeInsets.all(8),
                    child: ListView.builder(
                        shrinkWrap: true,
                        physics: NeverScrollableScrollPhysics(),
                        itemCount: posts.length,
                        itemBuilder: (ctx, i) => postWidget(post: posts[i])),
                  ),
                ],
              ),
            ),
            floatingActionButton: FloatingActionButton(
                onPressed: () async {
                  //Waiting for result
                  var newData =
                      await Navigator.pushNamed(context, userInput.route);
                  if (newData != null) {
                    context.read<mockData>().addPost(newData as dataFeed);
                  }
                },
                child: const Icon(Icons.add)),
          );
        });
  }
}


我的 Provider 和 fetch 设置类

import 'package:deep_pocket/models/data_feed.dart';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

class mockData with ChangeNotifier {
  List<dataFeed> _data = [
    // dataFeed(
    //   id: DateTime.now().toString(),
    //   imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
    //   name: "Priyam Srivastava",
    //   title: "How to change room ?",
    //   tag: 1,
    //   text:
    // "I would like to know the process of changing my room cause I have not been able to study, and my roomate always plays music and drinks too much then shouts all night, please tell me how",
    // ),
    // dataFeed(
    //   id: DateTime.now().toString(),
    //   imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
    //   title: "Anyone intresed in playing BGMI?",
    //   name: "Part Agarwal",
    //   tag: 2,
    //   text:
    //       "So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
    // ),
    // dataFeed(
    //   id: DateTime.now().toString(),
    //   imgsrc: "https://i.pravatar.cc/150?u=a042581f4e29026704d",
    //   title: "How to solve this question in O(n) complexity",
    //   name: "Preet Singh",
    //   tag: 3,
    //   text:
    //       "So I have been looing for a squad for a long time and now i have finally decided that I am gonna buckle up and ask you all to join me",
    // ),
  ];
  List<dataFeed> get items {
    return [..._data];
  }

  Future<void> fetchandAddPost() async {
    var url = link;
    try {
      print("getting your data");
      final response = await http.get(url);
      final extractedData = json.decode(response.body) as Map<String, dynamic>;

      final List<dataFeed> loadedPosts = [];
      extractedData.forEach((key, value) {
        loadedPosts.add(dataFeed(
            id: key,
            imgsrc: value['imgsrc'],
            name: value['name'],
            title: value['title'],
            text: value['text'],
            date: value['date']));
      });
      print(loadedPosts.length);
      _data = loadedPosts;
      print(_data.length);
      print("got your data");
      notifyListeners();
    } catch (e) {
      print(e);
      // TODO
    }
  }

  Future<void> addPost(dataFeed newpost) async {
    var url = link;
    try {
      final response = await http.post(
        url as Uri,
        body: json.encode({
          'imgsrc': newpost.imgsrc,
          'name': newpost.name,
          'title': newpost.title,
          'text': newpost.text,
          'tag': newpost.tag,
          'date': newpost.date,
        }),
      );
      final newPost = dataFeed(
          id: json.decode(response.body)['name'],
          imgsrc: newpost.imgsrc,
          name: newpost.name,
          title: newpost.title,
          text: newpost.text,
          tag: newpost.tag,
          date: newpost.date);
      _data.insert(0, newPost);
      notifyListeners();
    } catch (e) {
      print(e);
      // TODO
    }
  }
}

我正在从服务器获取数据,但没有显示,如果我添加新数据,它会显示。

【问题讨论】:

    标签: flutter dart cross-platform


    【解决方案1】:

    这是使用Provider、从网络获取数据、更新ListViewpagination的基本使用年龄。

    class ExampleWidget extends StatelessWidget {
      const ExampleWidget({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return ChangeNotifierProvider<ExampleChangeNotifier>(
          create: (_) => ExampleChangeNotifier.instance(),
          builder: (_, child) {
            return Selector<ExampleChangeNotifier, NetworkStatus>(
              selector: (_, model) => model.networkStatus,
              builder: (_, nStatus, __) => nStatus == NetworkStatus.Loading
                  ? const Center(
                      child: CircularProgressIndicator(),
                    )
                  : nStatus == NetworkStatus.Error
                      ? const Center(
                          child: Text('Your error widget'),
                        )
                      : Selector<ExampleChangeNotifier, int>(
                          selector: (_, model) => model.listLength,
                          builder: (_, length, __) => length > 0
                              ? ListView.builder(
                                  itemCount: length + 1,
                                  itemBuilder: (context, index) {
                                    if (index < length) {
                                      var listItem = _.read<ExampleChangeNotifier>().list[index];
    
                                      return SizedBox(
                                        height: 60,
                                        child: Text('List item: ${listItem.whatever}'),
                                      );
                                    } else {
                                      return Center(
                                        child: ElevatedButton(
                                          onPressed: () {
                                            _.read<ExampleChangeNotifier>().loadMore();
                                          },
                                          child: Selector<ExampleChangeNotifier, bool>(
                                            selector: (_, model) => model.loadMoreRequest,
                                            builder: (_, value, __) => value ? const Text('loading...') : const Text('load more'),
                                          ),
                                        ),
                                      );
                                    }
                                  },
                                )
                              : const Center(
                                  child: Text('No data found'),
                                ),
                        ),
            );
          },
        );
      }
    }
    
    enum NetworkStatus { Loading, Done, Error }
    
    class ExampleChangeNotifier extends ChangeNotifier {
      NetworkStatus _networkStatus = NetworkStatus.Loading;
      NetworkStatus get networkStatus => _networkStatus;
    
      final List<dynamic> _list = <dynamic>[];
      List<dynamic> get list => _list;
    
      int _listLength = 0;
      int get listLength => _listLength;
    
      int _skip = 0; //Send this in your request parameters and use for pagination, e.g (for mysql query) => ... DESC LIMIT _skip, 10
    
      bool _loadMoreRequest = false;
      bool get loadMoreRequest => _loadMoreRequest;
    
      ExampleChangeNotifier.instance() {
        _getDataFromNetwork();
      }
    
      Future<void> _getDataFromNetwork() async {
        try {
          //Make your http request
          // For example : await http.get('https:example.com?skip=$_skip');
          _loadMoreRequest = false;
          // ... Parse your data
          List<dynamic> networkData = <dynamic>[];
    
          _networkStatus = NetworkStatus.Done;
    
          if (networkData.isNotEmpty) {
            for (var item in networkData) {
              _list.add(item);
              _listLength++;
            }
          }
          notifyListeners();
        } catch (e) {
         _loadMoreRequest = false;
          _networkStatus = NetworkStatus.Error;
          notifyListeners();
        }
      }
    
      Future<void> loadMore() async {
        _skip = _listLength;
        _loadMoreRequest = true;
        notifyListeners();
        await _getDataFromNetwork();
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2017-06-13
      • 2017-08-10
      • 2020-04-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多