iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 12
0
Software Development

Kotlin 30 天,通過每天一個小 demo 學習 Android 開發系列 第 12

Kotlin 開發第 12 天 GithubStars ( OkHttp + RecyclerView)

  • 分享至 

  • xImage
  •  

GithubStars
GithubStars 是一個通過 Github API 請求數據,並通過 RecycleView 顯示的小應用。

  • 提供一個輸入框,用來輸入 Gtihub 用戶的名稱。
  • 通過 Gtihub API 取得該用戶 Starred 項目(https://api.github.com/users/使用者名稱/starred)
  • 以列表的方式呈現(Custom layout)

Permissions

因為會用到網路所以要在 AndroidManifest 裡面加入許可。

<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 當中。

https://ithelp.ithome.com.tw/upload/images/20171215/20107329FdBLEjpjYW.png

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 世界裡很有名的網路框架,來一個簡單的例子:

        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

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 之後,我們要通過 Intent 將參數傳給 ProjectListActivity

val intent = Intent(this@MainActivity, ProjectListActivity::class.java)
val bundle = Bundle()
bundle.putParcelableArrayList("projects", projects)
intent.putExtras(bundle)
startActivity(intent)

在 ProjectListActivity 端接受的方法:

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。


參考


上一篇
Kotlin 開發第 11 天 Alarm ( DatePickerDialog + AlertDialog)
下一篇
Kotlin 開發第 13 天 LocalStorage(SharedPreferences)
系列文
Kotlin 30 天,通過每天一個小 demo 學習 Android 開發30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言