使用Kotlin实现Android简单Demo,对比JAVA实现分析具体语法不同之处(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/M075097/article/details/75091515

使用Kotlin实现Android简单Demo,对比JAVA实现分析具体语法不同之处(二)

写在之前,上篇简单的实现了Kotlin工程文件的创建,并记录了默认生成代码与JAVA实现的差别,本篇就整个Demo的编码列举出与JAVA语法的不同之处。

实现的Demo效果如下,头部轮播图+RecyclerView

项目地址:git@github.com:M075097/kotlin_android_demo.git

一.页面布局,依然使用XML方式布局(代码布局分离个人感觉比较好一点),代码如下

activity_main.xml

<?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">

    <!-- 头部标题栏titlebar-->
    <RelativeLayout
        android:id="@+id/linearlayout_topbar_kotlindemo"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:background="@color/colorPrimary">

        <ImageView
            android:id="@+id/imageview_topbar_back"
            android:layout_width="20dp"
            android:layout_height="20dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:src="@drawable/ic_back"/>

        <TextView
            android:id="@+id/textview_first"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:text="Demo展示页面"/>
    </RelativeLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewpager_kotlindemo"
        android:layout_width="match_parent"
        android:layout_height="120dp"/>

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview_kotlindemo"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

二.MainActivity.kt代码如下

package com.yunzhongjun.weiyang.kotlindemo

import android.os.Bundle
import android.support.v4.view.ViewPager
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.yunzhongjun.weiyang.kotlindemo.data.BaseItemData
import com.yunzhongjun.weiyang.kotlindemo.data.ItemNormalData
import com.yunzhongjun.weiyang.kotlindemo.data.ItemTitleData

//继承自父类AppCompatActivity  实现接口 View.OnClickListener 对比JAVA实现为 class MainActivity extends AppCompatActivity implements View.OnClickListener{}
class MainActivity : AppCompatActivity(), View.OnClickListener {
var textView: TextView? = null//变量声明---需要初始化,想要初始化为null 则必须使用A?类型
var mRecyclerView: RecyclerView? = null
var mViewPager: ViewPager? = null
var backButton: ImageView? = null
//var mDataList: List<BaseItemData>? = null;
var mDataList: MutableList<BaseItemData>? = null;//Kotlin中的ArrayList声明之后,不能再增删元素,需要使用MutableList代替。泛型使用和JAVA类似
var adapter: MyRecyclerViewAdapter? = null
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)//调用父类中被覆写的方法,和JAVA中一样
    setContentView(R.layout.activity_main)
    initData()
    initView()
}

//方法声明
private fun initData() {
    var titleData: ItemTitleData? = null
    var normalData: ItemNormalData? = null
    mDataList = mutableListOf<BaseItemData>()
    for (i in 1..4) {// for循环
        titleData = ItemTitleData()
        titleData.title = "分类标题" + i
        mDataList!!.add(titleData)//直接使用mDataList.add()时,报错,原因是mDataList声明的类型为A?的类型,要想使用,需要 A? as A 之后使用或者在确认为非空之后直接使用A?的实例a!! Kotlin 会把A?智能转换A
        for (j in 1..5) {
            normalData = ItemNormalData();
            normalData.itemDes = "类型" + i + "下:" + "条目" + j
            normalData.itemIconPath = null;
            mDataList!!.add(normalData)
        }
    }
}

private fun initView() {
    textView = findViewById(R.id.textview_first) as TextView //强转类型,对比JAVA的(AA)A 实现 Kotlin直接使用 AA as A
    mRecyclerView = findViewById(R.id.recyclerview_kotlindemo) as RecyclerView
    mViewPager = findViewById(R.id.viewpager_kotlindemo) as ViewPager
    backButton = findViewById(R.id.imageview_topbar_back) as ImageView

    backButton?.setOnClickListener(this)
    var str: String = "Kotlin Demo 页面"
    textView?.setText(str)//T此处必须有?号因为A?和A不是同一种类型

    //init ViewPager
    var viewPagerAdapter:MyViewPagerAdapter = MyViewPagerAdapter(3);//新建对象 不需要使用new 类比JAVA 语法:MyViewPagerAdapter viewPagerAdapter = new MyViewPagerAdapter(3);
    mViewPager?.adapter = viewPagerAdapter //对象中原有的set/get方法只要符合标准的setter和getter命名规则 则可以直接使用A.property 赋值 其底层依然是调用setter和getter方法

    //init RecyclerView
    var layoutManager: LinearLayoutManager = LinearLayoutManager(this)
    mRecyclerView?.layoutManager = layoutManager;
    adapter = MyRecyclerViewAdapter(mDataList)
    //adapter?.setDataList(mDataList)
    mRecyclerView?.adapter = adapter
}
//接口方法覆写
override fun onClick(v: View?) {
    when (v?.id) {
        R.id.imageview_topbar_back -> {
            this.finish()
        }
        else -> {
            //TODO nothing
        }
    }
    //when 语法实现类比于JAVA中的
  /*  switch(v.getId()){
        case R.id.imageview_topbar_back:
                break;
        default:
            break;
    }*/

}
}

对比以上具体代码可以看到的Kotlin与JAVA代码差别有以下区别

  • 1.类继承和实现接口的语法不同,Kotlin中不需要使用extends和implements 来区分声明,统一使用”:”声明

Kotlin继承父类和实现接口如下:

class MainActivity : AppCompatActivity(), View.OnClickListener {
    //code what you want!   
}

Java实现如下:

class MainActivity extends AppCompatActivity implements View.OnClickListener{
    //code what you want!
}
  • 2.继承父类时如果父类没有显式的构造类(constructor)的实现,则需要在父类名后面加上()以表明使用其默认空参的构造函数

    代码如下

    class MainActivity : AppCompatActivity()//此处需要有()
    
  • 3.变量声明方式不同,变量用var关键字,常量使用val关键字,以Android中的TextView的声明为例

Kotlin中的TextView变量声明如下:

var textView: TextView? = null//变量声明---需要初始化,想要初始化为null 则必须使用A?类型

若直接使用则可以如下(不需要加?标识)
var textView1:TextView = findViewById(R.id.textview_first) as TextView

对比Java中的如下:

TextView textView;
  • 4.方法(函数)的声明不同

    Kotlin中 格式如下private fun functionName(a:A,b:B):C{}

    * Kotlin中使用fun关键字声明,
    * 方法参数为(变量名:变量类型)
    * 若参数为多个则中间用“,”分开
    * 返回值类型声明则在方法体前和参数之后加上":"进行明
    * Kotlin中方法也可以使用private,public声明
    

    对比JAVA 中的格式为 :private C functionName(A a,B b){}

  • 5.List使用不同 以ArrayList为例,Kotlin中区分了可变的和不可变的集合,以便准确控制集合什么时候可以更改什么时候不可以更改。进而可以控制不必要的bug生成及编写出一个稳定性更高的API 参考链接https://stackoverflow.com/questions/37913252/kotlins-list-missing-add-remove-etc

    Kotlin具体使用中如做如下集合的声明

    var mDataList: List<>? = ArrayList<>();

则在使用中mDataList?.add()中会报如下错误

smartcast is not impossible,beacuse “mDataList” is mutable property that could have been changed by this time 

####因此此处需要使用Kotlin中提供的集合类型MutableList,声明如下

var mDataList: MutableList<BaseItemData>? = null;//代码摘自MainActivity.kt

初始化如下

mDataList = mutableListOf<BaseItemData>()//代码摘自MainActivity.kt

使用如下

 mDataList?.add(normalData)//代码摘自MainActivity.kt
  • 6.for循环使用不同

    Kotlin中的使用代码如下

    for (j in 1..5) {//此处1..5 相当于数组[1,2,3,4,5]
    //do what you want
    }
    对比JAVA中的一种写法如下

    int[] aa = new int[]{1,2,3,4,5};
    for(int i:aa){
    //do what you want
    }

  • 7.强转类型使用不同,以TextView的强转对比如下

Kotlin中的强转如下

//findViewById()默认返回为View类型,要想被声明为TextView类型的textView接收 需要做以下强转
textView = findViewById(R.id.textview_first) as TextView //强转类型,对比JAVA的(AA)A 实现 Kotlin直接使用 AA as A

对比JAVA实现如下

textView = (TextView)findViewById(R.id.textview_first);
  • 8.对象实例化差别,就该Demo中自定义的MyViewPagerAdapter实例化对比

Kotlin中对象实例化如下,最大的不同是不需使用关键字“new”

var viewPagerAdapter:MyViewPagerAdapter = MyViewPagerAdapter(3)

JAVA中的对象实例化为

MyViewPagerAdapter viewPagerAdapter = new MyViewPagerAdapter(3);
  • 9.原有对象中符合setter和getter命名规则方法的使用的区别–以原生ViewPager设置Adapter的方法(该方法符合setter和getter规则)对比

Kotlin工程中设置Adapter,可以直接使用类似js中的属性赋值的方式对其进行设置

mViewPager?.adapter = viewPagerAdapter

JAVA中的使用如下

mViewPager.setAdapter(viewPagerAdapter);
  • 10.switch 语法差别

Kotlin中使用when实现类似JAVA中的switch语法结构,具体以MainActivity.kt中onclick(View view){}中的实现对比

when (v?.id) {
        R.id.imageview_topbar_back -> {
            this.finish()
        }
        else -> {//相当于switch中的default
            //TODO nothing
        }
    }

JAVA中的是实现如下

switch(v.getId()){
        case R.id.imageview_topbar_back:
                break;
        default:
            break;
    }

三.ViewPager使用的MyViewPagerAdapter定义代码如下

MyViewPagerAdapter.kt

package com.yunzhongjun.weiyang.kotlindemo

import android.support.v4.view.PagerAdapter
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView

/**
 * Created by weiyang on 2017/7/11 0011.
 */
class MyViewPagerAdapter(pageCount: Int) : PagerAdapter() {

private var pageCount: Int

init {
    this.pageCount = pageCount;
}

override fun isViewFromObject(view: View?, `object`: Any?): Boolean {
    return view == `object`;
}

override fun getCount(): Int {
    return pageCount
}

override fun destroyItem(container: ViewGroup?, position: Int, `object`: Any?) {
    container?.removeView(`object` as View)
    //super.destroyItem(container, position, `object`)
}

override fun instantiateItem(container: ViewGroup?, position: Int): Any {
    var imageView: ImageView? = ImageView(container?.context);
    var resId: Int
    when (position) {
        0 -> {
            resId = R.drawable.image_2
        }
        1 -> {
            resId = R.drawable.image_3
        }
        2 -> {
            resId = R.drawable.image_4
        }
        else -> {
            resId = R.drawable.image_aa
        }
    }
    imageView?.setImageDrawable(container?.context?.resources?.getDrawable(resId))
    var layoutParams: ViewGroup.LayoutParams = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
    imageView?.layoutParams = layoutParams
    imageView?.scaleType =ImageView.ScaleType.CENTER_CROP
    container?.addView(imageView)
    return imageView!!
}
}

对比JAVA实现可以看到该类实现的构造方法与JAVA不同

  • 构造函数实现的差别如下,Kotlin中class声明时在类名后的()内可以跟上默认的构造函数,但是该默认的构造函数的其他操作需要放到 init{}中进行,该构造函数称为主构造函数

具体详细的关于Kotlin中Class的主构造函数和次构造函数参考http://www.runoob.com/kotlin/kotlin-class-object.html

Kotlin实现如下

class MyViewPagerAdapter(pageCount: Int) : PagerAdapter() {

    private var pageCount: Int

    init {
        this.pageCount = pageCount;
    }
    //其他覆写的方法
    //...
}

JAVA实现如下

public class MyViewPagerAdapter extends PagerAdapter{
    private int pageCount;
    public MyViewPagerAdapter(int pageCount){
        //super();//隐藏的调用父类的默认构造函数
        this.pageCount = pageCount;
    }
}

四.其他该Demo中能够直接参考的Kotlin和JAVA语法不同的地方

  • 1.静态方法的实现(具体参考该Demo中的BaseItemData.kt)
    • JAVA中使用static关键字声明
    • Kotlin中则需要使用 companion object {} 包括相关方法
  • 2.枚举类的实现

具体代码如下:BaseItemData.kt

      package com.yunzhongjun.weiyang.kotlindemo.data

/**
 * Created by weiyang on 2017/7/11 0011.
 */
abstract class BaseItemData {
abstract fun getItemType(): ItemType

 enum class ItemType(typeValue: Int) {
    TypeNormal(0),
    TypeTitle(1),
    Unsupport(2);

    var typeValue: Int

    init {
        this.typeValue = typeValue;
    }

    companion object {
        //类比JAVA中的静态方法
        fun getTypeValue(typeValue: Int): ItemType {
            for (value in values()) {
                if (value.typeValue == typeValue) {
                    return value;
                }
            }
            return Unsupport;
        }
    }

}
}
  • 3 当一个实例使用类似A?声明后(A为具体的类名),若要调用部分属性时可能会报错,显示类型为nullable,则此时可以在确认其不为null时使用断言A!!把A?转换为A

对应示意代码如下

var a:A? = null
a!!.property//相关属性调用

没有更多推荐了,返回首页