今天要來完成最後的部分,要依據選擇的景點來搜尋空汙情況並且將資料顯示在spinner下方,圖示會依據空汙情況來做改變。
在kotlin中使用spinner只要輸入元件名稱便能夠直接做使用了。
tour_spinner.adapter = spinnerList
adapter直接放入一個ArrayAdapter便能夠完成spinner的顯示,ArrayAdapter要放入的值如下,nameList便是先前取得的景點列表。
val spinnerList: ArrayAdapter<String> = ArrayAdapter(context!!, R.layout.spinner_item, nameList)
完成後來設定點擊事件,在onItemSelectedListener中有兩個方法能做判斷,分別是未選擇時與選擇時的情況。
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val spinnerList: ArrayAdapter<String> = ArrayAdapter(context!!, R.layout.spinner_item, nameList)
tour_spinner.adapter = spinnerList
tour_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener{
override fun onNothingSelected(parent: AdapterView<*>?) {
}
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
}
}
}
選擇完地點後還需要判斷距離來選擇最近檢測站數值。
//計算兩點距離
fun getDistance(latitudeA: Double, longitudeA: Double, latitudeB: Double, longitudeB: Double): Float {
val locationA = Location("point A")
val locationB = Location("point B")
//A點經、緯度
locationA.longitude = longitudeA
locationA.latitude = latitudeA
//B點經、緯度
locationB.longitude = longitudeB
locationB.latitude = latitudeB
val distance: Float = locationA.distanceTo(locationB)
return distance
}
後面還會有空氣資料需要處理。
class Air {
var site: String? = null
var county: String? = null
var pm25: String? = null
var dataCreationDate: String? = null
var itemUnit: String? = null
}
開頭的地方有多幾行宣告。
class SelectFragment : Fragment(), View.OnClickListener {
companion object
val TAG = SelectFragment::class.java.simpleName
//旅遊資料
private lateinit var tours: ArrayList<Tour>
private lateinit var tour: Tour
private lateinit var nameList: ArrayList<String>
//空氣資料
private lateinit var airs: ArrayList<Air>
private lateinit var air: Air
//最短距離
var minDistance = 0.0f
var minDistanceArea = ""
var minDistanceAir = ""
.....
最後在spinner的onItemSelected下新增判斷便能夠依據距離來顯示所要呈現的資料。
class SelectFragment : Fragment(), View.OnClickListener {
companion object
val TAG = SelectFragment::class.java.simpleName
//旅遊資料
private lateinit var tours: ArrayList<Tour>
private lateinit var tour: Tour
private lateinit var nameList: ArrayList<String>
//空氣資料
private lateinit var airs: ArrayList<Air>
private lateinit var air: Air
//最短距離
var minDistance = 0.0f
var minDistanceArea = ""
var minDistanceAir = ""
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
getAssetsStream()
return inflater.inflate(R.layout.fragment_select, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val spinnerList: ArrayAdapter<String> = ArrayAdapter(context!!, R.layout.spinner_item, nameList)
tour_spinner.adapter = spinnerList
tour_spinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
//選擇地點
if (position != 0) {
Log.e("選擇的地點 ", "tour name : ${tours[position - 1].name}")
//取得地點經緯度
val getLongitudeA: Double = tours[position - 1].eastL!!.toDouble()
val getLatitudeA: Double = tours[position - 1].northL!!.toDouble()
//取得最短距離檢測站空氣品質
for (i in 0 until airs.size) {
when {
airs[i].site.equals("西屯") -> {
val areaDis = getDistance(getLongitudeA, getLatitudeA, 120.616917, 24.162197)
Log.e("空汙 ", "air p : $areaDis")
Log.e("minDistance ", "air p : $minDistance")
if (minDistance == 0.0f) {
minDistance = areaDis
minDistanceArea = "西屯"
minDistanceAir = airs[i].pm25!!
} else if (minDistance > areaDis) {
minDistance = areaDis
minDistanceArea = "西屯"
minDistanceAir = airs[i].pm25!!
}
}
airs[i].site.equals("忠明") -> {
val areaDis = getDistance(getLongitudeA, getLatitudeA, 120.641092, 24.151958)
Log.e("空汙 ", "air p : $areaDis")
Log.e("minDistance ", "air p : $minDistance")
if (minDistance == 0.0f) {
minDistance = areaDis
minDistanceArea = "忠明"
minDistanceAir = airs[i].pm25!!
} else if (minDistance > areaDis) {
minDistance = areaDis
minDistanceArea = "忠明"
minDistanceAir = airs[i].pm25!!
}
}
airs[i].site.equals("大里") -> {
val areaDis = getDistance(getLongitudeA, getLatitudeA, 120.677689, 24.099611)
Log.e("空汙 ", "air p : $areaDis")
Log.e("minDistance ", "air p : $minDistance")
if (minDistance == 0.0f) {
minDistance = areaDis
minDistanceArea = "大里"
minDistanceAir = airs[i].pm25!!
} else if (minDistance > areaDis) {
minDistance = areaDis
minDistanceArea = "大里"
minDistanceAir = airs[i].pm25!!
}
}
airs[i].site.equals("沙鹿") -> {
val areaDis = getDistance(getLongitudeA, getLatitudeA, 120.568794, 24.225628)
Log.e("空汙 ", "air p : $areaDis")
Log.e("minDistance ", "air p : $minDistance")
if (minDistance == 0.0f) {
minDistance = areaDis
minDistanceArea = "沙鹿"
minDistanceAir = airs[i].pm25!!
} else if (minDistance > areaDis) {
minDistance = areaDis
minDistanceArea = "沙鹿"
minDistanceAir = airs[i].pm25!!
}
}
airs[i].site.equals("豐原") -> {
val areaDis = getDistance(getLongitudeA, getLatitudeA, 120.741711, 24.256586)
Log.e("空汙 ", "air p : $areaDis")
Log.e("minDistance ", "air p : $minDistance")
if (minDistance == 0.0f) {
minDistance = areaDis
minDistanceArea = "豐原"
minDistanceAir = airs[i].pm25!!
} else if (minDistance > areaDis) {
minDistance = areaDis
minDistanceArea = "豐原"
minDistanceAir = airs[i].pm25!!
}
}
}
}
air_quality_tv.text = "品質狀況:$minDistanceAir"
//切換圖示
when {
minDistanceAir.toDouble() <= 15.4 -> {
air_quality_img.setBackgroundResource(R.drawable.park256)
air_quality_tv.setTextColor(Color.parseColor("#215968"))
}
minDistanceAir.toDouble() <= 35.4 -> {
air_quality_img.setBackgroundResource(R.drawable.farm)
air_quality_tv.setTextColor(Color.parseColor("#6A6822"))
}
minDistanceAir.toDouble() <= 54.4 -> {
air_quality_img.setBackgroundResource(R.drawable.canyon)
air_quality_tv.setTextColor(Color.parseColor("#8B5403"))
}
minDistanceAir.toDouble() <= 150.4 -> {
air_quality_img.setBackgroundResource(R.drawable.desert)
air_quality_tv.setTextColor(Color.parseColor("#8D2B2B"))
}
minDistanceAir.toDouble() <= 250.4 -> {
air_quality_img.setBackgroundResource(R.drawable.volcano)
air_quality_tv.setTextColor(Color.parseColor("#66265D"))
}
else -> {
air_quality_img.setBackgroundResource(R.drawable.danger)
air_quality_tv.setTextColor(Color.parseColor("#6A2222"))
}
}
}
//清除資料
minDistance = 0.0f
minDistanceArea = ""
minDistanceAir = ""
}
override fun onNothingSelected(parent: AdapterView<*>) {
}
}
}
//計算兩點距離
fun getDistance(latitudeA: Double, longitudeA: Double, latitudeB: Double, longitudeB: Double): Float {
val locationA = Location("point A")
val locationB = Location("point B")
//A點經、緯度
locationA.longitude = longitudeA
locationA.latitude = latitudeA
//B點經、緯度
locationB.longitude = longitudeB
locationB.latitude = latitudeB
val distance: Float = locationA.distanceTo(locationB)
return distance
}
//取得xml資料
fun getAssetsStream() {
try {
val tourData: InputStream = activity!!.assets.open("tour.xml")
val xmlPullParser = Xml.newPullParser()
tour = Tour()
tours = ArrayList()
nameList = ArrayList()
nameList.add("請選擇旅遊地點")
//xml解析器
xmlPullParser.setInput(tourData, "utf-8")
//取得xml節點
var eventType = xmlPullParser.eventType
//讀取xml資料
while (eventType != XmlPullParser.END_DOCUMENT) {
when (eventType) {
//開始讀檔案
XmlPullParser.START_DOCUMENT -> tours
//xml找到的節點儲存到list
XmlPullParser.START_TAG -> if (xmlPullParser.name == "RECORD") {
//節點-名稱
} else if (xmlPullParser.name == "名稱") {
val name = xmlPullParser.nextText()
tour.name = name
nameList.add(name)
//Log.e("tour name", "tour name: ${tour.name}")
//節點-區域
} else if (xmlPullParser.name == "鄉鎮市區") {
val area = xmlPullParser.nextText()
tour.area = area
//Log.e("tour area", "tour area: ${tour.area}")
//節點-地址
} else if (xmlPullParser.name == "地址") {
val addr = xmlPullParser.nextText()
tour.addr = addr
//Log.e("tour name", "tour name: ${tour.addr}")
//節點-經度
} else if (xmlPullParser.name == "東經") {
val eastL = xmlPullParser.nextText()
tour.eastL = eastL
//Log.e("tour name", "tour name: ${tour.eastL}")
//節點-緯度
} else if (xmlPullParser.name == "北緯") {
val northL = xmlPullParser.nextText()
tour.northL = northL
//Log.e("tour name", "tour name: ${tour.northL}")
}
//節點結束
XmlPullParser.END_TAG -> if (xmlPullParser.name == "RECORD") {
tours.add(tour)
tour = Tour()
}
}
//下一個xml節點
eventType = xmlPullParser.next()
}
tourData.close()
} catch (e: Exception) {
e.printStackTrace()
}
//輸出內容
for (i in 0 until tours.size) {
Log.e("tour ", "tour $i xml : ${tours[i].name}")
}
}
override fun onClick(view: View?) {
}
}
這個部分完全使用本地資料,所以無法改變檢測站數據,有機會的話可能會使用retrofit來直接使用api取得所需資料來做判斷,這個部分就先告一段了。