質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

Q&A

解決済

1回答

5167閲覧

【Android Studio】Kotlinで2階層以上のJsonのパースをしたい

sawaIT

総合スコア21

JSON

JSON(JavaScript Object Notation)は軽量なデータ記述言語の1つである。構文はJavaScriptをベースとしていますが、JavaScriptに限定されたものではなく、様々なソフトウェアやプログラミング言語間におけるデータの受け渡しが行えるように設計されています。

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Android Studio

Android Studioは、 Google社によって開発された、 Androidのネイティブアプリケーション開発に特化した統合開発ツールです。

Kotlin

Kotlinは、ジェットブレインズ社のアンドリー・ブレスラフ、ドミトリー・ジェメロフが開発した、 静的型付けのオブジェクト指向プログラミング言語です。

0グッド

1クリップ

投稿2018/09/09 16:24

編集2018/09/10 00:24

前提・実現したいこと

APIで取得した配列をもとにrecyclerViewで表示したい。
okhttp3とmoshiでrequest及びパースしているが、以下のような状態です。
※foreachの中で行うと予想をしているのですが調べたらリストの操作方法が多くあって適切な処理の仕方が分からなくなりました。
取り急ぎ、moshiの挙動を確認したところです。

できればサンプルで複数改装のJsonと合わせてコードをご教示頂きたく存じます。
※分かりやすいサイトがあればそちらでも可能です

発生している問題・エラーメッセージ

パース可能(https://myjson.com/wrx6o)

{ "id": 1, "title": "ヤクルト山田哲人31号「いい形で」14戦ぶり1発", "link": "https://www.nikkansports.com/baseball/news/img/201809090000757-w500_0.jpg", "summary": "ヤクルト山田哲人内野手が、14試合ぶりの1発を放った。 1回2死、DeNA平良のスライダーを左翼席へ運んだ。8月24日DeNA戦以来となる31号先制ソロを「いい形で入ることができました。先制点がとれて良かったです」と振り返った。", "author": "nikkansports.com", "updated": "2018-09-09T18:36:28+09:00" }

パース不可(https://myjson.com/jqbbk)

{  { "1": { "id": 1, "title": "ヤクルト山田哲人31号「いい形で」14戦ぶり1発", "link": "https://www.nikkansports.com/baseball/news/img/201809090000757-w500_0.jpg", "summary": "ヤクルト山田哲人内野手が、14試合ぶりの1発を放った。 1回2死、DeNA平良のスライダーを左翼席へ運んだ。8月24日DeNA戦以来となる31号先制ソロを「いい形で入ることができました。先制点がとれて良かったです」と振り返った。", "author": "nikkansports.com", "updated": "2018-09-09T18:36:28+09:00" }, "2": { "id": 1, "title": "2", "link": "https://www.nikkansports.com/baseball/news/img/201809090000757-w500_0.jpg", "summary": "ヤクルト山田哲人内野手が、14試合ぶりの1発を放った。 1回2死、DeNA平良のスライダーを左翼席へ運んだ。8月24日DeNA戦以来となる31号先制ソロを「いい形で入ることができました。先制点がとれて良かったです」と振り返った。", "author": "nikkansports.com", "updated": "2018-09-09T18:36:28+09:00" }, "3": { "id": 1, "title": "ヤクルト3", "link": "https://www.nikkansports.com/baseball/news/img/201809090000757-w500_0.jpg", "summary": "ヤクルト山田哲人内野手が、14試合ぶりの1発を放った。 1回2死、DeNA平良のスライダーを左翼席へ運んだ。8月24日DeNA戦以来となる31号先制ソロを「いい形で入ることができました。先制点がとれて良かったです」と振り返った。", "author": "nikkansports.com", "updated": "2018-09-09T18:36:28+09:00" },略

該当のソースコード

kotlin

1package com.example.newsour.sportable 2 3import android.os.Bundle 4import android.support.v4.app.Fragment 5import android.view.ViewGroup 6import android.view.LayoutInflater 7import android.view.View 8import okhttp3.OkHttpClient 9import okhttp3.Request 10import android.os.AsyncTask 11import android.support.v7.widget.GridLayoutManager 12import android.support.v7.widget.RecyclerView 13import com.squareup.moshi.Moshi 14 15 16class NewsFragment : Fragment() { 17 override fun onCreate(savedInstanceState: Bundle?) { 18 super.onCreate(savedInstanceState) 19 val args = arguments 20 } 21 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { 22 val view = inflater.inflate(R.layout.news_fragment, container, false) 23 MyAsyncTask().execute() 24 return view 25 } 26 companion object { 27 fun newInstance(): NewsFragment { 28 val fragment = NewsFragment() 29 return fragment 30 } 31 } 32 33 inner class MyAsyncTask: AsyncTask<Void, Void, String>() { 34 35 override fun doInBackground(vararg p0: Void?): String { 36 return this.getHtml() 37 } 38 39 override fun onPostExecute(result: String) { 40 super.onPostExecute(result) 41 val recyclerView = view?.findViewById(R.id.RssListView) as RecyclerView 42 val adapter = RssListViewAdapter(createDataList(result), object : RssListViewAdapter.ListListener { 43 override fun onClickRow(tappedView: View, RssListData: RssListData) { 44 this.onClickRow(tappedView, RssListData) 45 } 46 }) 47 48 recyclerView.setHasFixedSize(true) 49 recyclerView.layoutManager = GridLayoutManager(activity, 2) 50 recyclerView.adapter = adapter 51 } 52 53 fun getHtml(): String { 54 val client = OkHttpClient() 55 val req = Request.Builder().url("https://api.myjson.com/bins/wrx6o").get().build() 56 val resp = client.newCall(req).execute() 57 58 return resp.body()!!.string() 59 } 60 } 61 fun createDataList(result:String): List<RssListData> { 62 val jsonText = result 63 val adapter = Moshi.Builder().build().adapter(Rss::class.java) 64 val rssList = adapter.fromJson(jsonText) 65 66 val dataList = mutableListOf<RssListData>() 67// rssList.forEach { 68 val data: RssListData = RssListData().also { 69 it.rssTitle = rssList!!.rssTitle 70 it.rssContributor = rssList!!.rssContributor 71 it.rssUrl = rssList!!.rssUrl 72 } 73 dataList.add(data) 74 //} 75 return dataList 76 } 77} 78
package com.example.newsour.sportable import com.squareup.moshi.Json data class Rss( @field:Json(name = "title") var rssTitle: String, @field:Json(name = "author") var rssContributor: String, @field:Json(name = "link") var rssUrl: String )

###メモ
あとで試す

// マップをキーと値のペアで回す
for ((key, value) in map) {
println("key=$key, value=$value")
}

補足情報(FW/ツールのバージョンなど)

Android Studio 3.1.4
Build #AI-173.4907809, built on July 24, 2018
JRE: 1.8.0_152-release-1024-b02 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

MoshiでJSONをパースする場合、JSONの構造に合わせたJsonAdapterを生成して渡すようにします。Moshi側がJSONの構造を勝手に判断して階層のあるデータを生成してくれるわけではありません。

問題のJSONの場合は、おそらく要素数不定のオブジェクト形式のようですから、Map<String, Rss>に対応したJsonAdapterを渡すようにすればよいでしょう。

kotlin

1val rssMapType = Types.newParameterizedType( 2 Map::class.java, 3 String::class.java, 4 Rss::class.java 5) 6val rssMapAdapter: JsonAdapter<Map<String, Rss>> = Moshi.Builder() 7 .build() 8 .adapter(rssMapType) 9 10val rssMap: Map<String, Rss>? = rssMapAdapter.fromJson(jsonText) 11 12// あとは適当にループして目的のデータに変換してください 13val dataList = rssMap?.map { (key, rss) -> 14 RssListData().also { 15 ... 16 } 17}

投稿2018/09/10 04:45

kakajika

総合スコア3131

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

sawaIT

2018/09/12 14:40

ありがとうございます!大変助かりました!今後ともよろしくお願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問