美文网首页kotlin
kotlin-4-其他

kotlin-4-其他

作者: 揭穿套路 | 来源:发表于2019-01-22 11:42 被阅读0次
    1、扩展函数

    简单来说,Kotlin扩展函数允许我们在不改变已有类的情况下,为类添加新的函数。

    例如,我们能够为Activity中添加新的方法,让我们以更简单术语显示toast,并且这个函数不需要传入任何context,它可以被任何Context或者它的子类调用,比如Activity或者Service:

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

    扩展函数并不是真正地修改了原来的类,它是以静态导入的方式来实现的。实际上是在定义的文件中增加了一个static public final函数。
    扩展函数可以被声明在任何文件中,因此有个通用的方式是把一系列有关的函数放在一个新建的文件里。

    例:ImageView 增加一个扩展函数:

    fun ImageView.loadUrl(url: String) {
        Picasso.with(context).load(url).into(this)
    }
    

    然后我们在使用的时候只需这样简单的一行:

    imageView.loadUrl(url)
    

    扩展属性实际上不会向类添加新的成员或者函数

    2、容器的操作符

    Kotlin 中,容器自身带有一系列的操作符,可以非常简洁的去实现一些逻辑

    
    java
    for(int i = 0; i < container.childCount - 1;  i++) {
        View childView = container.getChildAt(i);
        if(childView.getVisibility() == View.GONE) {
            childView.setVisibility(View.VISIBLE);
        }
    }
    
    rxjava
    Observable.range(0, container.getChildCount() - 1)
            .filter(new Predicate<Integer>() {
                @Override
                public boolean test(Integer integer) throws Exception {
                    return container.getChildAt(integer).getVisibility() == View.GONE;
                }
            }).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            container.getChildAt(integer).setVisibility(VISIBLE);
        }
    });
    
    kotlin
    (0 until container.childCount) //until 不包含右区间
            .map { container.getChildAt(it) } // it 
            .filter { it.visibility == View.GONE }
            .forEach { it.visibility = View.VISIBLE }
    

    上述代码首先创建了一个 0 到 container.childCount - 1 的区间;再用 map 操作符配合取出 child 的代码将这个 Int 的集合转化为了 childView 的集合;然后在用 filter 操作符对集合做筛选,选出 childView 中所有可见性为 GONE 的作为一个新的集合;最终 forEach 遍历把所有的 childView 都设置为 VISIBLE。

    3、anko

    Kotlin 中有一个专为 Android 开发量身打造的库,名为 anko,其中包含了许多可以简化开发的代码,其中就对线程进行了简化。
    https://github.com/Kotlin/anko

    例:android 网络请求
    java 基础实现

        new Thread(new Runnable() {
                @Override
                public void run() {
                    URL url;
                    HttpURLConnection conn = null;
                    StringBuilder response = null;
                    try {
                        url = new URL("https://www.baidu.com");
                        conn = (HttpURLConnection)url.openConnection();
                        conn.setRequestMethod("GET");
                        conn.setDoInput(true);
                        conn.setDoOutput(true);
                        OutputStream os = conn.getOutputStream();
                        os.close();
                        BufferedReader red = new BufferedReader(new InputStreamReader(conn.getInputStream()));
                        String line ;
                        response = new StringBuilder();
                        while( (line =red.readLine()) != null ){
                            response.append(line);
                        }
                        red.close();
                    }catch (MalformedURLException e) {
    
                    } catch (IOException e) {
                        e.printStackTrace();
                    } finally {
                        if (conn != null) {
                            conn.disconnect();
                        }
                    }
                    final String _response = response.toString();
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(_response)
                        }
                    });
                }
            }).start();
    

    rxjava 基础实现 (未使用retofit)

    Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> e) {
            此处进行网络请求
        }
    })
    .subscribeOn(Schedulers.newThread())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
        }
    });
    

    kotlin 实现

            async {
                val response = URL("https://www.baidu.com").readText()
                uiThread {
                    textView.text = response
                }
            }
    
    4、双冒号 :: 使用

    Kotlin 中 双冒号操作符 表示把一个方法当做一个参数,传递到另一个方法中进行使用,通俗的来讲就是引用一个方法。先来看一下例子:

    
        fun getResult(str1: String, str2: String): String = "result is {$str1 , $str2}"
    
        /**
         * @param p1 参数1
         * @param p2 参数2
         * @param method 方法名称
         */
        fun lock(p1: String, p2: String, method: (str1: String, str2: String) -> String): String {
            return method(p1, p2)
        }
        // 简化版
        fun lock(p1: String, p2: String, method: (str1: String, str2: String) -> String): String =  method(p1, p2)
        // 最简版
        fun lock(p1: String, p2: String, method: (str1: String, str2: String) -> String)=  method(p1, p2)
    
       fun main(args: Array<String>) {
          println(lock("param1", "param2", ::getResult))
      }
    
    

    如果我们需要调用其他 Class 中的某一个方法是:
    写法为:

    fun main(args: Array<String>) {
        var d = Test()
        println(lock("param1", "param2", d::getResult))
    }
    
    5、Elvis操作符(?:)

    如果 ?: 左侧表达式非空,返回其左侧表达式,否则返回右侧表达式

    java
            String str = null;
            int n = -1;
            if (null != str && str.length() > 0) {
                n = str.length();
            }
            int i = null != str ? str.length() : -1;
    
    kotlin
            var str: String? = null
            val n: Int = if (str != null) str.length else -1
            val i = str?.length ?: -1
    
    6、_(下划线)
    作为lambda函数的参数名称
    fun main(args: Array<String>) {
    
        val aa = mapOf(1 to "a",2 to "B")
    
        aa.forEach { key, value -> println("value:$value") 
    }
    

    在上述示例中,只是用到了value值,key并没有用到。这样,我们就想不在声明key,那么就需要使用下划线字符(_)作为key替代,即:

    fun main(args: Array<String>) {
    
        val aa = mapOf(1 to "a",2 to "B")
    
        aa.forEach { _, value -> println("value:$value") 
    }
    
    解构声明 中使用

    所谓的解构声明就是将一个对象解构(destructure)为多个变量,

    data class Book(var id: Int, var name: String, var desc: String)
    fun main(args: Array<String>) {
            val book = Book(12, "英语","描述")
            val (id,_,desc) = book
            println("id=$id,desc=$desc")
    }
    
    数字 中使用

    Kotlin的数字面值可以使用下划线来分隔数值进行分组

    fun main(args: Array<String>) {
       val oneMillion = 1_000_000
       val hexBytes = 0xFF_EC_DE_5E
        // Log: 1000000
        println(oneMillion)
        // Log: ffecde5e
        println(hexBytes.toString(16))
    }
    

    相关文章

      网友评论

        本文标题:kotlin-4-其他

        本文链接:https://www.haomeiwen.com/subject/kvchjqtx.html