首页 > 代码库 > Kotlin编程开发Android运用程序(Volley+Gson依赖库)
Kotlin编程开发Android运用程序(Volley+Gson依赖库)
在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依赖库)