接上一篇: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
数据来源网址:易源数据 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中 改为了以下模式
@Nullable public 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)? = null fun 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" />