Xamarin.Forms JSON 对象到 Listview
Posted
技术标签:
【中文标题】Xamarin.Forms JSON 对象到 Listview【英文标题】:Xamarin.Forms JSON object into Listview 【发布时间】:2015-05-03 23:48:38 【问题描述】:我正在尝试解析此 JSON 对象并将其绑定到 Xamarin.Forms 中的 ListView。
我完全不知道如何处理它,因为我对 Xamarin Forms 完全陌生。
有更简单的方法吗?
我返回的 JSON 对象
[
"id": 1,
"name": "Leanne Graham",
"username": "Bret"
,
"id": 2,
"name": "Ervin Howell",
"username": "Antonette"
]
这是我处理 REST json 响应的代码
public class RestClient
public RestClient ()
public async Task<User[]> GetUsersAsync ()
var client = new System.Net.Http.HttpClient ();
client.BaseAddress = new Uri("http://jsonplaceholder.typicode.com");
var response = client.GetAsync("users");
var usersJson = response.Result.Content.ReadAsStringAsync().Result;
var rootobject = JsonConvert.DeserializeObject<Rootobject>(usersJson);
return rootobject.Users;
Users.cs
public class Rootobject
public User[] Users get; set;
public class User
public string id get; set;
public string username get; set;
ListView Form Code
var sv = new RestClient ();
var es = sv.GetUsersAsync();
Xamarin.Forms.Device.BeginInvokeOnMainThread (() =>
Debug.WriteLine("Found " + es.Result.Length + " users");
listView.ItemsSource = es.Result;
);
XAML
public ListViewPage ()
Title = "Users";
var sv = new RestClient ();
var es = sv.GetUsersAsync();
Xamarin.Forms.Device.BeginInvokeOnMainThread (() =>
Debug.WriteLine("Found " + es.Result.Length + " users");
listView.ItemsSource = es.Result;
);
listView = new ListView ();
listView.ItemTemplate = new DataTemplate(typeof(TextCell));
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "username");
listView.ItemTemplate = new DataTemplate(typeof(ItemCell));
Content = new StackLayout
Children =
listView
;
【问题讨论】:
【参考方案1】:您的异步调用不正确。如果您必须在构造函数中执行此操作(这不是执行此操作的最佳位置),您可能希望使用 ContinueWith,因为不应使用 using Task.Result。此外,由于 Result 是一个阻塞调用,因此您在构造列表视图之前分配了项目源,并且您得到了一个空引用异常。
试试这个:
public class ListViewPage : ContentPage
private readonly ListView listView;
public ListViewPage()
Title = "Users";
this.listView = new ListView ItemTemplate = new DataTemplate(typeof (TextCell));
this.listView.ItemTemplate.SetBinding(TextCell.TextProperty, "username");
Content = new StackLayout
Children = this.listView
;
var sv = new RestClient();
var es = sv.GetUsersAsync().ContinueWith(t =>
if (t.Status == TaskStatus.RanToCompletion)
Debug.WriteLine("Found 0 users.", t.Result.Length);
Device.BeginInvokeOnMainThread(() => this.listView.ItemsSource = t.Result);
);
一个更好的选择(但也不是完美的)是覆盖出现的方法并且标记是异步的。这样您就可以在异步 REST 调用方法上使用 await。请注意,除非添加其他代码,否则每次视图出现时都会调用它。
protected override async void OnAppearing()
base.OnAppearing();
try
var sv = new RestClient();
// activate/show spinner here
this.listView.ItemsSource = await sv.GetUsersAsync();
// inactivate/hide spinner here
catch (Exception exception)
this.DisplayAlert("Error", exception.Message, "OK");
【讨论】:
我应该如何实现一个进度微调器(思考微调器),以便视图快速加载并仅显示微调器,直到它加载 JSON? 我编辑了 OnAppearing 重载以显示您将显示/隐藏微调器的位置。这是指标的 API:iosapi.xamarin.com/?link=T%3aXamarin.Forms.ActivityIndicator 只是一个小修正,您可能希望在 try-catch 的 finally 块中停用微调器,以便在出现错误时将其隐藏。 仅供参考,我在一个页面上有 2 个异步 API 调用(差异域)。我认为快速调用可以在构造函数中的 Device.BeginInvokeOnMainThread 中运行,而在 OnAppearing 中可以在笨重的调用中运行。我必须将两者都放入 OnAppearing 以使页面始终如一地工作。有趣的是,在修复之前,listView 没有在每个页面加载时显示数据的模式。干杯@SKall。【参考方案2】:看起来您没有在等待 sv.GetUsersAsync,我不确定 Result 是否会在不等待操作完成的情况下包含所有数据。
虽然可以使用任何集合和任何对象作为列表视图的数据源,但最好使用 ObservableCollection 并使您的 User 类实现 INotifyPropertyChanged(查看 Fody.PropertyChanged nuget 包)。
你能和我们分享一下 xaml 吗?
编辑 1
你定义了你的 ItemTemplate 两次。
listView.ItemTemplate = new DataTemplate(typeof(TextCell)); //first definition
listView.ItemTemplate.SetBinding(TextCell.TextProperty, "username");
listView.ItemTemplate = new DataTemplate(typeof(ItemCell)); //second definition, remove it
另外,最好将 MVVM 与 Xamarin.Forms 一起使用,并将数据加载到视图模型中,而不是在页面的构造函数中。 Here 是关于 mvvm 和 Xamarin.Forms 中数据加载的好文章。
编辑 2
你为什么用这种奇怪的方式使用 async/await?与其读取 Task.Result 属性,不如使用 async/await 对。 Example.
【讨论】:
现已添加 XAML。但我很想知道是否有更简单的方法来加载 JSON 并将其绑定到我的 ListView 添加了关于异步/等待的评论。抱歉,这只是您的使用方式。 完全没有,我只是在网上找到了一个这样做的例子。以上是关于Xamarin.Forms JSON 对象到 Listview的主要内容,如果未能解决你的问题,请参考以下文章
无法反序列化当前 JSON 对象,xamarin.forms 中的错误
如何将json.net添加到Xamarin Forms,本地项目或PCL上?
调试器在解析 Rest API 响应 HttpClient、Xamarin Forms 时停止