极简Kotlin-For-Android(一)

安装 Kotlin 插件java

Android Studio 3.+ 已经有了 Kotlin 插件,若是是更早的版本,点击 Android Studio | File | Settings | Plugins,搜索 Kotlin ,安装,重启 Android Studio .数据库

建立工程编程

点击 Android Studio | File | New project : 勾选Incloud Kotlin support.
就会看到下面的类:json

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}
复制代码

定义类api

1.只需使用class关键字.
2.它有一个惟一默认的构造器,大部分状况下只需使用这个默认构造器便可.
3.构造函数的函数体,写在init块{}中数组

class Person(name:String ,age : Int) {
    init {
    }
}
复制代码

类继承安全

1.上帝类是Any(相似于java中的Object)
2.全部类默认是不可继承的(final),咱们只能继承声明open或abstract的类bash

open class Animal(name: String)
class Person(name:String ,age : Int) : Animal(name) 
复制代码

函数(java中的方法)网络

1.使用fun关键字
2.若是没有指定返回值,默认返回Unit(java中的void),固然也能够指定返回任何类型app

fun add(age1:Int ,age2:Int) : Int{
    return age1+age2
}
复制代码

Tips: 分号不是必须的,结尾不使用分号会节约不少时间,养成这个好习惯吧!

3.若是返回结果可使用表达式表达出来,直接使用等号:

fun add2(age1: Int , age2: Int) : Int = age1+age2
复制代码

构造方法和函数参数
1.kotlin中参数是先写名称,后写类型....(有点不适应) 2.能够给参数一个指定默认值,使其变得可选,例以下面toast函数第二个参数给了默认值,调用时候能够不传第二个值(java中重载方法的替换?)

fun toast(msg : String , length : Int = Toast.LENGTH_LONG){
    Toast.makeText(this,msg,length).show();
}

toast("打印吐司鸭")
toast("打印吐司鸭",Toast.LENGTH_SHORT)
复制代码

Tips:
String模板内插*:

val name = "susan"
println("name : $name")
输出结果: name : susan
复制代码

编写你的第一个类

咱们在MainActivity的布局文件中加入RecyclerView,而后设置好LayoutManager:

val recycler = findViewById(R.id.recycler) as RecyclerView
recycler.layoutManager = LinearLayoutManager(this)
复制代码

如上代码,LayoutManager会经过属性设置,而不是经过set方法.
对象实例化也去掉了new关键字,构造函数仍然会被调用. 接着设置Adapter:

class ForecastListAdapter(val items : List<String>) : RecyclerView.Adapter<ForecastListAdapter.ViewHolder>(){
    //绑定数据
    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        holder.textView.text = items[position]
    }
    //返回list count
    override fun getItemCount(): Int {
        return items.size
    }
    //建立viewHolder
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(TextView(parent.context))
    }
    class ViewHolder(val textView : TextView) : RecyclerView.ViewHolder(textView)
}
复制代码

回到MainActivity,如今咱们将少许数据放入recyclerview中:

//定义天气数组数组
    val weaList= listOf<String>(
            "北京 -0 - 微风",
            "北京 -10 - 微风",
            "北京 -13 - 微风",
            "北京 -20 - 微风",
            "北京 -5 - 微风"
            )
recycler.adapter = ForecastListAdapter(weaList)
复制代码

关于List的建立:
能够经过一个函数listOf建立一个常亮list,它接收任何类型的vararg(可变长度参数).还有不少其余函数:setOf,arrayListOf hashSetOf, etc...

运行你的项目吧:

接下来,必需要学习一些基本类型,变量,属性等才能继续.

变量和属性
在kotlin中,一切都是对象~

基本类型
integer float boolean等类型依然存在,不过是以对象存在.它们的工做方式与java十分类似,须要注意如下几点:

数字类型不会自动转型.例如不能给Double分配int型值

val i: Int = 7
    val d: Double = i.toDouble()
复制代码

char不能直接做为一个数字来处理,须要转换成数字

val a : Char = 'c'
    val b : Int = a.toInt()
复制代码

位运算 java中使用的 || 或者 && kotlin中使用and or

val willOr = FLAG1 or FLAG2
    val willAnd = FLAG1 and FLAG2
复制代码

字面能够写明具体的类型,可是不是必须的,编译器会自动解析类型

val i = 12 //as Int
val l = 3l //as Long
val f = 5f //as Float
val d = 3.5 //as Double
复制代码

一个String 能够像数组那样访问,而且被迭代

val s = "test"
val t = s[2]//一个字符's'
//迭代
val o = "test"
for (b in o){
    print(t)
}
复制代码

变量
变量可简单定义为 : val(不可变)和var(可变).可是不可变在kotlin是一个很重要的概念.

一个不可变对象意味着它在实例化以后就不能再去改变它的状态了。若是你须要一个这个对象修改以后的版本,那就会再建立一个新的对象。这个让编程更加具备健壮性和预估性。

在Java中,大部分的对象是可变的,那就意味着任何能够访问它这个对象的代码均可以去修改它,从而影响整个程序的其它地方。不可变对象也能够说是线程安全的,由于它们没法去改变,也不须要去定义访问控制,由于全部线程访问到的对象都是同一个

一个重要的概念是:尽量地使用val。除了个别状况(特别是在Android中,有不少类咱们是不会去直接调用构造函数的),大多数时候是能够的。

若是咱们须要使用更多的范型类型,则须要指定:

val a: Any = 23
val c: Context = activity
复制代码

属性
没有任何指定,属性会默认使用getter和setter.

class Dog {
    val color : Int = 0
}
复制代码

固然也能够自定义set,get.

var color : Int = 3
    get() = field.toBigDecimal().intValueExact()
    set(value) {
        field = 3 + value
    }
复制代码

Anko来了

  • 主要目的是用来替换以前XMl的方式来使用代码生成UI布局
  • Anko还包含了许多有帮助的函数和属性来避免写不少代码
  • 了解Anko的实现方式对学习kotlin有很大帮组

开始使用Anko
刚使用findviewbyid的能够用fins替换

val recycler : RecyclerView  = find(R.id.recycler) 
复制代码

Anko还有一些别的实用功能:
实例化Intent,Activity之间的跳转,Fragment的建立,数据库的访问,Alert的建立......。

扩展函数

扩展函数数是指在一个类上增长一种新的行为,甚至咱们没有这个类代码的访问权限。这是一个在缺乏有用函数的类上扩展的方法。

在Java中,一般会实现不少带有static方法的工具类。Kotlin中扩展函数的一个优点是咱们不须要在调用方法的时候把整个对象看成参数传入。扩展函数表现得就像是属于这个类的同样,并且咱们可使用this关键字和调用全部public方法。

举个例子,咱们能够建立一个toast函数,这个函数不须要传入任何context,它能够被任何Context或者它的子类调用,好比Activity或者Service:

fun Context.toast(message: CharSequence, duration: Int = Toast.LENGTH_SHORT) {    
    Toast.makeText(this, message, duration).show()
}
复制代码

这个方法能够在Activity内部直接调用:

toast("Hello world!")
toast("Hello world!", Toast.LENGTH_LONG)
复制代码

扩展函数并非真正地修改了原来的类,它是以静态导入的方式来实现的。扩展函数能够被声明在任何文件中,所以有个通用的实践是把一系列有关的函数放在一个新建的文件里。

执行一个请求
若是只是执行一个简单的api请求,咱们能够不用任何非三方库实现

class Request(val url : String) {
    fun run(){
        val jsonStr = URL(url).readText()
        Log.d("result",jsonStr)
    }
}
复制代码

众所周知,在子线程中是不容许进行网络请求的,java的AsyncTask是很是丑陋的...diss一波...

Anko提供了很是简单的DSL来处理异步任务,它知足大部分的需求。它提供了一个基本的async函数用于在其它线程执行代码,也能够选择经过调用uiThread的方式回到主线程。在子线程中执行请求以下这么简单:

val url = "https://samples.openweathermap.org/data/2.5/weather?q=London,uk&appid=b6907d289e10d714a6e88b30761fae22"
        doAsync() {
            Request(url).run()
            uiThread { toast("Request") }
        }
复制代码

此时运行项目,查看log,能够发现一个简单请求已经实现了!
接着咱们要把他使用json解析,转换成实体类.

数据类 数据类是一种很是强大的类,它可让你避免建立Java中的用于保存状态但又操做很是简单的POJO的模版代码。它们一般只提供了用于访问它们属性的简单的getter和setter。定义一个新的数据类很是简单:

data class Forecast(val date : Date , val temp : Float ,
                    val details : String) 
复制代码

转换json到数据类

关于伴生对象Companion objects :
Kotlin容许咱们去定义一些行为与静态对象同样的对象。尽管这些对象能够用众所周知的模式来实现,好比容易实现的单例模式。咱们须要一个类里面有一些静态的属性、常量或者函数,咱们可使用companion object。这个对象被这个类的全部对象所共享,就像Java中的静态属性或者方法。

修改一下Request类:

class Request(val zipCode : String) {

    companion object {
        private val APP_ID = "15646a06818f61f7b8d7823ca833e1ce"
        private val URL = "http://api.openweathermap.org/data/2.5/" +"forecast/daily?mode=json&units=metric&cnt=7"
        private val COMPLETE_URL = "$URL&APPID=$APP_ID&q="
    }

    public fun execute() : ForecastResult{
        val jsonStr = URL(COMPLETE_URL + zipCode).readText()
        return Gson().fromJson(jsonStr,ForecastResult::class.java)
    }

    @Deprecated("使用execute替换")
    public fun run(){
        val jsonStr = URL(url).readText()
        Log.d("result",jsonStr)
    }
}
复制代码

数据类:

data class ForecastResult(val city: ResponseClasses.City,
                     val cnt: Int,
                     val cod: String,
                     val list: List<ResponseClasses.ForeCast>,
                     val message: Double) {


    data class ForeCast(
            val clouds: Int,
            val deg: Int,
            val dt: Int,
            val humidity: Int,
            val pressure: Double,
            val rain: Double,
            val speed: Double,
            val temp: Temp,
            val weather: List<Weather>
    )

    data class Temp(
            val day: Double,
            val eve: Double,
            val max: Double,
            val min: Double,
            val morn: Double,
            val night: Double
    )

    data class Weather(
            val description: String,
            val icon: String,
            val id: Int,
            val main: String
    )

    data class City(
            val coord: Coord,
            val country: String,
            val id: Int,
            val name: String,
            val population: Int
    )

    data class Coord(
            val lat: Double,
            val lon: Double
    )
}
复制代码

好累,先写到这里@_@

分享一首好音乐: Lo Que Siento - cuco 咱们都是作梦的梦想家

相关文章
相关标签/搜索