intent中传入class需要java class
companion object {
fun start(context: Context) {
context.startActivity(Intent(context, ShoppingCartActivity::class.java))
}
}
定义
object CartContainer {
fun setCallBack(callback: Callback): CartContainer {
this.callback = callback
return this
}
}
单例调用
CartContainer.setCallBack()
对象集合某字段合并成字符串
合并prodCrowds集合中所有crowd对象crowdText 字段
fun getProdCrowdsName(): String =
prodCrowds.joinToString(",") { crowd -> crowd.crowdText }
一个类集合转另一个类集合
从Sku类集合list获取CartNumBody类集合
val list = adapter.list.map { SkuApi.CartNumBody(it.prodId, it.prodNum, true) }
集合统计double类型数据之和
统计skuList集合中sku的价格之和,这里使用BigDecimal来统计,直接使用+会有差错,sumByDouble{}
使用的是+操作。
var totalPrice = 0.0
skuList.asSequence()
.filter { it.isSelect }
.forEach { totalPrice = BigDecimalUtil.add(totalPrice, it.getTotalPrice()) }
BigDecimalUtil.add方法如下,传入BigDecimal需要转String类型,double类型似乎也会出些小差错。
public static double add(double value1, double value2) {
return new BigDecimal(String.valueOf(value1)).add(new BigDecimal(String.valueOf(value2))).doubleValue();
}
定义
data class Sku(
@SerializedName("prod_id") var prodId: Long = 0,
@SerializedName("prod_name") var prodName: String? = null) : Serializable {
//方法定义
}
克隆对象使用sku.copy()
可复制所有值,基本类型会复制,引用类型会使用引用地址,即使用的浅拷贝
不需要再定义多余接口,直接定义函数类型变量:
private var callback: (() -> Unit)? = null
定义set方法
fun setCallBack(callback: () -> Unit): CartContainer {
this.callback = callback
return this
}
调用上面的回调方法
callback?.let { it() }
设置回调,obj为上边定义回调的对象
obj.setCallBack { 方法体 }
定义
var onConfirmClickListener: ((categoryId: Long?, tagIdList: MutableList?, crowdIdList: MutableList?) -> Unit) ? = null
调用上面的回调方法
onConfirmClickListener?.let { it(categoryId, tagIdList, crowdIdList) }
设置回调,obj为上边定义回调的对象
obj.onConfirmClickListener = { categoryId, tagIdList, crowdIdList ->
mCategoryId = categoryId
mTagIdList = tagIdList
mCrowdIdList = crowdIdList
skuDrawerLayout.closeDrawers()
getData(Constants.PAGE_INDEX_START, mCategoryId, mTagIdList, mCrowdIdList)
skuSwipeRefreshLayout.isRefreshing = true
}
java类回调为接口
setOnConfirmClick(object : OnConfirmClick {
override fun onClick() {
方法体
}
})
java类回调为抽象类
setOnConfirmClick(object : OnConfirmClick() {
override fun onClick() {
方法体
}
})
定义变量
private lateinit var adapter: SkuAdapter
在任何可初始化方法中初始化,可初始化多次
adapter = SkuAdapter(activity)
延迟初始化,其在第一次使用时初始化,下面的lazy为函数
val mDialogManager: DialogManager by lazy {
DialogManager(this)
}
解析:上面lazy默认返回SynchronizedLazyImpl类实例,该对象持有属性value,get方法用懒加载方式实现,如下边代码,其实现是判断另一个属性_value是否初始化,已初始化返回值,否则调用initializer!!()即上面代码DialogManager(this)
,注意DialogManager(this)
实际上是()->DialogManager(this)
lambda表达式。我们使用mDialogManager变量实际上调用的是SynchronizedLazyImpl对象里的value.get()
方法
override val value: T
get() {
val _v1 = _value
if (_v1 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST")
return _v1 as T
}
return synchronized(lock) {
val _v2 = _value
if (_v2 !== UNINITIALIZED_VALUE) {
@Suppress("UNCHECKED_CAST") (_v2 as T)
}
else {
val typedValue = initializer!!()
_value = typedValue
initializer = null
typedValue
}
}
}
lazy函数可指定线程安全模式
- LazyThreadSafetyMode.SYNCHRONIZED
有同步锁,只会在一个线程初始化,因而时线程安全的
- LazyThreadSafetyMode.PUBLICATION
未初始化时可能会初始化多次,一旦初始化便不再初始化,其值只取第一次初始化的值
- LazyThreadSafetyMode.NONE
可能会初始化多次,多线程中行为不确定,建议只用于单个线程初始化
name变量初始化为abc
var name: String by Delegates.observable("abc") { property, oldValue, newValue ->
println("$property $oldValue->$newValue")
}
修改变量name为mz会调用上面observable的lambda表达式property, oldValue, newValue ->
println("$property $oldValue->$newValue")
name = "mz"
解析:oboservable返回ObservableProperty对象,该对象
内部实现了setValue方法,如下边代码,beforeChange永远返回true,所以afterChange会被调用,afterChange指向的是上边指定的lambda表达式property, oldValue, newValue -> println("$property $oldValue->$newValue")
public override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val oldValue = this.value
if (!beforeChange(property, oldValue, value)) {
return
}
this.value = value
afterChange(property, oldValue, value)
}
使用Delegates.vetoable可在属性值变更前做处理操作,传入的lambda表达式赋值给beforeChange函数,需要返回boole值,返回true时不修改该变量,返回false修改该变量
同样可以同时观察变更前和变更后做处理操作,beforeChange返回true时不会调用afterChange函数
var age: Int by object : ObservableProperty<Int>(25) {
override fun afterChange(property: KProperty<*>, oldValue: Int, newValue: Int) {
super.afterChange(property, oldValue, newValue)
println("$property $oldValue->$newValue")
}
override fun beforeChange(property: KProperty<*>, oldValue: Int, newValue: Int): Boolean {
println("$property $oldValue->$newValue")
return super.beforeChange(property, oldValue, newValue)
}
}
by关键字解析见文档 中 英
可定义在类体中、方法体中
fun refreshData() = getData(Constants.PAGE_INDEX_START, mCategoryId, mTagIdList, mCrowdIdList)
在Activity扩展showSnackBar方法,在Activity子类中可直接调用showSnackBar()方法
fun Activity.showSnackBar(view: View, msg: String, time: Int = Snackbar.LENGTH_SHORT) {
Snackbar.make(view, msg, time).show()
}
代码调用处 context.obtainString(R.id.text)
会替换成下边方法的方法体代码this.resources.getString(resId)
inline fun Context.obtainString(resId: Int): String = this.resources.getString(resId)
如下代码,内联函数不仅会去掉valid函数,也会去掉body函数替换成body函数体的代码,会使body不再是一个函数,因而无法用于下边定义的submit高阶函数参数
inline fun valid(lock: Lock, body: () -> T): T {
lock.lock()
try {
submit(body) //内联后body不是函数,无法传给submit函数
return body()
} finally {
lock.unlock()
}
}
//submit高阶函数
fun <T> submit(body: ()-> T){
}
可以使用noinline关键字禁止内联
inline fun valid(lock: Lock, noinline body: () -> T): T {
lock.lock()
try {
submit(body) //body禁止内联后可传入submit函数
return body()
} finally {
lock.unlock()
}
}
fun <T> submit(body: ()-> T){
}
添加依赖包
api "org.jetbrains.anko:anko-common:0.10.2"
Activity中代码
doAsync {
//子线程中执行
uiThread {
//UI线程中执行,如Activity销毁则不会执行
}
}