Kotlin编程开发Android运用程序(Volley+Gson依赖库)
Posted 新根
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin编程开发Android运用程序(Volley+Gson依赖库)相关的知识,希望对你有一定的参考价值。
Kotlin编程开发Android运用程序的相关介绍:
- Kotlin编程之AndroidStudio(包括3.0与2.x版本)配置与使用
- Kotlin编程开发Android运用程序(Volley+Gson依赖库)
- Kotlin编程之Kotlin Android Extensions(扩展插件)
- Kotlin编程之Glide v4 Generated API(Unresolved reference GlideApp)
- Kotlin Android Extensions+Android MVP项目(RxJava+Rerotfit+OkHttp+Glide)
- Anko Layout+MVP(Glide,Retrofit,OkHttp,RxJava)开发Android运用程序
在2017年Google IO大会中,宣布Kotlin 作为官方语言。跟着党走总没错的想法,开始满怀激情的开始Kotlin之旅。
历经一个下午的探索Kotlin编程后。昨晚按耐不住激动心情,边摸石头边过河的方式,花了一个晚上时间,撸了本项目代码。过完一段时间的后,Kotlin理解提高了,再回头看下本项目,肯定是左右嫌弃的,但是这毕竟是本人的第一个Kotlin项目。
1. AndroidStudio支持Kotlin的配置:
若是使用的androidStudio3.0以下,是默认不支持Kotlin语言的,需要自行配置。
Androistudio 3.0以上是自带支持Kotlin。
具体配置与使用,可以参考上篇讲解的文章, Kotlin编程之AndroidStudio(包括3.0与2.x版本)配置与使用。
2. 在Gralde中添加依赖库:
注意点:这里展示的项目已经支持Kotlin编写,在Project的Gralde 和Moudle的Gralde已经有Kotlin配置。
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:recyclerview-v7:25.3.1'
testCompile 'junit:junit:4.12'
compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
//官方框架
compile 'com.android.volley:volley:1.0.0'
compile 'com.google.code.gson:gson:2.8.0'
}
3. 根据需求开始用Kotlin编写:
使用AndroidStudio怎么创建Kotlin文件或者项目,请阅读 Kotlin编程之AndroidStudio使用。
项目需求:
- 在豆豌API中搜索导演的电影
- 在里列表中加载电影
实现:
- Kotlin语言编写
- Volley+Gson官方框架异步加载和解析
- RecyclerView中显示电影
根据分析,开始编写代码:
1. 编写Volley的单例操作类:
object
关键字声明单例类lateinit
关键字声明声明一个非空变量,好处不需要设置初始值。lazy()
延迟属性,同步的产生一个单个对象。Val
关键字声明一个只读对象,Var
关键字声明一个可写对象。注意点: 创建对象不需要使用Java中
new
关键字。
/***
* object 用于单例模式
*
* object声明对象名后,通过对象名来访问,但是不能使用 = 右边赋值。
*
*/
object VolleySingletion{
/**
* lateinit 声明一个非空变量,且不需要设置初始值。
*/
private lateinit var context:Context
/**
* 这里使用 延迟属性(lazy properties):首次访问时计算结果,以后再次访问时候,将拷贝第一次记录的结果。
*
*
* 使用形式: var p: String by lazy { }
*
* lazy()返回一个lazy<T> 的 T 对象.
*
* 注意点: lazy属性的计算结果的过程是同步锁的(synchronized)。
*
* 作用: 单例对象
*/
val requestQueque :RequestQueue by lazy {
Volley.newRequestQueue(context)
}
val imageLoader :ImageLoader by lazy {
// 不需要调用 new 关键字才创建对象
ImageLoader(requestQueque,LruBtimapCache() )
}
fun initConfi(context:Context){
this.context =context.applicationContext
}
}
2. 编写ImageLoader需要用到的LruCache:
一个类继承父类和实现接口的方式 :
class 类名 :超类名(),接口名
LruBitmapCache主构造函数中,指定参数类型为Int,同时也指定一个默认值。
LruBitmapCache带有主构造函数,因此超类(这里是LruCache)必须在主构造函数中初始化。
Companion
关键字,修饰伴生对象。伴生对象类名,可以省略
/***
* LruBitmapCache主构造函数中,指定一个默认值。
*
* LruBitmapCache带有主构造函数,因此超类(这里是LruCache)必须在主构造函数中初始化。
*
*/
class LruBtimapCache (size: Int= defaultSize ): LruCache<String,Bitmap>(size) ,ImageLoader.ImageCache{
override fun getBitmap(url: String): Bitmap ?{
return get(url)
}
override fun putBitmap(url: String?, bitmap: Bitmap?) {
put(url,bitmap)
}
override fun sizeOf(key: String, value: Bitmap): Int {
return value.rowBytes*value.height/1024
}
/**
* 使用Companion关键字,伴生对象类名,可以省略。
*/
companion object{
/**
* val声明一个只读的变量
*
*/
val defaultSize: Int get() {
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
val cacheSize = maxMemory / 8
return cacheSize
}
}
}
3. 编写自定义的Application:
override
关键字用于复写超类或者接口中存在的方法
class BaseApplication :Application(){
override fun onCreate() {
super.onCreate()
//初始化Volley配置
VolleySingletion.initConfi(this)
}
}
在AndroidManifest.xml中配置:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.xingen.kotlindemo">
//联网权限
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".BaseApplication" //使用自定义的Application
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
4. 编写实体类
这里也存在一个点疑问:data
关键字修饰数据对象,但是必须带有主构造器函数。
因此,这里并未使用data修饰数据对象。
- 类型后面带有
?
是允许该对象为空
//https://api.douban.com/v2/movie/search?q=张艺谋,返回的数据结构。
class MovieList {
lateinit var subjects: List<Movie>
class Movie {
lateinit var year: String
var title: String? = null
var id: String? = null
lateinit var images: Images
class Images {
var small: String?= null
var large: String? = null
}
}
}
5. 编写RecyclerView的Adapter:
this
引用是最内层的对象,若是引用外层对象,需要使用this@类名
除开下文的初始化全局变量方式外,还可以在主构造函数中声明类型的方式
class ImageListAdapter(movieList: List<MovieList.Movie>) : RecyclerView.Adapter<ImageListAdapter.ViewHolder>() {
/**
* 指定一个全局的变量,从主构造函数中获取到参数,进行初始化
*/
var list = movieList
/**
* 加载的数量
*/
override fun getItemCount(): Int {
return list.size
}
/**
* 创建 ViewHolder
*/
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
var rootView = View.inflate(parent.context, R.layout.item_imagelist_layout, null)
return ViewHolder(rootView)
}
/**
* 绑定ViewHolder,进行加载数据
*/
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
holder.loadImage(position)
}
/**
* inner修饰内部类
*/
inner class ViewHolder(var rootView: View) : RecyclerView.ViewHolder(rootView) {
/**
* 构建一个加载数据的方法,参数为RecyclerView中的当前的位置
*/
fun loadImage(position: Int) {
var iv = rootView.findViewById(R.id.imagelist_iv) as NetworkImageView
var title = rootView.findViewById(R.id.imagelist_title) as TextView
/**
* this@类名的方式,拿到需要对应类的this指向。
*/
var adapter=this@ImageListAdapter
/**
* NetWorkImageView开始加载图片
*/
iv.setDefaultImageResId(R.mipmap.ic_launcher)
iv.setErrorImageResId(R.mipmap.ic_launcher)
iv.setImageUrl(adapter.list[position].images.large,VolleySingletion.imageLoader)
title.text=adapter.list[position].title
}
}
}
6. 编写MainActivity,进行发送请求和更新数据:
/**
* 一个类继承父类和实现接口的方式; class 类名 :超类名(),接口名
*/
class MainActivity : AppCompatActivity() {
/**
* override用于覆写继承父类或者实现接口中方法。
*
* fun 用于标识方法
*
* 参数形式: 参数名: 类型
*
* ? 是用于指定可以为空对象
*
*/
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
shwoDiaglog()
this.initView()
this.sendRequest()
}
lateinit var recyclerView: RecyclerView
/**
* 初始化控件
*/
fun initView() {
recyclerView = this.findViewById(R.id.main_recycler_view) as RecyclerView
}
/**
* 将网络数据加载到RecyclerView
*/
fun loadData(movieList: List<MovieList.Movie>) {
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = ImageListAdapter(movieList)
}
lateinit var progressDialog: ProgressDialog
/**
* 显示dialog
*/
fun shwoDiaglog() {
progressDialog = ProgressDialog(this)
progressDialog.show()
}
/**
* 取消dialog
*/
fun cancleDialog() {
progressDialog.dismiss()
}
/**
* Toast显示
*/
fun loadToast(content: String?) {
Toast.makeText(this, content, Toast.LENGTH_SHORT).show()
}
/**
* 发送请求,这里使用douban公开的搜索电影的API
*/
fun sendRequest() {
var url = "https://api.douban.com/v2/movie/search?q=张艺谋"
val request = StringRequest(url, Response.Listener<String> {
response ->
//请求成功,Gson解析json
var movilist = Gson().fromJson(response, MovieList::class.java)
loadData(movilist.subjects)
cancleDialog()
}, Response.ErrorListener {
error ->
loadToast(error.message)
cancleDialog()
})
// 单利类中对象的引用
VolleySingletion.requestQueque.add(request)
}
}
activity_main.xml代码如下:
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.xingen.kotlindemo.MainActivity">
<android.support.v7.widget.RecyclerView
android:id="@+id/main_recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView>
</android.support.constraint.ConstraintLayout>
item_imagelist_layout.xml代码如下:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal" android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp">
<com.android.volley.toolbox.NetworkImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:scaleType="centerCrop"
android:id="@+id/imagelist_iv"/>
<TextView
android:layout_width="wrap_content"
android:id="@+id/imagelist_title"
android:layout_gravity="center_vertical"
android:layout_marginLeft="20dp"
android:layout_height="wrap_content" />
</LinearLayout>
项目的最终目录结构,如下:
项目运行结果:
项目代码:https://github.com/13767004362/KotlinVolleyDemo
资源参考:
AndroidStudio的配置:http://blog.csdn.net/hexingen/article/details/72621795
Kotlin中英文比对的官网:https://www.kotlincn.net/
Kotlin中文:https://huanglizhuo.gitbooks.io/kotlin-in-chinese/content/
Kotlin中文翻译组:https://github.com/huanglizhuo/kotlin-in-chinese
以上是关于Kotlin编程开发Android运用程序(Volley+Gson依赖库)的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 编程语言成为其 Android 应用程序开发人员的首选语言
Kotlin-First !谷歌正式宣布 Kotlin 成为 Android 开发首选编程语言!
Java vs Kotlin 应该使用Kotlin进行Android开发吗