ListViewでタップされた都市のお天気情報を表示するだけです。
Livedoorさんのお天気情報を使用します。
表示xmlの作成
stringは適宜いい感じに
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<!-- 上-->
<ListView
android:id="@+id/lvCityList"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5" />
<!-- 下-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.5"
android:orientation="vertical">
<!-- タイトル-->
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="@string/tv_winfo_title"
android:gravity="center"
android:textSize="25dp" />
<!-- 中身-->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<!-- 都市名-->
<TextView
android:id="@+id/tvCityName"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="25dp" />
<!-- 天気テロップ-->
<TextView
android:id="@+id/tvWetherTelop"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="20sp" />
</LinearLayout>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<!-- 天気情報-->
<TextView
android:id="@+id/tvWetherDesc"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textSize="15sp" />
</ScrollView>
</LinearLayout>
</LinearLayout>
MainActivity.ktの編集
解説しながらやっていきたい
MainActivity.kt
package com.websarva.wings.android.asyncsample
import android.os.AsyncTask
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.AdapterView
import android.widget.ListView
import android.widget.SimpleAdapter
import android.widget.TextView
import org.json.JSONObject
import java.io.BufferedReader
import java.io.InputStream
import java.io.InputStreamReader
import java.net.HttpURLConnection
import java.net.URL
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
//❶SimpleAdapterを作成して、クリック処理の呼び出しまで
val lvCityList = findViewById<ListView>(R.id.lvCityList)
val cityList: MutableList<MutableMap<String,String>> = mutableListOf()
var city = mutableMapOf("name" to "大阪" , "id" to "270000") //このIDはAPI用
cityList.add(city)
city = mutableMapOf("name" to "神戸" , "id" to "280010") //このIDはAPI用
cityList.add(city)
val from = arrayOf("name")
val to = intArrayOf(android.R.id.text1)
val adapter = SimpleAdapter(applicationContext,cityList,android.R.layout.simple_expandable_list_item_1,from,to)
lvCityList.adapter = adapter
//タップしたときの処理
lvCityList.onItemClickListener = ListItemClickListener()
}
//*クリックでクリックした都市を表示
private inner class ListItemClickListener: AdapterView.OnItemClickListener{
override fun onItemClick(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
//タップされた都市名と都市IDを取得
val item = parent?.getItemAtPosition(position) as Map<String,String>
val cityName = item["name"]
val cityId = item["id"]
// 取得した都市をtvで表示するように登録
val tvCityName = findViewById<TextView>(R.id.tvCityName)
tvCityName.setText(cityName + "天気:")
//❷タップされたときにお天気情報取得の処理を呼び出す
val receiver = WeatherInfoReceiver()
//実行(★IDを渡す)
receiver.execute(cityId)
}
}
//*AsyncTaskを継承するメンバクラスを作成
private inner class WeatherInfoReceiver(): AsyncTask<String,String,String>() {
//バックグラウンド処理
override fun doInBackground(vararg params: String?): String {
val id = params[0]
val urlStr = "http://weather.livedoor.com/forecast/webservice/json/v1?city=${id}"
//❸接続処理
val url = URL(urlStr)
val con = url.openConnection() as HttpURLConnection
con.requestMethod = "GET"
con.connect()
val stream = con.inputStream
val result = is2String(stream)
con.disconnect()
stream.close()
//onPostExecuteへ渡す
return result
}
//❹解析
override fun onPostExecute(result: String?) {
//文字解析
val rootJSON = JSONObject(result)
//項目1つ抜き出す
val descriptionJSON = rootJSON.getJSONObject("description")
val desc = descriptionJSON.getString("text")
//配列ごと抜き出す
val forecasts = rootJSON.getJSONArray("forecasts")
//配列の一つ目のJSONオブジェクト
val forecastsNow = forecasts.getJSONObject(0)
val telop = forecastsNow.getString("telop")
//天気情報用文字列をセット
val tvWeatherTelop = findViewById<TextView>(R.id.tvWetherTelop)
val tvWeatherDesc = findViewById<TextView>(R.id.tvWetherDesc)
tvWeatherTelop.text = telop
tvWeatherDesc.text = desc
}
// 文字型変換 どこでもソース落ちてます!
private fun is2String(stream: InputStream): String {
val sb = StringBuilder()
val reader = BufferedReader(InputStreamReader(stream, "UTF-8"))
var line = reader.readLine()
while(line != null) {
sb.append(line)
line = reader.readLine()
}
reader.close()
return sb.toString()
}
}
}