diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index f2b26f3..5a30cd4 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -38,6 +38,7 @@
+
\ No newline at end of file
diff --git a/app/src/main/java/luyao/util/ktx/ui/ExtActivity.kt b/app/src/main/java/luyao/util/ktx/ui/ExtActivity.kt
index e62c344..b9f3423 100644
--- a/app/src/main/java/luyao/util/ktx/ui/ExtActivity.kt
+++ b/app/src/main/java/luyao/util/ktx/ui/ExtActivity.kt
@@ -16,6 +16,7 @@ class ExtActivity : CommonListActivity() {
add(ItemBean("AppExt", ToastExtActivity::class.java))
add(ItemBean("CommonExt", CommonExtActivity::class.java))
add(ItemBean("IntentExt", IntentExtActivity::class.java))
+ add(ItemBean("KtxSpan",KtxSpanActivity::class.java))
add(ItemBean("ListenerExtActivity", ListenerExtActivity::class.java))
add(ItemBean("PermissionExt", PermissionExtActivity::class.java))
add(ItemBean("SharedPreferencesExt", SharedPreferencesActivity::class.java))
diff --git a/app/src/main/java/luyao/util/ktx/ui/KtxSpanActivity.kt b/app/src/main/java/luyao/util/ktx/ui/KtxSpanActivity.kt
new file mode 100644
index 0000000..678bbcc
--- /dev/null
+++ b/app/src/main/java/luyao/util/ktx/ui/KtxSpanActivity.kt
@@ -0,0 +1,41 @@
+package luyao.util.ktx.ui
+
+import android.graphics.Color
+import android.text.Layout
+import kotlinx.android.synthetic.main.activity_ktx_span.*
+import kotlinx.android.synthetic.main.title_layout.*
+import luyao.ktx.R
+import luyao.util.ktx.base.BaseActivity
+import luyao.util.ktx.core.span.KtxSpan
+
+/**
+ * Created by luyao
+ * on 2019/8/7 14:07
+ */
+class KtxSpanActivity : BaseActivity() {
+
+ override fun getLayoutResId() = R.layout.activity_ktx_span
+
+ override fun initView() {
+ mToolbar.title = "KtxSpan"
+ setKtxSpan()
+ }
+
+ override fun initData() {
+ }
+
+ private fun setKtxSpan() {
+ KtxSpan().with(spanTv).show {
+ text(
+ "SpanUtils",
+ foregroundColor = Color.YELLOW,
+ backgroundColor = Color.LTGRAY,
+ alignment = Layout.Alignment.ALIGN_CENTER
+ )
+ text("前景色", foregroundColor = Color.GREEN)
+ text("背景色", backgroundColor = Color.LTGRAY)
+ text("行高居中对齐", lineHeight = 2 * spanTv.lineHeight, backgroundColor = Color.LTGRAY)
+ text("字体大小", textSize = 40)
+ }
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/res/layout/activity_ktx_span.xml b/app/src/main/res/layout/activity_ktx_span.xml
new file mode 100644
index 0000000..d5bc516
--- /dev/null
+++ b/app/src/main/res/layout/activity_ktx_span.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/ktx/src/main/java/luyao/util/ktx/core/span/KtxLineHeightSpan.kt b/ktx/src/main/java/luyao/util/ktx/core/span/KtxLineHeightSpan.kt
new file mode 100644
index 0000000..0324a52
--- /dev/null
+++ b/ktx/src/main/java/luyao/util/ktx/core/span/KtxLineHeightSpan.kt
@@ -0,0 +1,51 @@
+package luyao.util.ktx.core.span
+
+import android.graphics.Paint
+import android.text.style.LineHeightSpan
+
+/**
+ * Created by luyao
+ * on 2019/8/7 16:07
+ */
+class KtxLineHeightSpan(val height: Int,val verticalAlignment:Int) : LineHeightSpan {
+
+ companion object{
+ val ALIGN_CENTER = 2
+ val ALIGN_TOP = 3
+ }
+
+
+ override fun chooseHeight(
+ text: CharSequence?,
+ start: Int,
+ end: Int,
+ spanstartv: Int,
+ lineHeight: Int,
+ fm: Paint.FontMetricsInt
+ ) {
+ var need = height - (lineHeight + fm.descent - fm.ascent - spanstartv)
+ if (need > 0) {
+ when (verticalAlignment) {
+ ALIGN_TOP -> fm.descent += need
+ ALIGN_CENTER -> {
+ fm.descent += need / 2
+ fm.ascent -= need / 2
+ }
+ else -> fm.ascent -= need
+ }
+ }
+ need = height - (lineHeight + fm.bottom - fm.top - spanstartv)
+ if (need > 0) {
+ when (verticalAlignment) {
+ ALIGN_TOP -> fm.bottom += need
+ ALIGN_CENTER -> {
+ fm.bottom += need / 2
+ fm.top -= need / 2
+ }
+ else -> fm.top -= need
+ }
+ }
+ }
+
+
+}
\ No newline at end of file
diff --git a/ktx/src/main/java/luyao/util/ktx/core/span/KtxSpan.kt b/ktx/src/main/java/luyao/util/ktx/core/span/KtxSpan.kt
index ffac7c0..19f7c86 100644
--- a/ktx/src/main/java/luyao/util/ktx/core/span/KtxSpan.kt
+++ b/ktx/src/main/java/luyao/util/ktx/core/span/KtxSpan.kt
@@ -1,9 +1,81 @@
package luyao.util.ktx.core.span
+import android.graphics.Typeface
+import android.text.Layout
+import android.text.SpannableStringBuilder
+import android.text.Spanned
+import android.text.style.*
+import android.widget.TextView
+
/**
* Created by luyao
* on 2019/8/6 16:46
*/
class KtxSpan {
+ private val LINE_SEPARATOR = System.getProperty("line.separator")
+ private var mText: CharSequence = ""
+ private var mTextSize : Int = -1
+ private var mLineHeight = -1
+ private var mForegroundColor = -1
+ private var mBackgroundColor = -1
+ private var isBold = false
+ private var mAlignment: Layout.Alignment? = null
+ private var mFlag = Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
+
+ lateinit var mTextView: TextView
+ val mSpanBuilder by lazy { SpannableStringBuilder() }
+
+ fun with(view: TextView): KtxSpan {
+ this.mTextView = view
+ return this
+ }
+
+ fun text(
+ text: CharSequence,
+ textSize:Int = -1,
+ lineHeight: Int = -1,
+ foregroundColor: Int = -1,
+ backgroundColor: Int = -1,
+ alignment: Layout.Alignment? = null
+ ): KtxSpan {
+ mText = "$text$LINE_SEPARATOR"
+ mTextSize = textSize
+ mLineHeight = lineHeight
+ mForegroundColor = foregroundColor
+ mBackgroundColor = backgroundColor
+ mAlignment = alignment
+ updateSpan()
+ return this
+ }
+
+ private fun updateSpan() {
+ if (mText.isEmpty()) return
+ val start = mSpanBuilder.length
+ mSpanBuilder.append(mText)
+ val end = mSpanBuilder.length
+
+ if (mTextSize != -1)
+ mSpanBuilder.setSpan(AbsoluteSizeSpan(mTextSize,true),start,end,mFlag)
+
+ if (mLineHeight != -1)
+ mSpanBuilder.setSpan(KtxLineHeightSpan(mLineHeight,KtxLineHeightSpan.ALIGN_CENTER), start, end, mFlag)
+
+ if (mForegroundColor != -1)
+ mSpanBuilder.setSpan(ForegroundColorSpan(mForegroundColor), start, end, mFlag)
+
+ if (mBackgroundColor != -1)
+ mSpanBuilder.setSpan(BackgroundColorSpan(mBackgroundColor), start, end, mFlag)
+
+ if (isBold)
+ mSpanBuilder.setSpan(StyleSpan(Typeface.BOLD), start, end, mFlag)
+
+ mAlignment?.let { mSpanBuilder.setSpan(AlignmentSpan.Standard(it), start, end, mFlag) }
+ }
+
+ inline fun show(func: KtxSpan.() -> Unit): KtxSpan {
+ func()
+ mTextView.text = mSpanBuilder
+ return this
+ }
+}
-}
\ No newline at end of file
diff --git a/ktx/src/main/java/luyao/util/ktx/core/span/KtxTextSizeSpan.kt b/ktx/src/main/java/luyao/util/ktx/core/span/KtxTextSizeSpan.kt
new file mode 100644
index 0000000..0f82fe7
--- /dev/null
+++ b/ktx/src/main/java/luyao/util/ktx/core/span/KtxTextSizeSpan.kt
@@ -0,0 +1,46 @@
+package luyao.util.ktx.core.span
+
+import android.graphics.Canvas
+import android.graphics.Paint
+import android.text.style.ReplacementSpan
+
+/**
+ * Created by luyao
+ * on 2019/8/7 16:42
+ */
+class KtxTextSizeSpan(val textSize: Int, val verticalOffset: Int) : ReplacementSpan() {
+
+ private lateinit var mPaint: Paint
+
+ override fun getSize(paint: Paint, text: CharSequence?, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
+ mPaint = Paint(paint)
+ mPaint.textSize = textSize.toFloat()
+
+ fm?.let {
+ if (textSize > paint.textSize) {
+ val newFm = mPaint.fontMetricsInt
+ fm.descent = newFm.descent
+ fm.ascent = newFm.ascent
+ fm.top = newFm.top
+ fm.bottom = newFm.bottom
+ }
+ }
+
+ return mPaint.measureText(text, start, end).toInt()
+ }
+
+ override fun draw(
+ canvas: Canvas,
+ text: CharSequence,
+ start: Int,
+ end: Int,
+ x: Float,
+ top: Int,
+ y: Int,
+ bottom: Int,
+ paint: Paint
+ ) {
+ val baseLine = (y + verticalOffset).toFloat()
+ canvas.drawText(text, start, end, x, baseLine, mPaint)
+ }
+}
\ No newline at end of file