延迟加载json列表视图颤动

延迟加载json列表视图颤动

本文介绍了延迟加载json列表视图颤动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试为从api中获取的 list 实施延迟加载.我为 ListView 实现了一个侦听器,以检查它何时到达底部.我在这里遇到的问题是:

I am trying to implement a lazy loading for a list that I am fetching from api. I have implemented a listener for my ListView to check when it reaches the bottom. The issue I have here is:

1)如何为列表设置加载项的初始数量?

1) How do I set an initial number of loaded items for my list?

2)如何在调用loadMore()方法时自动将项目添加到列表中?

2) How do I automatically add items to the list while calling my loadMore() method?

class _HomeServiceState extends State<HomePage>
    with AutomaticKeepAliveClientMixin {
   List<Mentor> filteredData;

  List<Mentor> users = [];
 @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _scrollcontroller.addListener(() {
      if (_scrollcontroller.position.atEdge) {
        if (_scrollcontroller.position.pixels == 0){
      // you are at top position

        } else{
      // you are at bottom position
          loadMore();
        }
    }
    });
  }

  @override
  Widget build(BuildContext context) {
    final mentors = new FutureBuilder(
      future: _future,
      builder: (BuildContext context, AsyncSnapshot snapshot) {
          return  ListView.builder(
              shrinkWrap: true,
              physics: ScrollPhysics(),
              itemCount: filteredData.length + 1,
              itemBuilder: (BuildContext context, int index) {
                if (index == filteredData.length) {
                  return CupertinoActivityIndicator();
                }
                return ListTile(
                  leading: CircleAvatar(
                    maxRadius: 23,
                    backgroundImage: NetworkImage(NetworkUtils.host +
                        AuthUtils.profilePics +
                        filteredData[index].profile_image),
                  ),
                  title: Text(
                      filteredData[index].first_name +
                          " " +
                          filteredData[index].last_name,
                      style: TextStyle(
                        color: Color(0xFF041F36),
                        fontFamily: 'Muli',
                        fontSize: 16.0,
                      )),
                  subtitle: Text(capitalize(filteredData[index].industry),
                      style: TextStyle(
                        color: Color(0xFF25282A),
                        fontFamily: 'MuliLight',
                        fontSize: 12.0,
                      )),
                  trailing: Text(capitalize(filteredData[index].country),
                      style: TextStyle(
                        color: Color(0xFF25282A),
                        fontFamily: 'MuliItalic',
                        fontSize: 12.0,
                      )),
                  onTap: () {
                    Navigator.push(
                        context,
                        SlideFromRightPageRoute(
                            widget: MenteeDetailPage(filteredData[index])));
                  },
                );
              },
            );
        }
      },
    );

  Future<List<Mentor>> _getUsers() async {
    sharedPreferences = await SharedPreferences.getInstance();
    var data = await http.get(
      NetworkUtils.host + AuthUtils.endPointMentors,
      headers: {
        'Authorization': "Bearer " + sharedPreferences.getString("token"),
        'Accept': 'application/json'
      },
    );
    var jsonData = json.decode(data.body);
    for (var u in jsonData["data"]) {
      Mentor user = Mentor(
        u["id"]!=null ? u["id"]: "",
        u["category"]!=null ? u["category"] : "",
        u["email"]!=null ? u["email"]: "",
        u["email_verified_at"] !=null ? u["email_verified_at"]: "",
        u["first_name"] !=null ? u["first_name"]: "",
        u["last_name"] != null ?u["last_name"]: "",
        u["other_name"] !=null ? u["other_name"]: "",
        u["country"] !=null ? u["country"]: "",
        u["industry"] !=null ? u["industry"]: "",
        u["gender"] !=null ? u["gender"]: "",
        u["bio_interest"] !=null ? u["bio_interest"]: "",
        u["phone"] !=null ?u["phone"]: "",
        u["state_of_origin"] !=null ? u["state_of_origin"]: "",
        u["fav_quote"] != null ? u["fav_quote"]: "",
        u["profile_image"] != null ? u["profile_image"] : "",
        u["terms"] !=null ? u["terms"]: "",
        u["check_status"] !=null ? u["check_status"]: "",
        u["current_job"] != null ? u["current_job"]: "",
        u["created_at"] !=null ? u["created_at"]: "",
        u["updated_at"]!=null ? u["updated_at"]: "",
        u["social_id"] !=null ? u["social_id"]: "",
        getFromList(u["employment"], 'company'),
        getFromList(u['employment'], 'position'),
        getFromList(u['education'], 'institution'),
        getFromList(u['education'], 'degree'),);

      users.add(user);
    }
    filteredData = users;
    return filteredData;
  }
  String getFromList(Map<String, dynamic> json, String key) {
    return json != null ? json[key] : "";
  }
  @override
  void dispose() {
    _scrollcontroller.dispose();
    super.dispose();
  }

  @override
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;

  loadMore() {
    print("edkwj");
  }
}

推荐答案

您需要检查,调用分页功能需要显示多少个项目,它可能是10,20,30,这是您的要求.在下面的示例中,我假设当时有20个项目,因此在您的API响应中,您需要检查是否正在获得20个项目,或者是否像下面这样.

You need to make check that , how many item you need to show for calling the pagination functionality , it could be 10,20,30 as your requirement. In my below example i am assuming the 20 items at time, So inside in your API response , you need to make check that you are getting the 20 items or not a time like below.

Future<List<Mentor>> _getUsers() async {
    sharedPreferences = await SharedPreferences.getInstance();
    var data = await http.get(
      NetworkUtils.host + AuthUtils.endPointMentors,
      headers: {
        'Authorization': "Bearer " + sharedPreferences.getString("token"),
        'Accept': 'application/json'
      },
    );
    var jsonData = json.decode(data.body);
    for (var u in jsonData["data"]) {
      Mentor user = Mentor(
        u["id"] != null ? u["id"] : "",
        u["category"] != null ? u["category"] : "",
        u["email"] != null ? u["email"] : "",
        u["email_verified_at"] != null ? u["email_verified_at"] : "",
        u["first_name"] != null ? u["first_name"] : "",
        u["last_name"] != null ? u["last_name"] : "",
        u["other_name"] != null ? u["other_name"] : "",
        u["country"] != null ? u["country"] : "",
        u["industry"] != null ? u["industry"] : "",
        u["gender"] != null ? u["gender"] : "",
        u["bio_interest"] != null ? u["bio_interest"] : "",
        u["phone"] != null ? u["phone"] : "",
        u["state_of_origin"] != null ? u["state_of_origin"] : "",
        u["fav_quote"] != null ? u["fav_quote"] : "",
        u["profile_image"] != null ? u["profile_image"] : "",
        u["terms"] != null ? u["terms"] : "",
        u["check_status"] != null ? u["check_status"] : "",
        u["current_job"] != null ? u["current_job"] : "",
        u["created_at"] != null ? u["created_at"] : "",
        u["updated_at"] != null ? u["updated_at"] : "",
        u["social_id"] != null ? u["social_id"] : "",
        getFromList(u["employment"], 'company'),
        getFromList(u['employment'], 'position'),
        getFromList(u['education'], 'institution'),
        getFromList(u['education'], 'degree'),);

      users.add(user);
    }
    filteredData = users;
    ////HERE ARE MAKING THE CHECK THE LOAD MORE FUNCTIONALITY
    if (users.length == 20) {
      isLoading = true;
    }
    else {
      isLoading = false
    }

    return filteredData;
  }

从上面的代码中,我们知道列表中是否有 20 个项目,或者没有 isLoading 布尔值.

From above code , we come to know that there is 20 items in the list or not with isLoading boolean.

下一步,我们需要检测listview;底部滚动表示当列表位于底部时,我们的加载更多功能应该起作用.

Next step we need to detect the listview;s bottom scroll means when list come at the bottom then our load more functionality should work.

为此 ScrollController 进行ListView底部的滚动检测.正如我创建的ScrollController列表器,并将其添加到Listview的contoller中以检测滚动.我已经创建了它的演示,请检查一次.第一次加载20个项目,然后我们将调用api加载更多项目.

For it ScrollController for the scrolling detection at the bottom for the ListView . As i have created the ScrollController listner and added to the Listview's contoller for the detection of the scroll. I have created the demo of it , please check it once. At first time it load the 20 items and then afet we will call api to load more items.

class _HomeScreen extends State<HomeScreen> {
  List dataList = new List<int>();
  bool isLoading = false;
  int pageCount = 1;
  ScrollController _scrollController;

  @override
  void initState() {
    super.initState();

    _scrollController = new ScrollController(initialScrollOffset: 5.0)
      ..addListener(_scrollListener);
  }

  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Gridview',
        debugShowCheckedModeBanner: false,
        theme: ThemeData(
          primaryColor: Colors.red,
          accentColor: Color(0xFFFEF9EB),
        ),
        home: Scaffold(
            appBar: new AppBar(),
            body: ListView.builder(
              shrinkWrap: true,
              controller: _scrollController,  //// YOU ARE ADDING THE CONTROLLER HERE TO ADD THE SCROLL LISTENER
              physics: ScrollPhysics(),
              itemCount: filteredData.length + 1,
              itemBuilder: (BuildContext context, int index) {
                if (index == filteredData.length) {
                  return CupertinoActivityIndicator();
                }
                return ListTile(

                );
              },
            )));
  }

  //// ADDING THE SCROLL LISTINER
  _scrollListener() {
    if (_scrollController.offset >=
        _scrollController.position.maxScrollExtent &&
        !_scrollController.position.outOfRange) {
      setState(() {
        print("comes to bottom $isLoading");
        isLoading = true;

        if (isLoading) {
          print("RUNNING LOAD MORE");

          pageCount = pageCount + 1;


          //// CALL YOUR API HERE FOR THE NEXT FUNCTIONALITY
         getUsers();

        }
      });
    }
  }



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


}

_scrollListener 内,您需要调用API以从分页中获取更多项目

Inside the _scrollListener you need to call API to get more item from the pagination

这篇关于延迟加载json列表视图颤动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 12:43