引言:本文仅记录自己项目中使用到的扩展类、则需使用!(均为kt文件)

一、ActivityExpand

/**

* 启动Activity

*/

fun AppCompatActivity.startPager(actClass: Class<*>) {

startActivity(Intent(this, actClass))

}

/**

* 启动Activity

*/

fun Context.startPager(actClass: Class<*>) {

startActivity(Intent(this, actClass))

}

/**

* 传递intent,启动Activity

*/

fun Context.startPager(intents: Intent, actClass: Class<*>) {

intents.setClass(this, actClass)

startActivity(intents)

}

/**

* 待餐传递

*/

fun Activity.startPager(intents: Intent, actClass: Class<*>) {

intents.setClass(this, actClass)

startActivity(intents)

}

使用:

 

二、ContextExand(兼容6.0 及一下老设备写法)

fun Context.getColors(@ColorRes id: Int) = ContextCompat.getColor(this, id)

fun Context.getDrawables(@DrawableRes id: Int) = ContextCompat.getDrawable(this, id)

三、DecimalExpand

fun String.fenToYuanByString() = BigDecimal(this).fenToYuanByNumber()

fun Int.fenToYuanByString() = BigDecimal(this).fenToYuanByNumber()

fun String.fenToYuanByStringNoZero(): String {

return try {

val result = BigDecimal(this).fenToYuanByNumber().toString()

result.subSequence(0, result.indexOf(".")).toString()

} catch (e: Exception) {

BigDecimal(this).fenToYuanByNumber().toString()

}

}

fun Int.fenToYuanByStringNoZero(): String {

return try {

val result = BigDecimal(this).fenToYuanByNumber().toString()

result.subSequence(0, result.indexOf(".")).toString()

} catch (e: Exception) {

BigDecimal(this).fenToYuanByNumber().toString()

}

}

fun BigDecimal.fenToYuanByNumber(): BigDecimal =

this.divide(BigDecimal(100), 2, RoundingMode.HALF_UP)

格式化money 保留2位数

四、FloatExpand(dp、sp像素转换)

fun Float.dp2Px() = ConvertUtils.dp2px(this).toFloat()

fun Float.px2Dp() = ConvertUtils.px2dp(this).toFloat()

fun Float.sp2Px() = ConvertUtils.sp2px(this).toFloat()

用到了第三方库(当然也可以不用、懒得折腾了):

implementation 'com.blankj:utilcodex:1.31.1'

使用: 

 

 

五、LongExpand

//格式化时间

fun Long.formatDate(format: String) = SimpleDateFormat(format, Locale.CHINA).format(Date(this))

/**

* this ==单位秒

* 返回对应的秒数 eg 1s 2s

*/

fun Long.formatSeconds(): String = when {

this <= 0 -> {

"00:00"

}

this < 60 -> {

format(Locale.getDefault(), "00:%02d", this % 60)

}

this < 3600 -> {

format(

Locale.getDefault(),

"%02d:%02d",

this / 60,

this % 60

)

}

else -> {

format(

Locale.getDefault(),

"%02d:%02d:%02d",

this / 3600,

this % 3600 / 60,

this % 60

)

}

}

六、ObjectExpand(对象转json字符串)

fun Any.toJson(): String {

return try {

GsonUtils.toJson(this)

} catch (e: Exception) {

""

}

}

七、StringExpand

/**

* 是否包含英文字母与数字

*/

fun String.isLetter(): Boolean {

val regex = "^[a-z0-9A-Z].*"

return this.matches(Regex(regex))

}

/**

* 是否包含英文字符

*/

fun String.isContainLetter(): Boolean {

val regex = ".*[a-zA-Z]+.*"

return Pattern.compile(regex, Pattern.CASE_INSENSITIVE or Pattern.DOTALL).matcher(this)

.matches()

}

/**

* 全部为英文字母?

*/

fun String.isAllLetter(): Boolean {

val regex = "[a-zA-Z]+"

return this.matches(Regex(regex))

}

/**

* 判断是否包含.0 .00的数据类型

* 整数

*/

fun String.convertInteger(): String {

val subs = splitToMutableList(".")

return if (subs.last() == "0") {

removeSuffix(".0")

} else if (subs.last() == "00") {

removeSuffix(".00")

} else {

this

}

}

/**

* 隐藏中间的手机号 188****7502

*/

fun String.hideMiddlePhone(): String {

val msg = replaceRange(3..6, "")

return StringBuilder(msg).apply {

for (index in 0..length) {

if (index == 3) {

insert(index, "****")

}

}

}.toString()

}

/**

* 隐藏身份证、

*/

fun String.hideIcCard(): String {

val last = this.length - 4

val msg = replaceRange(4..last, "")

return StringBuilder(msg).apply {

for (index in 0..length) {

if (index == 4) {

insert(index, "******")

}

}

}.toString()

}

//截取 根据表达式

fun String.splitToMutableList(regex: String) = split(regex).toMutableList()

/**

* 转为实体类对象

*/

fun String.toJsonObject(type: Class): T? {

return try {

GsonUtils.fromJson(this, type)

} catch (e: Exception) {

null

}

}

/**

* 转为list实体类对象

*/

fun String.toJsonListObject(type: Class): List? {

return try {

GsonUtils.fromJson?>(this, GsonUtils.getListType(type))

} catch (e: Exception) {

null

}

}

八、RecycleViewExpand

/**

* 是否滚动到底部

*/

fun RecyclerView.isSlideToBottom(): Boolean {

return this.computeVerticalScrollExtent() + this.computeVerticalScrollOffset() >= this.computeVerticalScrollRange()

}

fun RecyclerView.isSlideToTop(): Boolean {

return if (layoutManager is LinearLayoutManager) {

val firstItemPosition =

(layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()

firstItemPosition == 0

} else false

}

九、ViewExpand(包含了EditText、ScrollView、ImageView等)

fun View.showAnim(duration: Long, listener: AnimatorListenerAdapter?) {

ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).run {

this.duration = duration

addListener(listener)

start()

}

}

/**

* 隐藏动画

*/

fun View.hideAnim(duration: Long, listener: AnimatorListenerAdapter?): Animator {

return ObjectAnimator.ofFloat(this, "alpha", 1f, 0f).apply {

this.duration = duration

if (listener != null) {

addListener(listener)

}

start()

}

}

fun View.hideAnimate(duration: Long = 500, alpha: Float = 0f, listener: AnimatorListenerAdapter) {

this.animate().alpha(alpha).setDuration(duration).setListener(listener).start()

}

/**

* 扩大点击作用域

* @param expandTouch 扩大的点击区域

*/

fun View.setTouchDelegate(expandTouch: Int) {

try {

val parentView = this.parent as View

parentView.post {

val rect = Rect()

this.getHitRect(rect)

rect.top -= expandTouch

rect.bottom += expandTouch

rect.left -= expandTouch

rect.right += expandTouch

parentView.touchDelegate = TouchDelegate(rect, this)

}

} catch (e: Exception) {

}

}

/**

* 点击放大

* implementation 'com.github.SherlockGougou:BigImageViewPager:androidx-6.2.0'

*/

fun ImageView.clickBigger(uri: String, showDownBt: Boolean = true) {

setOnClickListener {

ImagePreview.getInstance().setContext(this.context).setImage(uri)// 图片

.setShowCloseButton(true)// 是否显示关闭按钮

.setShowDownButton(showDownBt)// 是否显示下载按钮

.setFolderName(

this.context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()

)// 设置下载到的文件夹名(保存到根目录)

.start()

}

}

/**

* 点击放大

*/

fun ImageView.clickBigger(

listUri: List, defaultIndex: Int = 0, showDownBt: Boolean = true

) {

setOnClickListener {

ImagePreview.getInstance().setContext(this.context).setImageList(listUri)// 图片

.setIndex(defaultIndex).setShowCloseButton(true)// 是否显示关闭按钮

.setShowDownButton(showDownBt)// 是否显示下载按钮

.setFolderName(

this.context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()

)// 设置下载到的文件夹名(保存到根目录)

.start()

}

}

/**

* 清除点击放大逻辑

*/

fun ImageView.clearClickBigger() {

setOnClickListener(null)

}

fun View.show() {

visibility = View.VISIBLE

}

fun View.hide() {

visibility = View.INVISIBLE

}

fun View.goneHide() {

visibility = View.GONE

}

/**

* 禁止输入空格 禁止后xml中的限制将失效。

* @param limitLength 限制文本输入长度

*/

fun EditText.noSpace(limitLength: Int = 1000) {

filters = arrayOf(object : InputFilter {

override fun filter(

source: CharSequence?, p1: Int, p2: Int, p3: Spanned?, p4: Int, p5: Int

): CharSequence? {

return when {

source.isNullOrBlank() -> ""

source.contains("\\n") -> {

source.toString().replace("\\n", "")

}

source.contains("\\b") -> {

source.toString().replace("\\b", "")

}

else -> null

}

}

}, InputFilter.LengthFilter(limitLength))

}

//禁止\n \b 符号

fun EditText.noSymbol(limitLength: Int = 1000) {

filters = arrayOf(object : InputFilter {

override fun filter(

source: CharSequence?, p1: Int, p2: Int, p3: Spanned?, p4: Int, p5: Int

): CharSequence? {

return when {

source?.contains("\\n") == true -> {

source.toString().replace("\\n", "")

}

source?.contains("\\b") == true -> {

source.toString().replace("\\b", "")

}

else -> null

}

}

}, InputFilter.LengthFilter(limitLength))

}

//只输入中文

fun EditText.onlyCN(limitLength: Int = -1) {

if (limitLength != -1) {

filters = arrayOf(object : InputFilter {

override fun filter(

source: CharSequence?, start: Int, end: Int, p3: Spanned?, p4: Int, p5: Int

): CharSequence? {

try {

for (index in start..end) {

return if (!isChinese(source?.get(index))) "" else source

}

} catch (e: Exception) {

}

return null

}

}, InputFilter.LengthFilter(10))

} else {

filters = arrayOf(object : InputFilter {

override fun filter(

source: CharSequence?, start: Int, end: Int, p3: Spanned?, p4: Int, p5: Int

): CharSequence? {

try {

for (index in start..end) {

return if (!isChinese(source?.get(index))) "" else source

}

} catch (e: Exception) {

}

return null

}

})

}

}

/**

* 判定输入汉字

*

* @param c

* @return

*/

fun isChinese(c: Char?): Boolean {

if (c == null) {

return false

}

val ub = Character.UnicodeBlock.of(c)

return ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub === Character.UnicodeBlock.GENERAL_PUNCTUATION || ub === Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub === Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS

}

/**

* 设置Hint字体大小

*/

fun EditText.setHintTextSize(hint: String, sizeSp: Int) {

val sp = SpannableString(hint).apply {

setSpan(

AbsoluteSizeSpan(sizeSp, true), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE

)

}

setHint(sp)

}

fun EditText.setHintTextSize(sizeSp: Int) {

val sp = SpannableString(hint).apply {

setSpan(

AbsoluteSizeSpan(sizeSp, true), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE

)

}

hint = sp

}

/**

* 设置过滤器、一般用于提现等金额操作、

* 保留两位小数

*/

fun EditText.formatMoney() {

filters = arrayOf(AmountInputFilter())

}

/**

* 限制输入小数位数

*/

fun EditText.limitInputNUm(numLimitLength:Int) {

filters = arrayOf(AmountInputFilter(numLimitLength))

}

fun EditText.clearFilter() {

filters = arrayOf()

}

class AmountInputFilter : InputFilter {

constructor()

constructor(numLimitLength: Int) {

this.numLimitLength = numLimitLength

}

/**

* 最大数字,我们取int型最大值

*/

val MAX_VALUE = Int.MAX_VALUE

/**

* 小数点后的数字的位数

*/

var numLimitLength = 2

var p: Pattern? = null

init {

//除数字以外的

p = Pattern.compile("[0-9]*")

}

override fun filter(

source: CharSequence,

start: Int,

end: Int,

dest: Spanned,

dstart: Int,

dend: Int

): CharSequence {

val oldtext = dest.toString()

//第一个输入.或者0,返回

if (dest.toString() == "" && source.isNotEmpty() && (source[0].toString() == "." || source[0].toString() == "0")) return ""

// 验证删除等按键 排除首字符.

if (TextUtils.isEmpty(source)

|| (TextUtils.isEmpty(oldtext)

&& source[0].toString() == ".")

) {

return ""

}

// 验证非数字或者小数点的情况

val m = p!!.matcher(source)

if (oldtext.contains(".")) {

// 已经存在小数点的情况下,只能输入数字

if (!m.matches()) {

return ""

}

} else {

// 未输入小数点的情况下,可以输入小数点和数字

if (!m.matches() && source != ".") {

return ""

}

}

// 验证输入金额的大小

if (source.toString() != "") {

val dold = (oldtext + source.toString()).toDouble()

if (dold > MAX_VALUE) {

return dest.subSequence(dstart, dend)

} else if (dold == MAX_VALUE.toDouble()) {

if (source.toString() == ".") {

return dest.subSequence(dstart, dend)

}

}

}

// 验证小数位精度是否正确

if (oldtext.contains(".")) {

val index = oldtext.indexOf(".")

val len = dend - index

// 小数位只能2位

if (len > numLimitLength) {

return dest.subSequence(dstart, dend)

}

}

return dest.subSequence(dstart, dend).toString() + source.toString()

}

}

/**

* 全局置灰

* 一般我们都知道图像是由一个一个像素点组成的,而像素点是通过RGBA(红绿蓝,透明度)来控制的,这个是数字方向的。

* 但是在我们早期的彩色电视机中,我们经常会调整彩电的色调,饱和度和亮度,其中色调就是物体的颜色,饱和度就是颜色的纯度,从0到100%来描述,亮度就是颜色的相对明暗程度。

* 既然饱和度为0就可以变成灰色,那么我们通过设置ColorMatrix然后给到Paint画笔。

*/

fun setWindowsViewGray(view: View) {

try {

val paint = Paint()

val cm = ColorMatrix()

cm.setSaturation(0f)

paint.colorFilter = ColorMatrixColorFilter(cm)

view.setLayerType(View.LAYER_TYPE_HARDWARE, paint)

} catch (e: Exception) {

e.printStackTrace()

} catch (e: Error) {

e.printStackTrace()

}

}

/**

* 恢复原色

*/

fun setWindowsViewPrimaryColor(view: View) {

try {

val paint = Paint()

val cm = ColorMatrix()

cm.setSaturation(1f)

paint.colorFilter = ColorMatrixColorFilter(cm)

view.setLayerType(View.LAYER_TYPE_HARDWARE, paint)

} catch (e: Exception) {

e.printStackTrace()

} catch (e: Error) {

e.printStackTrace()

}

}

/**

* 是否到底部

*/

fun ScrollView.isBottom() = (this.getChildAt(0).height - this.height == this.scrollY)

/**

* 是否到底部 带有误差

*/

fun ScrollView.isBottom(deviationPx: Int) =

((this.getChildAt(0).height - this.height) - deviationPx <= this.scrollY)

/**

* 滚动到顶部

*/

fun ScrollView.scrollTop() = this.fullScroll(ScrollView.FOCUS_UP)

/**

* 滚动到底部

*/

fun ScrollView.scrollBottom() = this.fullScroll(ScrollView.FOCUS_DOWN)

十、ImageView 使用Coil的扩展

依赖:

//coil 图片加载框架Kotlin 推荐

implementation("io.coil-kt:coil:1.1.1")

implementation("io.coil-kt:coil-gif:0.9.5")

//加载一个圆角为10dp的图片

/**

* corner.dp2Px() 也可以自行进行dp转换

* placeholder errorPic 、自行替换、展位图 及加载错误图

*/

fun ImageRequest.Builder.coilSet(

corner: Float = 10f,

@DrawableRes placeholder: Int = R.drawable.ic_qg_placeholder,

@DrawableRes errorPic: Int = R.drawable.ic_qg_placeholder,

scale: Scale = Scale.FILL

) {

placeholder(placeholder)

error(errorPic)

transformations(RoundedCornersTransformation(corner.dp2Px()))

scale(scale)

}

//corner.dp2Px()参考FloatExpand扩展函数

 使用:

val test_uri1 =

"https://img2020.cnblogs.com/blog/1289812/202005/1289812-20200509091913298-1286944090.png"

fun test1() {

val imageView = ImageView(this)

//加载一个圆角为10dp的图片

imageView.load(test_uri1) {

coilSet()

}

}

文章链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。