Android Kotlin(二)—— Kotlin与Retrofit进行网络请求RecyclerView展示图片列表

来源:互联网 发布:名片设计软件哪个好 编辑:程序博客网 时间:2024/06/07 04:55

接上一篇:Android Kotlin(一)—— Kotlin 入门与 HttpURLConnection 网络请求

一.获取插件和框架

1.摒弃findViewById 

apply plugin: 'kotlin-android-extensions'

2.Retrofit相关获取

compile 'com.squareup.retrofit2:retrofit:2.3.0'compile 'com.squareup.retrofit2:converter-gson:2.3.0'compile 'com.squareup.retrofit2:converter-scalars:2.3.0'compile 'com.squareup.okhttp3:logging-interceptor:3.7.0'compile 'com.google.code.gson:gson:2.8.0'

3.Glide 

mavenCentral()maven { url 'https://maven.google.com' }

compile 'com.github.bumptech.glide:glide:4.2.0'annotationProcessor 'com.github.bumptech.glide:compiler:4.2.0'

4.JsonToKotlinClass 插件:将json解析为kotlin 的 Bean类

获取方式:可直接在Studio中  File --> Settings --> Plugins --> Browse Repositories -->搜索 JsonToKotlinClass

使用方法:http://blog.csdn.net/wuseal/article/details/77508585

二.Retrofit

网络请求地址:http://route.showapi.com/197-1?showapi_appid=42684&showapi_sign=f6527e909abc4edea350ec8b9a9db0f5&num=10

数据来源网址:易源数据  https://www.showapi.com/

1.获取JSON 转换为Bean类

JSON数据:

{
    "showapi_res_code": 0,
    "showapi_res_error": "",
    "showapi_res_body": {
        "newslist": [{
            "title": "甜美女神 sugar小甜心CC 酥胸美臀大尺度比基尼巴厘岛写真",
            "picUrl": "http://m.xxxiao.com/wp-content/uploads/sites/3/2016/09/m.xxxiao.com_7f98c6da4ae2eaf1536b1d7d69e05157-682x1024.jpg",
            "description": "美女写真",
            "ctime": "2016-09-27 20:00",
            "url": "http://m.xxxiao.com/75780"
        }],
        "code": 200,
        "msg": "success"
    }
}

JsonToKotlinClass 插件转Bean类

data class ImageBean(        @SerializedName("showapi_res_code") var showapiResCode: Int,         @SerializedName("showapi_res_error") var showapiResError: String,        @SerializedName("showapi_res_body") var showapiResBody: ShowapiResBody)data class ShowapiResBody(        @SerializedName("newslist") var newslist: List<Newslist>,        @SerializedName("code") var code: Int,         @SerializedName("msg") var msg: String )data class Newslist(        @SerializedName("title") var title: String,         @SerializedName("picUrl") var picUrl: String,         @SerializedName("description") var description: String,         @SerializedName("ctime") var ctime: String,         @SerializedName("url") var url: String )

2.Post方式网络请求

API接口

interface PictureApi {    @POST("197-1")    @FormUrlEncoded    fun getPicture(@Field("showapi_appid") showapi_appid: String,                    @Field("showapi_sign") showapi_sign: String,                    @Field("num") num: Int) : Call<ImageBean>}

网络请求

class HttpManager {    var retrofit = Retrofit.Builder()            .baseUrl("http://route.showapi.com/")   //基地址            .addConverterFactory(GsonConverterFactory.create())            .build()    fun getPicture(num: Int, success: (ImageBean) -> Unit, fail: (String) -> Unit) {        var pictureApi: PictureApi = retrofit.create(PictureApi::class.java)        var call: Call<ImageBean> = pictureApi.getPicture("42684", "f6527e909abc4edea350ec8b9a9db0f5", num)        call.enqueue(object : Callback<ImageBean> {            override fun onResponse(call: Call<ImageBean>?, response: Response<ImageBean>) {                success(response.body()!!)            }            override fun onFailure(call: Call<ImageBean>?, t: Throwable?) {                fail(t.toString())            }        })    }}

在此处

success: (ImageBean) -> Unit  与 fail: (String) -> Unit 为回掉接口

在Kotlin中可以不用 再像Java中还需要重新创建接口,可以直接编写

success: (ImageBean) -> Unit 对应Java中的  void success(ImageBean imagebean)

fail: (String) -> Unit 对应Java中的 void fail(String str)

PictureApi::class.java 在Kotlin中 还需要Java类时 使用 ::.class.java 这种方式

三.RecyclerView 与 Adapter

class PictureAdapter(private var list: List<Newslist>) : RecyclerView.Adapter<PictureAdapter.MyViewHolder>() {        fun notifyDataChange(list: List<Newslist>) {       //更新适配器数据        this.list = list        notifyDataSetChanged()    }    override fun getItemCount(): Int {        return list.size    }    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {        var view = LayoutInflater.from(parent.context).inflate(R.layout.item_rcy_picture, parent, false)        return MyViewHolder(view)    }    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {        holder.textView.text = list[position].title //展示图片标题         Glide.with(holder.imageView)                //ImageView中展示图片                .load(list[position].picUrl)               .into(holder.imageView)    }    class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {        var textView = itemView.findViewById(R.id.TextView) as TextView        var imageView = itemView.findViewById(R.id.ImageView) as ImageView    }}

上面ViewHolder 是在sdk 25的情况下 findViewById 在 SDK 26中 改为了以下模式

@Nullablepublic final <T extends View> T findViewById(@IdRes int id) {    if (id == NO_ID) {        return null;    }    return findViewTraversal(id);}

对应写法

var textView = itemView.findViewById<TextView>(R.id.TextView)var imageView = itemView.findViewById<ImageView>(R.id.ImageView)

或者

var textView: TextView = itemView.findViewById(R.id.TextView)var imageView: ImageView = itemView.findViewById(R.id.ImageView)

四.Activity中使用

class TestActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_test)        var adapter = PictureAdapter(ArrayList()) //适配器,默认一个空的集合,等网络请求后更新数据         recyclerView.layoutManager = LinearLayoutManager(this)        recyclerView.adapter = adapter        button.setOnClickListener {            //按钮点击事件            HttpManager().getPicture(                    10, //网络请求 5条数据 num表示网络请求返回的数据数量                    { adapter.notifyDataChange(it.showapiResBody.newslist) }, //成功的回掉接口                    { Toast.makeText(this, it, Toast.LENGTH_SHORT).show() } //失败的回掉接口            )        }    }}

五.加上RecyclerView Item点击事件

在adapter中 

var mListener: ((pos: Int) -> Unit)? = nullfun setOnItemClickListener(listener: ((pos: Int) -> Unit)) {    mListener = listener}

holder.imageView.setOnClickListener {    mListener?.invoke(position)}

在Activity中  点击某个Item 得到点击的位置 并吐司

adapter.setOnItemClickListener {    Toast.makeText(this, it.toString(), Toast.LENGTH_SHORT).show()}

附上XML  

activity中

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/button"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="点击我吧" />    <android.support.v7.widget.RecyclerView        android:id="@+id/recyclerView"        android:layout_width="match_parent"        android:layout_height="match_parent" /></LinearLayout>

RecyclerView Item中

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="wrap_content"    android:orientation="vertical">    <TextView        android:id="@+id/TextView"        android:layout_width="match_parent"        android:layout_height="wrap_content" />    <ImageView        android:id="@+id/ImageView"        android:layout_width="wrap_content"        android:layout_height="180dp" /></LinearLayout>

别忘记网络请求权限

<uses-permission android:name="android.permission.INTERNET" />



阅读全文
2 0
原创粉丝点击