简体   繁体   English

列表视图页面上的无限滚动

[英]Infinite Scroll on Listview page

I have a listview whose data is fetched from json on the server.我有一个列表视图,其数据是从服务器上的 json 获取的。 Code:代码:

ObservableCollection<QuizHome> quizhomedatasource = new ObservableCollection<QuizHome>();
private bool incall = false, endoflist = false;
int offset = 1, halaman = 1;
private void MainGrid_Loaded(object sender, RoutedEventArgs e)
        {
            quizhomedatasource.Clear();
            QuizList.ItemsSource = quizhomedatasource;
            ProgressQuiz(offset);
        }
private void QuizList_Loaded(object sender, RoutedEventArgs e)
        {
            ScrollViewer viewer = GetScrollViewer(this.QuizList);
            viewer.ViewChanged += Viewer_ViewChanged;
        }

        private void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
        {
            ScrollViewer view = (ScrollViewer)sender;
            double progress = view.VerticalOffset / view.ScrollableHeight;
            if (progress > 0.7 && !endoflist)
            {
                incall = true;
                while (offset < halaman)
                {
                    ProgressQuiz(++offset);
                }
            }
            else
            {
                incall = false;
            }
        }

        public static ScrollViewer GetScrollViewer(DependencyObject depObj)
        {
            if (depObj is ScrollViewer) return depObj as ScrollViewer;

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
            {
                var child = VisualTreeHelper.GetChild(depObj, i);
                var result = GetScrollViewer(child);
                if (result != null) return result;
            }
            return null;
        }
private async void ProgressQuiz(int offset)
        {
                        try
                        {
                                urlPath = "https://mhnkp2.com/school/api-v3/fetch/tryout_paket_perkelas";
                                var values = new List<KeyValuePair<string, string>>
                                {
                                    new KeyValuePair<string, string>("halaman", offset.ToString()),
                                    new KeyValuePair<string, string>("limit", "10"),
                                    new KeyValuePair<string, string>("kelas", "2")
                                };
                                var httpClient = new HttpClient(new HttpClientHandler());
                                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("SCH-API-KEY", "SCH_KEnaBiDeplebt");
                                httpClient.DefaultRequestHeaders.TryAddWithoutValidation("token", token.Token);
                                var response = await httpClient.PostAsync(urlPath, new FormUrlEncodedContent(values));
                                response.EnsureSuccessStatusCode();
                                string jsonText = await response.Content.ReadAsStringAsync();
                            try
                            {
                                JsonObject jsonObject = JsonObject.Parse(jsonText);
                                JsonObject groupObject1 = jsonObject.GetObject();                                        
                                double pages = groupObject1["total_page"].GetNumber();
                                    double page = groupObject1["current_page"].GetNumber();
                                    Buku file = new Buku();
                                    file.PageNo = Convert.ToInt32(page);
                                    file.Pages = Convert.ToInt32(pages);
                                    halaman = file.Pages;
                                    JsonArray jsonData1 = jsonObject["data"].GetArray();
                                    foreach (JsonValue groupValue1 in jsonData1)
                                    {
                                        JsonObject groupObject2 = groupValue1.GetObject();
                                        string title = groupObject2["judul"].GetString();

                                        QuizHome quiz = new QuizHome();
                                        quiz.Title = title;
                                        quizhomedatasource.Add(quiz);
                                    }
                                    if (quizhomedatasource.Count < 0)
                                    {
                                        QuizList.Visibility = Visibility.Collapsed;
                                        statusKosong.Visibility = Visibility.Visible;
                                    }
                                }
                            }

I have a problem that if the loaded page exceeds the number of pages, then "statuskosong" is displayed.我有一个问题,如果加载的页面超过页面数,则会显示“statuskosong”。 How can I prevent "statuskosong" from being displayed and data not being loaded again?如何防止显示“statuskosong”并且不再加载数据?

Note:笔记:

  • "statuskosong" is the text that will be displayed when data = 0 “statuskosong”是数据= 0时将显示的文本

How can I prevent "statuskosong" from being displayed and data not being loaded again?如何防止显示“statuskosong”并且不再加载数据?

You can set statusKosong.Visibility to Collapsed every time you call the ProgressQuiz method, and then display it when it detects that quizhomedatasource.Count is 0.可以在每次调用ProgressQuiz方法时设置statusKosong.VisibilityCollapsed ,然后在检测到quizhomedatasource.Count为0时显示。

By the way, your judgment condition at the end of the ProgressQuiz method is quizhomedatasource.Count < 0 , this will not happen, you can change it to quizhomedatasource.Count == 0对了,你在ProgressQuiz方法最后的判断条件是quizhomedatasource.Count < 0 ,不会出现这种情况,可以改成quizhomedatasource.Count == 0

Regarding avoiding repeated requests, we can add new judgment conditions in the Viewer_ViewChanged callback and set the return value of the ProgressQuiz method to Task :关于避免重复请求,我们可以在Viewer_ViewChanged回调中增加新的判断条件,将ProgressQuiz方法的返回值设置为Task

private async void Viewer_ViewChanged(object sender, ScrollViewerViewChangedEventArgs e)
{
     ScrollViewer view = (ScrollViewer)sender;
     double progress = view.VerticalOffset / view.ScrollableHeight;
     if (progress > 0.7 && !endoflist && !incall)
     {
         incall = true;
         while (offset < halaman)
         {
             await ProgressQuiz(++offset);
         }
     }
     else
     {
         incall = false;
     }
}

private async Task ProgressQuiz(int offset)
{
    //code
}

By judging the incall and waiting for the ProgressQuiz method to execute, repeated requests can be avoided.通过判断incall等待ProgressQuiz方法执行,可以避免重复请求。


From the code you provided, you are creating an incrementally loaded list.根据您提供的代码,您正在创建一个增量加载的列表。

Obtaining the ScrollViewer in ListView through VisualTreeHelper and attaching events is a workaround, but UWP provides another way to solve the incremental loading problem more elegantly (From Windows Community Toolkit):通过VisualTreeHelper获取ListView中的ScrollViewer并附加事件是一种变通方法,但UWP提供了另一种更优雅地解决增量加载问题的方法(来自Windows Community Toolkit):

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM