【发布时间】:2019-07-16 15:03:25
【问题描述】:
我正在使用 Xamarin 开发跨平台应用程序。数据源是一个 JSON 文件,其中包含一些单词及其押韵,如下所示。我必须从 JSON 文件中读取单词,为此我设计了一个模型类“WordRhyme.cs”。 。我的代码运行良好,但由于某些原因,我无法检索每个单词的押韵。过去三天我一直在努力寻找解决方案,但没有运气。当 Rhymes 返回一个列表时,我还尝试用嵌套在单词列表中的列表替换标签,但这不起作用(xaml 编码在下面添加)。还有一种方法可以只从 JSON 中选择几条记录,因为它可能有数百条记录,但我想显示一些。在谷歌搜索学习之前,我还没有在 Xamarin 中编程过。
json1.json
{
"words": [
{
"word": "coffee",
"syllables": 2,
"topic": "Food and drink",
"rhymes": [
{
"word": "toffee",
"score": 385,
"numSyllables": 2
},
{
"word": "naafi",
"score": 178,
"numSyllables": 2
},
{
"word": "tophi",
"score": 172,
"numSyllables": 2
},
{
"word": "sofie",
"score": 75,
"numSyllables": 2
},
{
"word": "yoffie",
"numSyllables": 2
}
]
},
{
"word": "Cat",
"syllables": 2,
"topic": "Animals",
"rhymes": [
{
"word": "Hat",
"score": 385,
"numSyllables": 2
},
{
"word": "Fat",
"score": 178,
"numSyllables": 2
},
{
"word": "Mat",
"score": 172,
"numSyllables": 2
},
{
"word": "coffey2",
"score": 152,
"numSyllables": 2
},
{
"word": "toffy2",
"score": 119,
"numSyllables": 2
} ]
}
]
}
WordRhyme.cs
using System;
using System.Collections.Generic;
using System.Text;
namespace JsonTest2.Models
{
public class Rhyme
{
public string word { get; set; }
public int score { get; set; }
public int numSyllables { get; set; }
}
public class Word
{
public string word { get; set; }
public int syllables { get; set; }
public string topic { get; set; }
public List<Rhyme> rhymes { get; set; }
}
public class WordRhymes
{
public List<Word> words { get; set; }
}
}
Page1.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="JsonTest2.Page1">
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Margin="30" Text="Rhyming Words JSON Parsing" FontSize="25" />
<ListView x:Name="listViewWords" Grid.Row="1" HorizontalOptions="FillAndExpand" Footer="" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding word}" HorizontalOptions="StartAndExpand" Grid.Row="0" TextColor="Blue" FontAttributes="Bold"/>
<Label Text="{Binding syllables}" HorizontalOptions="StartAndExpand" Grid.Row="1" TextColor="Orange" FontAttributes="Bold"/>
<Label Text="{Binding topic}" HorizontalOptions="StartAndExpand" Grid.Row="2" TextColor="Gray" FontAttributes="Bold"/>
<Label Text="{Binding rhymes.word}" Grid.Row="3" TextColor="Blue" FontAttributes="Bold"/>
<Label Text="{Binding rhymes.score}" Grid.Row="4" TextColor="Blue" FontAttributes="Bold"/>
<Label Text="{Binding rhymes.numSyllables}" Grid.Row="5" TextColor="Blue" FontAttributes="Bold"/>
<BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" Grid.Row="6" HorizontalOptions="FillAndExpand" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Page1.xaml.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using JsonTest2.Models;
using Newtonsoft.Json;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace JsonTest2
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
GetJsonData();
}
void GetJsonData()
{
string jsonFileName = "json1.json";
WordRhymes ObjWordList = new WordRhymes();
var assembly = typeof(Page1).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjWordList = JsonConvert.DeserializeObject<WordRhymes>(jsonString);
}
//Binding listview with json string
listViewWords.ItemsSource = ObjWordList.words;
}
}
}
嵌套 ListView Page2Json.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="JsonTest2.Page2Json">
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Margin="30" Text="Rhyming Words JSON Parsing" FontSize="25" />
<ListView x:Name="listViewWords" Grid.Row="1" HorizontalOptions="FillAndExpand" Footer="" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand" Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding word}" HorizontalOptions="StartAndExpand" Grid.Row="0" TextColor="Blue" FontAttributes="Bold"/>
<Label Text="{Binding syllables}" HorizontalOptions="StartAndExpand" Grid.Row="1" TextColor="Orange" FontAttributes="Bold"/>
<Label Text="{Binding topic}" HorizontalOptions="StartAndExpand" Grid.Row="2" TextColor="Gray" FontAttributes="Bold"/>
<ListView x:Name="listViewRhymes" HorizontalOptions="FillAndExpand" ItemsSource="{Binding listViewWords.rhymes}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid HorizontalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Text="{Binding rhymes.word}"></Label>
<Label Text="{Binding rhymes.score}"></Label>
<Label Text="{Binding rhymes.numSyllables}"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Label Text="{Binding rhymes.word}" HorizontalOptions="StartAndExpand" Grid.Row="2" TextColor="Gray" FontAttributes="Bold"/>
<BoxView HeightRequest="2" Margin="0,10,10,0" BackgroundColor="Gray" Grid.Row="3" HorizontalOptions="FillAndExpand" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<StackLayout Orientation="Horizontal">
<Button x:Name="nextButton" Text="Next" Clicked="NextButton_Clicked"></Button>
<Button x:Name="backButton" Text="Back" Clicked="BackButton_Clicked"></Button>
</StackLayout>
</Grid>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
【问题讨论】:
-
是解析 json(与 Xamarin 无关)还是显示它的问题?你需要先缩小范围。此外,嵌套 ListView 是一个可怕的想法。最后,您的外部 StackLayout 和 Grid 似乎真的没有任何用途。
-
@Jason 你能解释一下为什么解析 JSON 文件有问题吗?我设计的类具有正确数据类型的所有字段/属性。我猜 WordRhymes 和 Word 类被正确解析,因为它们能够检索数据。是的,我知道使用嵌套的 ListViews 不是一个好主意,但为了让我的代码正常工作,我已经尝试过了。
-
我没说是。我在问你。您的问题标题明确表示“解析嵌套的 json”,但问题的主体暗示 UI 存在问题。这是两个完全不同的东西。你需要弄清楚哪个是真正的问题。确定您的 json 是否正确反序列化到您的模型中应该是相当简单的。
-
@Jason,我认为这可能是两者都有问题,这就是我发布所有代码的原因。我会再次检查,谢谢您的帮助。
-
@Aisha 嗨,如果回答有帮助,记得标记它:)