对一个KotlinAPP的copy

原创 2017年06月14日 12:14:58

最近看了下Kotlin。随便找了个简单的地址就开始了copy。真的是copy,代码结构,布局,图片等都是copy的。

本文地址: http://blog.csdn.net/qq_25806863/article/details/73209612

主要是为了体验一下Kotlin在Android开发中是什么样子的。

copy对象就是几百个Gank的其中一个:https://github.com/onlyloveyd/GankIOWithKotlin

也可以他博客看一下 http://blog.csdn.net/poorkick/article/details/72510645

非常感谢大神的分享,copy的结果就是:https://github.com/wangyisll/gankapplication/tree/master

图什么就不放了,跟原来那个一样,就是颜色变了一下

这里写图片描述

因为使用了Kotlin Android Extensions,所以我觉得没必要再用ButterKnife了,所以就删掉了。

哈哈,下面记录一下copy中感受到的不同,都只是一部分示例,更多的可以看代码进行比较。

这是大神的java版 https://github.com/onlyloveyd/GankIOClient

这是大神的kotlin版 https://github.com/onlyloveyd/GankIOWithKotlin

具体语法还是看官方语法文档吧。

1.Kotlin Android Extensions

这是Kotlin官方的扩展,可以省去finViewById

如在activity_main.xml中有这样的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolBar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/colorPrimary"
        android:fitsSystemWindows="true"
        android:titleTextColor="@color/white"/>

</LinearLayout>

上面的id为toolBar,所以在代码中可以直接使用id来表示这个空间,跟ButterKnife一样。

先引入:

import kotlinx.android.synthetic.main.activity_main.*

然后就能直接在代码中使用了:

setSupportActionBar(toolBar)

2.对属性的引用

在Kotlin中,控件的大部分get和set的属性都能直接向下面这样用:

 tvTitle.setText("a")
 //写成
 tvTitle.text = "a"

3.单例

在原来的额网络请求类单例是这样的:

public class HttpMethods {

    public static final String BASE_URL = "http://gank.io/api/";

    private static final int DEFAULT_TIMEOUT = 5;

    private Retrofit retrofit;
    private ContentService contentService;
    private OkHttpClient mOkHttpClient;

    //构造方法私有
    private HttpMethods() {
        //手动创建一个OkHttpClient并设置超时时间
        OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
        httpClientBuilder.connectTimeout(DEFAULT_TIMEOUT, TimeUnit.SECONDS);
        mOkHttpClient = httpClientBuilder.build();

        retrofit = new Retrofit.Builder().client(mOkHttpClient)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(BASE_URL)
                .build();

        contentService = retrofit.create(ContentService.class);
    }


    //获取单例
    public static HttpMethods getInstance() {
        return SingletonHolder.INSTANCE;
    }

    /**
     * 用于获取干货数据
     *
     * @param subscriber 由调用者传过来的观察者对象
     * @param category   类别
     * @param pagesize   请求数据个数
     * @param pagenum    页码
     */
    public void getData(Observer<DataBean> subscriber, String category, String pagesize,
            int pagenum) {
        contentService.getContent(category, pagesize, pagenum)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(subscriber);
    。。。
    //在访问HttpMethods时创建单例
    private static class SingletonHolder {
        private static final HttpMethods INSTANCE = new HttpMethods();
    }
}

在Kotlin中,单例直接这样写:

object RetrofitClient {
    private val retrofit: Retrofit
    private val api: RetrofitApiService
    private val baseUrl = "http://gank.io/api/"

    init {
        val httpclient = OkHttpClient.Builder()
        httpclient.connectTimeout(10, TimeUnit.SECONDS)
        retrofit = Retrofit.Builder().client(httpclient.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .baseUrl(baseUrl)
                .build()
        api = retrofit.create(RetrofitApiService::class.java)
    }

    /**
     * 获取干货数据
     */
    fun getData(subscriber: Observer<TypeData>, category: String, pageSize: String, pageNum: Int) {
        api.getContent(category, pageSize, pageNum)
                .subscribeOn(Schedulers.io())
                .unsubscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .safeSubscribe(subscriber)
    }
}

class变成了object,然后下面这样使用就是单例的,那些方法就跟变成了static一样,直接调用:

RetrofitClient.getData(...)

4.常量类的定义

java中的常量类一般是这样的:

public class Constant {
    public static final long ONE_SECOND = 1000;
    public static final long ONE_MINUTE = ONE_SECOND * 60;
    public static final long ONE_HOUR = ONE_MINUTE * 60;
    public static final long ONE_DAY = ONE_HOUR * 24;
}

在Kotlin中可以写成这样:

object Constant {
    val ONE_SECOND: Long = 1000
    val ONE_MINUTE = ONE_SECOND * 60
    val ONE_HOUR = ONE_MINUTE * 60
    val ONE_DAY = ONE_HOUR * 24
}

使用起来都是一样的 Constant.ONE_SECOND,但是省掉了好多public static final

5.集合的定义

java中集合的初始化是这样的:

public static HashMap<String, Integer> sTypeColor = new HashMap<String, Integer>() {
        {
            put("Android", R.drawable.bg_android_tag);
            put("iOS", R.drawable.bg_ios_tag);
            put("瞎推荐", R.drawable.bg_rec_tag);
            put("拓展资源", R.drawable.bg_res_tag);
            put("App", R.drawable.bg_app_tag);
            put("福利", R.drawable.bg_bonus_tag);
            put("前端", R.drawable.bg_js_tag);
            put("休息视频", R.drawable.bg_video_tag);
        }
    };

    public static ArrayList<String> sCategoryList = new ArrayList<String>() {
        {
            add("all");
            add("Android");
            add("瞎推荐");
            add("iOS");
            add("前端");
            add("拓展资源");
            add("App");
            add("休息视频");
            add("福利");
        }
    };

在Kotlin中也可以写成类似的:

var sTypeColor: HashMap<String, Int> = object : HashMap<String, Int>() {
        init {
            put("Android", R.drawable.bg_android_tag)
            put("iOS", R.drawable.bg_ios_tag)
            put("瞎推荐", R.drawable.bg_rec_tag)
            put("拓展资源", R.drawable.bg_res_tag)
            put("App", R.drawable.bg_app_tag)
            put("福利", R.drawable.bg_bonus_tag)
            put("前端", R.drawable.bg_js_tag)
            put("休息视频", R.drawable.bg_video_tag)
        }
    }

    var sCategoryList: ArrayList<String> = object : ArrayList<String>() {
        init {
            add("all")
            add("Android")
            add("瞎推荐")
            add("iOS")
            add("前端")
            add("拓展资源")
            add("App")
            add("休息视频")
            add("福利")
        }
    }

更可以写成下面的简单的:

var sTypeColor = mutableMapOf("Android" to R.drawable.bg_android_tag,
            "iOS" to R.drawable.bg_ios_tag,
            "瞎推荐" to R.drawable.bg_rec_tag,
            "拓展资源" to R.drawable.bg_res_tag,
            "App" to R.drawable.bg_app_tag,
            "福利" to R.drawable.bg_bonus_tag,
            "前端" to R.drawable.bg_js_tag,
            "休息视频" to R.drawable.bg_video_tag)

    var sCategoryList = mutableListOf("all", "Android", "瞎推荐", "iOS", "前端", "拓展资源", "App", "休息视频", "福利")

又省了好多代码….

6.anko的startActivity

启动一个Activity是很常用的,通过anko可以快速启动一个Activity:

先导入,一般都是自动引用

import org.jetbrains.anko.startActivity

然后使用:

startActivity<OrderActivity>()

也可以带参数:

startActivity<WebActivity>("URL" to data.url)
//在WebActivity中接收参数,下面的intent其实就是getIntent(),extras其实就是getExtras()
intent.extras.getString("URL")

7.分支语句

Kotlin中用when代替了switch

用法也是类似的:

override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        when(item?.itemId){
            R.id.refresh -> wv.reload()
            R.id.share -> url?.let { share(it) }
            R.id.openinbrowse -> url?.let { browse(it) }
            R.id.copyurl -> {
                val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
                clipboard.text = url
                Snackbar.make(wv,"已复制到剪切板",Snackbar.LENGTH_SHORT).show()
            }
        }
        return super.onOptionsItemSelected(item)
    }

而且还能直接作为返回值:

override fun getItem(position: Int): Fragment? {
    return when (position) {
        0 -> DailyFragment.getInstance()
        1 -> SortFragment.getInstance()
        2 -> MindFragment.getInstance()
        else -> AboutFragment.getInstance()
    }
}

8. let的使用和空判断

经常会有这样的需求:

if (dailyBean.getResults().getAndroid() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getAndroid());
                }

判断一个东西不为空,然后执行一段代码。一行可能看不出来,下面这样呢?

@Override
            public void onNext(DailyBean dailyBean) {
              。。。
                if (dailyBean.getResults().getAndroid() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getAndroid());
                }
                if (dailyBean.getResults().getApp() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getApp());
                }
                if (dailyBean.getResults().getBonus() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getBonus());
                }
                if (dailyBean.getResults().getIOS() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getIOS());
                }
                if (dailyBean.getResults().getJs() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getJs());
                }
                if (dailyBean.getResults().getRec() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getRec());
                }
                if (dailyBean.getResults().getRes() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getRes());
                }
                if (dailyBean.getResults().getVideo() != null) {
                    mVisitableList.addAll(dailyBean.getResults().getVideo());
                }
                。。。
            }

如果用let,会少很多,作用是一样的:

override fun onNext(dailyData: DailyData) {
              ...
                    dailyData.results.android?.let { mVisitableList.addAll(it) }
                    dailyData.results.app?.let { mVisitableList.addAll(it) }
                    dailyData.results.bonus?.let { mVisitableList.addAll(it) }
                    dailyData.results.ios?.let { mVisitableList.addAll(it) }
                    dailyData.results.js?.let { mVisitableList.addAll(it) }
                    dailyData.results.rec?.let { mVisitableList.addAll(it) }
                    dailyData.results.res?.let { mVisitableList.addAll(it) }
                    dailyData.results.video?.let { mVisitableList.addAll(it) }
             ...
            }

block使用copy原理

简单来说,block就像一个函数指针,指向我们要使用的函数。 就和函数调用一样的,不管你在哪里写了这个block,只要你把它放在了内存中(通过调用存在这个block的方法或者是函数),不管放在栈...
  • leonliu070602
  • leonliu070602
  • 2016年10月31日 14:01
  • 308

关于OC中Copy和retain的心得

关于oc中的 @property中的retain和Copy的运用, 首先先看一下OC中的关于 * &之间的关系         NSString * str=@"123";         NS...
  • PassionWilliam
  • PassionWilliam
  • 2015年09月15日 13:05
  • 985

Unable to copy file to bin 对路径 的访问被拒绝

解决一个VS小问题
  • metababy
  • metababy
  • 2011年04月13日 13:36
  • 5797

SQL Server 2008如何copy database

SQL Server 2008如何copy database: 方法一:使用Microsoft SQL Server Management Studio中的Copy Database Wizard来辅...
  • tianshijianbing1989
  • tianshijianbing1989
  • 2014年11月11日 17:06
  • 1931

c++ copy库函数的用法

#include #include #include #include using namespace std; int main() {     int dim[]={1,2,3,...
  • qq_36125733
  • qq_36125733
  • 2017年03月27日 20:24
  • 415

iOS 视图的复制方法

NSData * archiveData = [NSKeyedArchiver archivedDataWithRootObject:stateLabel]; UILabel* aLa...
  • reylen
  • reylen
  • 2015年03月20日 10:08
  • 2459

Python中使用copy模块实现列表(list)拷贝

引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子: 问题描述:已知一个列表,求生成一...
  • lixintong1992
  • lixintong1992
  • 2016年03月29日 14:15
  • 857

copy一个数组的方法

NSArray *newArray = [NSMutableArray arrayWithArray:oldArray]; NSArray *newArray = [[[NSMutableArray...
  • liubo5290392
  • liubo5290392
  • 2013年11月15日 11:20
  • 1514

python中的引用、浅拷贝和深拷贝

在python中,有一句话:“一切皆为对象,一切皆为对象的引用“,所以 只要记住这句话就很容易清楚python中的引用、浅拷贝和深拷贝了。 1. 引用 python中的引用是经常使用的,pyth...
  • soft_kind
  • soft_kind
  • 2018年01月19日 23:56
  • 23

iOS 如何完整复制另一个视图控制器的内容

//  如果需要导航控制器 NavgationController 则需要继承父类(如父类没有导航控制器 或者不需要请忽略本) // 将另一个视图控制器的页面添加到当前页面  - (voi...
  • saw471
  • saw471
  • 2017年01月11日 15:44
  • 792
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:对一个KotlinAPP的copy
举报原因:
原因补充:

(最多只允许输入30个字)