GithubStars 是一個通過 Github API 請求數據,並通過 RecycleView 顯示的小應用。
- 提供一個輸入框,用來輸入 Gtihub 用戶的名稱。
- 通過 Gtihub API 取得該用戶 Starred 項目(https://api.github.com/users/使用者名稱/starred)
- 以列表的方式呈現(Custom layout)
Permissions
因為會用到網路所以要在 AndroidManifest 裡面加入許可。
1 |
<uses-permission android:name="android.permission.INTERNET"/> |
ProjectModel
我們在 「Kotlin 開發第 6 天 ImageList (RecyclerView)」已經有嘗試使用 data class 來建立 model了。
但因為 Android 開發過程會通過 intent 來進行 Activity 之間的傳值,
而其中一個將 Object 作為參數傳值的方法是讓 Object 實現 Parcelable 協定所定義的方法。
可以直接在 class name 上面點 option + enter,IDE 會幫我們直接將方法加入到 code 當中。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
data class ProjectModel(val projectName:String, val description:String, var avatarURL:String, var starCount:Int, var forkCount:Int, var username:String) : Parcelable { constructor(parcel: Parcel) : this( parcel.readString(), parcel.readString(), parcel.readString(), parcel.readInt(), parcel.readInt(), parcel.readString()) { } override fun writeToParcel(parcel: Parcel, flags: Int) { parcel.writeString(projectName) parcel.writeString(description) parcel.writeString(avatarURL) parcel.writeInt(starCount) parcel.writeInt(forkCount) parcel.writeString(username) } override fun describeContents(): Int { return 0 } companion object CREATOR : Parcelable.Creator<ProjectModel> { override fun createFromParcel(parcel: Parcel): ProjectModel { return ProjectModel(parcel) } override fun newArray(size: Int): Array<ProjectModel?> { return arrayOfNulls(size) } } } |
OkHttp
這是 Android 世界裡很有名的網路框架,來一個簡單的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
val client = OkHttpClient() val request = Request.Builder() .url("https://api.github.com/users/$username/starred") .build() client.newCall(request).enqueue(object: Callback{ override fun onFailure(call: Call?, e: IOException?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } override fun onResponse(call: Call?, response: Response?) { TODO("not implemented") //To change body of created functions use File | Settings | File Templates. } }) |
JSONObject/JSONArray
通過 http request 之後也一樣需要做 JSON 解析,這裡我們用 JSONObject / JSONArray
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
override fun onResponse(call: Call?, response: Response?) { val responseData = response?.body()?.string() val json = JSONArray(responseData) val projects: ArrayList<ProjectModel> = ArrayList() for(i in 0..(json.length() - 1)){ val item = json.getJSONObject(i) val owner = item.getJSONObject("owner") val ownerName = owner.get("login").toString() val avatarURL = owner.get("avatar_url").toString() val projectName = item.get("name").toString() val description = item.get("description").toString() val starCount = item.get("stargazers_count").toString().toInt() val forkCount = item.get("forks_count").toString().toInt() val project = ProjectModel(projectName, description, avatarURL, starCount, forkCount, ownerName) projects.add(project) } } |
Intent & Parcelable
把 JSON 解析成 ArrayList<ProjectModel> 之後,我們要通過 Intent 將參數傳給 ProjectListActivity
1 2 3 4 5 |
val intent = Intent(this@MainActivity, ProjectListActivity::class.java) val bundle = Bundle() bundle.putParcelableArrayList("projects", projects) intent.putExtras(bundle) startActivity(intent) |
在 ProjectListActivity 端接受的方法:
1 2 3 |
val projects: ArrayList<ProjectModel> = intent.extras.getParcelableArrayList("projects") val adapter = ProjectListAdapter(projects) projectListRecyclerView.adapter = adapter |
筆記
- 問題:MutableList 和 ArrayList 的區別在哪裏?
- 問題:var/val MutableList ,前綴是 var 或 val 和後面是 MutableList 或 List 的影響?
- 問題:有沒有類似 SwiftyJSON 的 JSON 解析工具?可以方便的設定初始值,如 empty String
- 問題:本來想要通過 searchButton.isEnable 來防止重複發送,但發現如果不在 UI 線程操作,會引起 crash。
不像是 iOS 開發,即使改變 UI 不是在主線程中,系統也會在主線程有空的時候來更新 UI,而不是直接 crash。
參考
- Github – okhttp
- 可以到 Github 上看對應的 Source Code
給剛好找到這篇文章的人:
解析 json 也可以用 google 出的 gson
https://github.com/google/gson
感謝 👍