生成静态函数的三种方式:
原始java静态函数:
import android.content.res.Resources;
import android.util.DisplayMetrics;
import android.util.TypedValue;
public class Utils {
private static final DisplayMetrics displayMetrics = Resources.getSystem().getDisplayMetrics();
public static float dp2px(float dp) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics);
}
}
方式一:静态函数直接定义在文件当中
kotlin和java不同,它的函数、属性都可以直接定义在文件当中
新建Utils.kt文件,内容如下:
/**
* 方式一:直接在文件中声明顶级函数
* kotlin调用时:函数名
* java调用时:类名加Kt:例:类名Kt.函数名
*/
fun dp2px(dp: Float): Float {
val displayMetrics = Resources.getSystem().displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
我们在其他kotlin文件中需要使用该静态方式时,直接dp2px(6.0f)即可
dp2px(6.0f)
注意在java文件中使用dp2px则需要用类名.方法的方式调用,类名后面还要加上Kt
UtilsKt.dp2px(9.0f);
按照方式一写出来的就是顶层函数或者叫包级函数
方式二:静态函数定义在object类中
可以达到在kotlin中直接使用类名.函数的方式进行调用,在object类中,它会自动创建一个类,并且含有一个单例对象,后续调用类中的数据以及函数时都是通过这个单例对象进行访问的,因此在java代码中调用我们这个工具类时,需要添加leiming.INSTANCE后面才能访问到函数
/**
* 方式二:使用object类,里面函数和属性均为静态
* kotlin调用时:类名.函数名
* java调用时:类名加INSTANCE:例:ObUtils.INSTANCE.dp2px(6.0f);
*/
object ObUtils {
fun dp2px(dp: Float): Float {
val displayMetrics = Resources.getSystem().displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
fun toast(string: String?) {
toast(string, Toast.LENGTH_SHORT)
}
private fun toast(string: String?, duration: Int) {
Toast.makeText(getApplicationContext().applicationContext, string, duration)
}
}
当然使用上面的方式二也就是kotlin中创建单例的一种写法。
方式三:利用伴生对象
/**
* 方式三:利用伴生对象,伴生对象也是用object修饰
* kotlin调用时:类名.函数名:MyUtils.dp2px(66.0f)
* java调用时:类名加 Companion:例:MyUtils.Companion.dp2px(66.0f);
*/
class MyUtils {
companion object {
fun dp2px(dp: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics)
}
}
}
和方式二类似,使用java调用时需要添加leiming.Companion.函数名
三种方式整体对比如下:
import android.content.res.Resources
import android.util.TypedValue
import android.widget.Toast
import com.gala.basecore.utils.PluginEnv.getApplicationContext
/**
* 方式一:直接在文件中声明顶级函数
* kotlin调用时:函数名
* java调用时:类名加Kt:例:类名Kt.函数名
*/
fun dp2px(dp: Float): Float {
val displayMetrics = Resources.getSystem().displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
/**
* 方式二:使用object类,里面函数和属性均为静态
* kotlin调用时:类名.函数名
* java调用时:类名加INSTANCE:例:ObUtils.INSTANCE.dp2px(6.0f);
*/
object ObUtils {
fun dp2px(dp: Float): Float {
val displayMetrics = Resources.getSystem().displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
fun toast(string: String?) {
toast(string, Toast.LENGTH_SHORT)
}
private fun toast(string: String?, duration: Int) {
Toast.makeText(getApplicationContext().applicationContext, string, duration)
}
}
/**
* 方式三:利用伴生对象,伴生对象也是用object修饰
* kotlin调用时:类名.函数名:MyUtils.dp2px(66.0f)
* java调用时:类名加 Companion:例:MyUtils.Companion.dp2px(66.0f);
*/
class MyUtils {
companion object {
fun dp2px(dp: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics)
}
}
}
综合上述方案二、三均是利用了object类内部的静态单例,进而访问到了普通的方法,因为在kotlin中是没有静态这个概念的,如果需要的话需要在kotlin中object类方法上添加注解@JvmStatic,这样从java访问就可以不用添加INSTANCE或者Companion了;注意这个注解只有在函数外面是object修饰时才有用。使用完成后编译器会将这个函数变成java中真正的静态函数,如下:
//方式二:
object ObUtils {
fun dp2px(dp: Float): Float {
val displayMetrics = Resources.getSystem().displayMetrics
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, displayMetrics)
}
@JvmStatic
fun toast(string: String?) {
toast(string, Toast.LENGTH_SHORT)
}
@JvmStatic
private fun toast(string: String?, duration: Int) {
Toast.makeText(getApplicationContext().applicationContext, string, duration)
}
}
//方式三:
class MyUtils {
companion object {
@JvmStatic
fun dp2px(dp: Float): Float {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, Resources.getSystem().displayMetrics)
}
}
}