2017-05-18 6 views
0

私はXamarinとC#を使って基本的なAndroidアプリケーションを作成しています。 私は学習中です。C#のJsonファイルからリストビューを作成する

私がしようとしているのは、JSONファイルからいくつかのデータを抽出してListViewを読み込むことです。 私は、サーバーを呼び出すための非同期タスクとデータの解析と抽出のための非同期タスクの2つのメソッドを作成しました(http://mysafeinfo.com/api/data?list=englishmonarchs&format=json)。

私の問題は、このデータをリストビューに与える方法がわからないことです。

ありがとうございます。

namespace App4 
{ 
[Activity(Label = "App4", MainLauncher = true, Icon = "@drawable/icon")] 
public class MainActivity : Activity 
{ 
    //Declare a Cancellation Token Source 
    CancellationTokenSource cts; 

    Button startbutton; 
    Button stopbutton; 
    TextView textView0; 
    ListView listView; 

    protected override void OnCreate(Bundle bundle) 
    { 
     base.OnCreate(bundle); 
     SetContentView(Resource.Layout.Main); 

     startbutton = FindViewById<Button> 
      (Resource.Id.startbutton); 
     stopbutton = FindViewById<Button> 
      (Resource.Id.stopbutton); 
     textView0 = FindViewById<TextView> 
      (Resource.Id.textView0); 
     listView = FindViewById<ListView> 
      (Resource.Id.listView); 


     //BASIC ASYNC START TASK 
     // click the startbutton to start the process 
     startbutton.Click += async (sender, e) => 
     {     
      // Instantiate the CancellationTokenSource 
      cts = new CancellationTokenSource(); 

      try 
      { 
       // **** GET **** 
       await Task.Run(() => LoadDataAsync(cts.Token)); 

      } 
      catch (TaskCanceledException) 
      { 
       textView0.Text = " Download deleted "; 
      } 
      catch (Exception) 
      { 
       textView0.Text = "Generic Error"; 
      } 

      // ***Set the CancellationTokenSource to null when the download is complete. 
      cts = null; 
     }; 

     //STOP BUTTON 
     stopbutton.Click += (sender, e) => 
     { 
      if (cts != null) 
      { 
       cts.Cancel(); 
      } 
     }; 
    } 

    //THIS METHOD LOAD JSON DATA FROM AN URL AND RETURN A STRING 

    public static async Task<string> LoadDataAsync(CancellationToken ct) 
    { 
     // Call the server and take the file 
     var client = new HttpClient(); 
     client.MaxResponseContentBufferSize = 1024 * 1024; //read up to 1MB of data 

     await Task.Delay(250);//Delay the task for deleting purpose 

     var response = await client.GetAsync(new Uri("http://mysafeinfo.com/api/data?list=englishmonarchs&format=json"), ct); 
     var result = await response.Content.ReadAsStringAsync(); 

     return result; 

    } 

    //THIS METHOD GET THE JSON DATA FROM THE STRING 

    private static void GetData(string result) 
    { 

     // Parse the Json file. 
     JArray file = JArray.Parse(result); 

     foreach (var item in file.Children<JObject>()) 
     {    
      string name = (string)item.SelectToken("nm"); 
      string city = (string)item.SelectToken("cty"); 
      string house = (string)item.SelectToken("hse"); 
      string years = (string)item.SelectToken("yrs"); 
     } 
    } 

} 

}

+0

各データ要素(名前、都市など)のプロパティを持つドメインオブジェクトを作成し、GetDataメソッドでそれらのオブジェクトのリストを作成する必要があります。彼らはListAdapaterを使用してそのデータをListViewに送ります。 – Jason

答えて

1

あなたはいくつかのことを必要とし、それが簡単にできるようにあなたは、いくつか他の人が変更を提案します。

まず、APIから受け取るデータでエンティティ/クラスを作成します。あなたが望むようにそれを呼び出していますが、私はあなたが受信される各フィールドとパブリックプロパティを追加しました見ての通り、この例のために私はEnglishMonarch

public class EnglishMonarch 
{ 
    public string Name {get; set;} 

    public string City {get; set;} 

    public string House {get; set;} 

    public string Years {get; set;} 
} 

それを呼び出します。

このライブラリJson.netを使用することをお勧めします.Jsonデータを数行のコードでエンティティに解析することができます。 XSまたはVSからナゲットパッケージをインストールすることができます。

作成したばかりのクラスにいくつか変更を加える必要があります。いくつかのアノテーションを追加するので、json.netは各jsonフィールドをクラスプロパティにマップする方法を知っています。

public class EnglishMonarch 
{ 
    [JsonProperty("nm")] 
    public string Name { get; set; } 

    [JsonProperty("cty")] 
    public string City { get; set; } 

    [JsonProperty("hse")] 
    public string House { get; set; } 

    [JsonProperty("yrs")] 
    public string Years { get; set; } 
} 

今、あなたが応答を取得して解析することができ、それは次のようにjson.net使用:

public List<EnglishMonarch> GetData (string jsonData) 
{ 
    if (string.IsNullOrWhiteSpace (jsonData)) 
     return new List<EnglishMonarch>(); 

    return JsonConvert.DeserializeObject<List<EnglishMonarch>> (jsonData); 
} 

注:EnglishMonarchのはなぜリストを? APIから1つ以上のアイテムを受け取っているので、これはあなたのListViewを設定するために使用するリストです。

これで、そのデータをListViewに入れてみましょう。 Androidの場合、Adapterを作成する必要があります。これは、ListViewに表示するデータと表示するデータを示します。

あなたのアダプタは次のようになります。

public class EnglishMonarchAdapter : BaseAdapter<EnglishMonarch> 
{ 
    public List<EnglishMonarch> Items { get; set;} 

    private readonly Context context; 

    public EnglishMonarchAdapter (Context context, List<EnglishMonarch> items) 
    { 
     this.context = context; 

     Items = items ?? new List<EnglishMonarch>(); 
    } 

    public override EnglishMonarch this [int position] 
    { 
     get { return Items [position]; } 
    } 

    public override int Count 
    { 
     get { return Items.Count; } 
    } 

    public override long GetItemId (int position) 
    { 
     return position; 
    } 

    public override View GetView (int position, View convertView, ViewGroup parent) 
    { 
     var view = convertView ?? LayoutInflater.FromContext (context).Inflate (Resource.Layout.englishmonarch_item_layout, parent, false); 

     var item = Items [position]; 

     var tvName = view.FindViewById<TextView> (Resource.Id.tvName); 
     var tvHouse = view.FindViewById<TextView> (Resource.Id.tvHouse); 
     var tvYear = view.FindViewById<TextView> (Resource.Id.tvYears); 
     var tvCity = view.FindViewById<TextView> (Resource.Id.tvCity); 

     tvName.Text = item.Name; 
     tvHouse.Text = item.House; 
     tvYear.Text = item.Years; 
     tvCity.Text = item.City; 

     return view; 
    } 
} 

GetView方法は、リストビューアイテムのビュー(セル)を作成し、ビューのフィールドにデータをマッピングする責任を負うものです。

このアダプタを使用するには、ListViewのItemView/Cellとして使用されるレイアウト(XML)を作成する必要があります。私が作成したものは、非常に簡単であり、私はそれをenglishmonarch_item_layout

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:orientation="vertical" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <TextView 
     android:id="@+id/tvName" 
     android:textSize="16sp" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <TextView 
     android:id="@+id/tvCity" 
     android:textSize="14sp" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <TextView 
     android:id="@+id/tvHouse" 
     android:textSize="11sp" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

    <TextView 
     android:id="@+id/tvYears" 
     android:textSize="11sp" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 
</LinearLayout> 

という名前今、あなただけのすべてです、あなたのstartButtonクリックイベント

startbutton.Click += async (sender, e) => 
    {     
     // Instantiate the CancellationTokenSource 
     cts = new CancellationTokenSource(); 

     try 
     { 
      // **** GET **** 
      var jsonData = await LoadDataAsync(cts.Token); 

      // ** Parse data into your entity **** 
      var items = GetData(jsonData); 

      // **** Create your adapter passing the data ***** 
      listview.Adapter = new EnglishMonarchAdapter(this, items); 
     } 
     catch (TaskCanceledException) 
     { 
      textView0.Text = " Download deleted "; 
     } 
     catch (Exception) 
     { 
      textView0.Text = "Generic Error"; 
     } 

     // ***Set the CancellationTokenSource to null when the download is complete. 
     cts = null; 
    }; 

にいくつかの作品を接着する必要があります。それはうまくいくはずです!

注:Json.netのようないくつかの部分をスキップして、手動でデータを解析することができます。

+0

これは完全で驚異的な答えです。 ありがとうございました! –

+0

正しい答えをマーク@AngelaAmeruoso – CDrosos

関連する問題