如何用Kotlin实现一个简单的Activity
来源:互联网 发布:中科院学位论文数据库 编辑:程序博客网 时间:2024/05/29 05:01
最近,Google公司正式宣布在Studio支持Kotlin语言开发Andriod,并支持java文件直接转变为kt(kotlin)文件。在初步学习了Kotlin基本语法后,忍不住code一下,最开始是直接将项目中的java文件转变为kt文件,但发现很多地方还是会报错,需要手动修改, 很是麻烦,所以用Kotlin后面手写了一个demo。
首先,activity_main的xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.wl.activity.MainActivity"> <android.support.v7.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="match_parent" android:layout_height="match_parent" /></LinearLayout>准备用RecyclerView实现一个简单的GridLayoutManager布局,所以Activity代码:
package com.wl.activityimport android.os.Bundleimport android.support.v7.app.AppCompatActivityimport android.support.v7.widget.GridLayoutManagerimport android.support.v7.widget.RecyclerViewimport com.example.wl.mubanapplication.Rimport com.example.wl.mubanapplication.help_class.ContextHelperimport com.example.wl.mubanapplication.model.Urlimport com.example.wl.mubanapplication.ui.view.DividerItemDecorationimport com.wl.adapter.AdapterPopularLocationKotlinimport com.wl.model.SecondModelKotlin@Suppress("UNUSED_EXPRESSION")class MainActivity : AppCompatActivity() { private val MARGIN = 20 override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val recylerView = findViewById(R.id.recyclerView) as RecyclerView val layoutManager = GridLayoutManager(ContextHelper.getApplicationContext(), 2) val decoration = DividerItemDecoration(ContextHelper.getApplicationContext(), R.drawable.divider, R.color.transparent) decoration.setSize(MARGIN) decoration.setType(DividerItemDecoration.BORDER) recylerView.addItemDecoration(decoration) recylerView.layoutManager = layoutManager val mAdapter = AdapterPopularLocationKotlin(mContext = ContextHelper.getApplicationContext()) mAdapter.setData(getSecondModelsKotlin() as MutableList<SecondModelKotlin>) recylerView.adapter = mAdapter val list: MutableList<SecondModelKotlin>? = getNames() as MutableList<SecondModelKotlin>?//?允许非空,不加?的话,一直不为空 val datas: MutableList<SecondModelKotlin> = ArrayList() var model: SecondModelKotlin if (list != null) {// for (i in list.indices) {// model = list[i]// model.name = "Liszt" + i// datas.add(model)// } for (i in list) { model = i model.name = "Liszt" + list.indexOf(model) datas.add(model) } mAdapter.setData(datas) } else { mAdapter.setData(getSecondModelsKotlin() as MutableList<SecondModelKotlin>) } print(max(2,6)) } fun max(a: Int, b: Int) = if (a > b) a else b//fun 方法,如果a>b,return a ,else return b; fun getSecondModelsKotlin(): List<SecondModelKotlin> { val list = ArrayList<SecondModelKotlin>() val model1 = SecondModelKotlin() model1.text = "Hello 1" model1.avatarUrl = Url.IMAGE_URL_FRANCE_1 model1.name = "Marks 1" list.add(model1) val model2 = SecondModelKotlin() model2.text = "Hello 2" model2.avatarUrl = Url.IMAGE_URL_FRANCE_2 model2.name = "Marks 2" list.add(model2) val model3 = SecondModelKotlin() model3.text = "Hello 3" model3.avatarUrl = Url.IMAGE_URL_FRANCE_3 model3.name = "Marks 3" list.add(model3) val model4 = SecondModelKotlin() model4.text = "Hello 4" model4.avatarUrl = Url.IMAGE_URL_FRANCE_4 model4.name = "Marks 4" list.add(model4) val model5 = SecondModelKotlin() model5.text = "Hello 5" model5.avatarUrl = Url.IMAGE_URL_FRANCE_2 model5.name = "Marks 5" list.add(model5) val model6 = SecondModelKotlin() model6.text = "Hello 1" model6.avatarUrl = Url.IMAGE_URL_FRANCE_3 model6.name = "Marks 1" list.add(model6) val model7 = SecondModelKotlin() model7.text = "Hello 2" model7.avatarUrl = Url.IMAGE_URL_FRANCE_4 model7.name = "Marks 2" list.add(model7) val model8 = SecondModelKotlin() model8.text = "Hello 3" model8.avatarUrl = Url.IMAGE_URL_FRANCE_1 model8.name = "Marks 3" list.add(model8) val model9 = SecondModelKotlin() model9.text = "Hello 4" model9.avatarUrl = Url.IMAGE_URL_FRANCE_2 model9.name = "Marks 4" list.add(model9) val model10 = SecondModelKotlin() model10.text = "Hello 5" model10.avatarUrl = Url.IMAGE_URL_FRANCE_4 model10.name = "Marks 5" list.add(model10) return list } fun getNames(): List<SecondModelKotlin>? { var model: SecondModelKotlin val list = java.util.ArrayList<SecondModelKotlin>() for (i in 0..49) { model = SecondModelKotlin() model.name = "hello-" + i list.add(model) }// return list return null }}
这个Activity的代码有很多地方与java很相似,但有不同,有种似是而非的感觉,具体解释一下:
如MainActivity类名的定义,class MainActivity:AppCompatActivity(), 后面的AppCompatActivity()按java的理解应该是MainActivity需要继承的父类,kotlin中用“:”来表示继承关系;
val recylerView = findViewById(R.id.recyclerView) as RecyclerView这句代码,我们肯定知道是在初始化控件,通过findViewById这个方法。但是注意后面的“as RecyclerView”,我们知道java中,findViewById后,都需要做强制类型转换,而RecyclerView明显是这个View需要转换的类型,所以Kotlin
中用“as”来表示强制类型转换。这里还有一个值得一说的知识点是,Kotlin中变量都用val来定义,常量都用var。例:
val a:String = “Hello World”,val b:Int = 1,前一个定义了一个String类型的变量a,后一个定义了一个Int类型的变量b。
val layoutManager = GridLayoutManager(ContextHelper.getApplicationContext(), 2)
这里需要注意怎么获取对象,java中获取对象通常都是new 对象的构造函数,kotlin中直接通过调用对象的构造函数就可获取对象。
这几句我们大致会知道是初始化Adapter及数据,但最后一句,却让人有点难理解,初一看,类似java中的赋值代码,但实际上在Kotlin中却等同于java中的“recylerView.setAdapter(mAdapter)”,另外,Kotlin中不再使用java中List来收集数据, 而是使用MutableList替代。val mAdapter = AdapterPopularLocationKotlin(mContext = ContextHelper.getApplicationContext())mAdapter.setData(getSecondModelsKotlin() as MutableList<SecondModelKotlin>)recylerView.adapter = mAdapter
fun getNames(): List<SecondModelKotlin>? { var model: SecondModelKotlin val list = java.util.ArrayList<SecondModelKotlin>() for (i in 0..49) { model = SecondModelKotlin() model.name = "hello-" + i list.add(model) }// return list return null }这里主要要看的是Kotlin中的For循环语法。可以看出Kotlin的for循环较之Java的for循环更简洁,没有初始化条件,判断条件,及控制语句,直接就是 “i in 0..49”,我们大致可以猜出i表示遍历时候的索引,而"0..49",表示遍历的范围,所以“in”可以顾名思义,表示一个判断:当i还在0-49的范围之内(i 可以等于49),for循环继续,否则for循环停止。
val list: MutableList<SecondModelKotlin>? = getNames() as MutableList<SecondModelKotlin>?//?允许非空,不加?的话,一直不为空val datas: MutableList<SecondModelKotlin> = ArrayList()var model: SecondModelKotlinif (list != null) { for (i in list.indices) { model = list[i] model.name = "Liszt" + list.indexOf(model) datas.add(model) } mAdapter.setData(datas)} else { mAdapter.setData(getSecondModelsKotlin() as MutableList<SecondModelKotlin>)}
这段代码只要要看的Kotlin如何遍历一个含自定义对象的MutableList。“i in list.indices”,通过后面的“model = list[i]”可知,i表示索引,但是list.indices是什么意思?为了探究,我试着做了下面的一个for循环:
val list: MutableList<SecondModelKotlin>? = getNames() as MutableList<SecondModelKotlin>?//?允许非空,不加?的话,一直不为空val datas: MutableList<SecondModelKotlin> = ArrayList()var model: SecondModelKotlinif (list != null) { for (i in list) { model = i model.name = "Liszt" + list.indexOf(model) datas.add(model) } mAdapter.setData(datas)} else { mAdapter.setData(getSecondModelsKotlin() as MutableList<SecondModelKotlin>)}不难看出,i表示集合中的自定义对象,因此可知,indices表示获取的是当前的索引。
fun getNames(): List<SecondModelKotlin>? { var model: SecondModelKotlin val list = java.util.ArrayList<SecondModelKotlin>() for (i in 0..49) { model = SecondModelKotlin() model.name = "hello-" + i list.add(model) }// return list return null }这里需要学习的是Kotlin中方法的定义。fun表示定义的是方法,getNames(),是方法名,而冒号后面的List<SecondModelKotlin>表示返回值。但是"?"是什么意思。这里需要看这段代码的另一种写法:
fun getNames(): List<SecondModelKotlin> { var model: SecondModelKotlin val list = java.util.ArrayList<SecondModelKotlin>() for (i in 0..49) { model = SecondModelKotlin() model.name = "hello-" + i list.add(model) } return list// return null }这种写法中没有“?”,返回值是List(非空集合);前一种方法,返回值为null,如果不加?,会提示报错,但是加了“?”,则可以返回null。这里是是kotlin比java简洁体现之一,java很多逻辑都要作非空判断,相信大家写得很烦,而kotlin对此作了优化,默认是没有null,如果需要允许有null的情况,则在赋值的时候, 也就是等号左边,加上“?”,如val a : String ?=null , 而val a :String = null是错误的语法
而数据模型SecondModelKotlin的定义:
class SecondModelKotlin { var name = "" var avatarUrl = "" var text = ""}这里值得一提的是,Kotlin中没有set,get方法, 并且kotlin推荐将类的属性定义为常量。
最后将Adapter贴上。
package com.wl.adapterimport android.content.Contextimport android.support.v7.widget.RecyclerViewimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.RelativeLayoutimport android.widget.TextViewimport com.bumptech.glide.Glideimport com.example.wl.mubanapplication.Rimport com.example.wl.mubanapplication.help_class.ContextHelperimport com.example.wl.mubanapplication.ui.view.RoundImageViewimport com.wl.model.SecondModelKotlinimport java.util.*class AdapterPopularLocationKotlin(mContext: Context) : RecyclerView.Adapter<RecyclerView.ViewHolder>() { private var mItemClickListener: OnItemClickListener? = null private val inflater: LayoutInflater = LayoutInflater.from(mContext) private var datas: MutableList<SecondModelKotlin>? = null fun setData(list: MutableList<SecondModelKotlin>) { if (datas == null) { datas = ArrayList<SecondModelKotlin>() } datas!!.clear() datas!!.addAll(list) notifyDataSetChanged() } val list: MutableList<SecondModelKotlin> get() = datas!! override fun getItemCount(): Int { return datas!!.size } override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) { val holder = viewHolder as ChildViewHolder val model = datas!![position] holder.setModel(model) } override fun onCreateViewHolder(viewHolder: ViewGroup, viewType: Int): RecyclerView.ViewHolder { val view = inflater.inflate(R.layout.item_popular_country, null) val holder = ChildViewHolder(view) return holder } inner class ChildViewHolder(v: View) : RecyclerView.ViewHolder(v) { internal var iv_image: RoundImageView? = null internal var tv_area: TextView? = null internal var model: SecondModelKotlin? = null internal var rl_parent: RelativeLayout init { iv_image = v.findViewById(R.id.iv_image) as RoundImageView tv_area = v.findViewById(R.id.tv_area) as TextView rl_parent = v.findViewById(R.id.rl_parent) as RelativeLayout } fun setModel(model: SecondModelKotlin) { Glide.with(ContextHelper.getApplicationContext()) .load(model.avatarUrl) .centerCrop() .error(R.drawable.avatar_default_black) .into(iv_image) tv_area!!.text = model.name } }}
清单文件注册申明activity:
<activity android:name="com.wl.activity.MainActivity" android:label="@string/title_activity_main" android:theme="@style/AppTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> </intent-filter></activity>
build.gradle中配置如下:
apply plugin: 'kotlin-android'
android { compileSdkVersion 25 buildToolsVersion "25.0.1" defaultConfig { applicationId "com.example.haoyuban111.mubanapplication" minSdkVersion 19 targetSdkVersion 25 versionCode 1 versionName "1.0" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" multiDexEnabled true } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } sourceSets { main.java.srcDirs += 'src/main/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 files('libs/nineoldandroids-2.4.0.jar') // compile 'com.facebook.fresco:fresco:0.12.0' // compile 'com.facebook.fresco:animated-webp:0.12.0' // compile 'com.facebook.fresco:webpsupport:0.12.0' // compile 'com.facebook.fresco:imagepipeline-okhttp:0.12.0+' compile files('libs/commons-io-2.4.jar') compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version" compile 'com.android.support:appcompat-v7:25.1.1' compile 'com.android.support:support-v4:25.1.1' compile 'com.android.support:recyclerview-v7:25.1.1' compile 'com.github.bumptech.glide:glide:3.7.0' compile 'com.squareup.okhttp3:okhttp:3.6.0' compile 'com.google.code.gson:gson:2.6.2' compile 'com.android.support.constraint:constraint-layout:1.0.2' compile 'com.android.support:design:25.3.1' testCompile 'junit:junit:4.12'}repositories { mavenCentral()}
最终运行结果如下:
只是初步学习了一下,讲的很肤浅,希望对大家的学习有帮助吧
- 如何用Kotlin实现一个简单的Activity
- 如何用phototype框架实现一个简单的ajax验证
- 【Android】如何用MediaPlayer实现一个简单的音视频播放器
- 如何用java 5分钟实现一个最简单的mysql代理服务器?
- 如何用viewpager写一个简单易用的安卓Bannner实现轮播
- 如何用WebSocket实现一个简单的聊天室以及单聊功能
- 初识kotlin,实现一个简单的列表
- Kotlin实现一个简单的登录界面
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- 如何用C#写一个简单的Login窗口
- java swing 窗口和控件自适应大小
- (个人)AR电子书系统创新实训第三周(1)
- Spring Boot打包总结
- 怎么理解,java语言是跨平台的?即什么是跨平台?C也说自己是跨平台的,怎么理解?
- 1040. 有几个PAT(25) PAT
- 如何用Kotlin实现一个简单的Activity
- c++收银系统
- Launchpad图标大小怎么调整?
- android Recyclerview上拉加载更多
- python str和reper的区别
- Android图片压缩
- 互联网+策划书
- XHTML与HTML、HTML5的区别
- Math与Random类-Java基础064