工作中用到了,翻译一下,原文地址:http://kotlinlang.org/docs/tutorials/android-plugin.html

作者:Yan Zhulanow

本教程介绍了Kotlin Android Extensions的使用,用以提高对Android开发的支持。

在本教程中,我们将介绍Kotlin Android Extensions插件使用所需的步骤,从而提高Android的开发体验。

View Binding

背景介绍

每一个Android程序猿都非常了解findViewById() 方法。毫无疑问,他会导致一些潜在的错误(如,强转异常)而且难以阅读和维护,非常令人讨厌。尽管有一些库可以解决这个问题,但是这些库都需要为每一个view 添加注解。

Kotlin Android Extensions插件使我们能够获得与其中一些库相同的体验,但是无需添加任何额外的代码。

例如下面的代码

// Using R.layout.activity_main from the 'main' source setimportkotlinx.android.synthetic.main.activity_main.*

classMyActivity:Activity(){overridefunonCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)

// Instead of findViewById(R.id.textView)

textView.setText("Hello, world!")

}

}

textView是Activity的扩展属性,它与activity_main.xml中声明的类型相同(所以它是一个TextView)

Kotlin Android Extensions 的使用

配置

在本教程中,我们将使用Gradle,但使用IntelliJ IDEA项目结构或Maven也可以完成相同的任务。有关设置Gradle以使用Kotlin的详细信息,请参阅使用Gradle。

Android扩展是IntelliJ IDEA和Android Studio的Kotlin插件的一部分。你不需要安装额外的插件。

你所需要做的就是在你module下的build.gradle文件中添加如下代码:

apply plugin:'kotlin-android-extensions'

导入合成的组件

它可以非常方便的一次导入所有合成的组件。

importkotlinx.android.synthetic.main..*

假如layout是activity_main.xml,那我们就导入 kotlinx.android.synthetic.main.activity_main.*

如果我们想调用View的一些属性,我们还应该导入 kotlinx.android.synthetic.main.activity_main.view.*.

这样,我们就可以调用调用相应的扩展组件,这些扩展组件是以XML文件中的View命名的属性。(就是view的id)例如下面的view
android:id="@+id/hello"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
就会有一个叫hello的属性:
activity.hello.text = "Hello World!"

实验功能

Android Extensions 插件包括几个实验功能,比如Parcelable生成器,这些功能还没有应用到生产环境,如果你想使用他们,需要打开实验模式。在build.gradle 中添加以下代码
androidExtensions {
experimental = true
}

视图界面的支持
Android Extensions 插件支持不同类型的视图界面,最基本的就是acitivity,fragment,view。
事实上,你可以把任意一个类变成视图界面,只要你实现LayoutContainer 接口
import kotlinx.android.extensions.LayoutContainer

class ViewHolder(override val containerView: View) : ViewHolder(containerView), LayoutContainer {
fun setup(title: String) {
itemTitle.text = "Hello World!"
}
}

注意,你需要打开实验模式来使用LayoutContainer

渠道支持
Android Extensions 插件支持Android 不同的渠道,比如你有一个free的渠道
android {
productFlavors {
free {
versionName "1.0-free"
}
}
}
你可以通过以下代码导入 free/res/layout/activity_free.xml 所有生成的属性
import kotlinx.android.synthetic.free.activity_free.*
在实验模式下,你可以指定任意一个变体的名字,不仅仅是渠道,例如freeDebug,FreeRelease

视图缓存
调用findviewbyid() 很耗时,尤其是在复杂多层次的视图界面里。所以Android Extensions 通过缓存视图来减少findviewbyid()的调用。
下面的例子,findviewbyid()只会被调用一次。
class MyActivity : Activity()

fun MyActivity.a() {
textView.text = "Hidden view"
textView.visibility = View.INVISIBLE
}
然而对于下面这种情况
fun Activity.b() {
textView.text = "Hidden view"
textView.visibility = View.INVISIBLE
}

我们不知道这个函数是否只会被我们的来源的活动或简单的Java活动调用。因此,即使前面的示例中的MyActivity实例作为接收者传递,我们也不使用缓存。

改变视图缓存策略
你可以全局或者针对某个界面的改变视图的缓存策略,这也需要打开实验模式
全局的视图缓存策略可以在build.gradle 中设置
androidExtensions {
defaultCacheImplementation = "HASH_MAP" // also SPARSE_ARRAY, NONE
}
默认情况下,Android Extensions 插件使用HashMap储存,您也可以切换到SparseArray,或者关闭储存, 当您仅使用Android扩展的Parcelable部分时,后者(SparseArray)特别有用。
同时,你也可以使用注解@ContainerOptions 改变某个界面的视图缓存策略

import kotlinx.android.extensions.ContainerOptions
@ContainerOptions(cache = CacheImplementation.NO_CACHE)
class MyActivity : Activity()

fun MyActivity.a() {
// findViewById() will be called twice
textView.text = "Hidden view"
textView.visibility = View.INVISIBLE
}
Parcelable
从Kotlin 1.1.4开始,Android Extensions 插件提供了Parcelable 实现生成器作为实验功能。
首先,启用Parcelable 支持 Apply the kotlin-android-extensions ,然后打开实验功能。

使用
使用@Parcelize 注解这个类,Parcelable就会自动实现
import kotlinx.android.parcel.Parcelize
@Parcelize
class User(val firstName: String, val lastName: String, val age: Int): Parcelable

@Parcelize 需要所有的属性在主构造方法中声明,如果在类中声明的话,Android Extensions 会发出警告。此外,如果某些主构造函数参数不是属性,则不能应用@Parcelize。
如果你的类需要更高级的序列化逻辑,你可以把它写在一个内部类中:

@Parcelize
data class Value(val firstName: String, val lastName: String, val age: Int) : Parcelable {
private companion object : Parceler {
override fun User.write(parcel: Parcel, flags: Int) {
// Custom write implementation
}

    override fun create(parcel: Parcel): User {        // Custom read implementation    }}

}
支持的属性类型
@Parcelize支持广泛的类型:
--基本类型,包括封箱的类型(Integer)
--Objects and enums;
--String, CharSequence;
--Exception;
--Size, SizeF, Bundle, IBinder, IInterface, FileDescriptor;
--SparseArray, SparseIntArray, SparseLongArray, SparseBooleanArray;
--所有的 Serializable (是的,Date 也支持) 和所有实现 Parcelable 的类;
--所有支持类型的集合: 比如 List (mapped to ArrayList), Set (mapped to LinkedHashSet), Map (mapped to LinkedHashMap);
--还包括一些具体实现的集合: ArrayList, LinkedList, SortedSet, NavigableSet, HashSet, LinkedHashSet, TreeSet, SortedMap, NavigableMap, HashMap, LinkedHashMap, TreeMap, ConcurrentHashMap;
--所有支持类型的数组
--所有支持类型为null的情况.

自定义Parcelers
假如你的类型不能直接支持,你可以写一个Parceler 映射
class ExternalClass(val value: Int)
object ExternalClassParceler : Parceler {
override fun create(parcel: Parcel) = ExternalClass(parcel.readInt())

override fun ExternalClass.write(parcel: Parcel, flags: Int) {    parcel.writeInt(value)}

}

可以使用@TypeParceler或@WriteWith注释应用外部parcelers
// Class-local parceler
@Parcelable
@TypeParceler()
class MyClass(val external: ExternalClass)

// Property-local parceler
@Parcelable
class MyClass(@TypeParceler() val external: ExternalClass)

// Type-local parceler
@Parcelable
class MyClass(val external: @WriteWith() ExternalClass)

更多相关文章

  1. GitHub上受欢迎的Android(安卓)UI Library
  2. Android(安卓)设置EditText的DrawableRight和DrawableLeft 的通
  3. 【Android(安卓)开发教程】纯编码实现UI
  4. android hasSystemFeature函数及系统特性配置
  5. Android实现ViewPager滑动播放视频,ViewPager+Fragment取消懒加载
  6. Android-->Android(安卓)原生支持圆角图片,圆角ImageView
  7. Android(安卓)Studio 上的 HttpClient 插件
  8. android 动画 ——视图动画(View Animation)
  9. Android(安卓)Browser 支持屏蔽webaudio的功能

随机推荐

  1. Android intent消息通知机制
  2. android流媒体框架介绍
  3. 定制android设备启动后进入的初始界面
  4. Android Studio配置Flutter遇到的问题及
  5. 在Android中使用Application保存全局变量
  6. android中动态给EditText获得焦点并弹起
  7. Google 发布 Android Design 网站
  8. Android本地视频播放器开发--ffmpeg解码
  9. Android -- Button(按钮)的几种监听方式
  10. android 模拟器键盘控制键不能用 以及 设