Skip to content

Commit

Permalink
base line span
Browse files Browse the repository at this point in the history
  • Loading branch information
ekibun committed May 18, 2020
1 parent 322345b commit 9b8dfd5
Show file tree
Hide file tree
Showing 8 changed files with 44 additions and 46 deletions.
10 changes: 3 additions & 7 deletions app/src/main/java/soko/ekibun/bangumi/ui/topic/ReplyDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import android.content.DialogInterface
import android.content.Intent
import android.provider.OpenableColumns
import android.text.Spanned
import android.text.style.ImageSpan
import android.view.KeyEvent
import android.view.MenuItem
import android.view.View
Expand All @@ -31,10 +30,7 @@ import soko.ekibun.bangumi.api.bangumi.Bangumi
import soko.ekibun.bangumi.ui.view.BaseDialog
import soko.ekibun.bangumi.util.HtmlUtil
import soko.ekibun.bangumi.util.ResourceUtil
import soko.ekibun.bangumi.util.span.ClickableImageSpan
import soko.ekibun.bangumi.util.span.ClickableUrlSpan
import soko.ekibun.bangumi.util.span.CollapseUrlDrawable
import soko.ekibun.bangumi.util.span.UploadDrawable
import soko.ekibun.bangumi.util.span.*
import java.lang.ref.WeakReference

/**
Expand Down Expand Up @@ -196,7 +192,7 @@ class ReplyDialog : BaseDialog(R.layout.dialog_reply) {
drawable.url = emojiList[position].second
view.item_input.editableText.insert(
view.item_input.selectionStart,
HtmlUtil.createImageSpan(ImageSpan(drawable, emojiList[position].first, ImageSpan.ALIGN_BASELINE))
HtmlUtil.createImageSpan(BaseLineImageSpan(drawable, emojiList[position].first))
)
drawable.container = WeakReference(view.item_input)
drawable.loadImage()
Expand Down Expand Up @@ -335,7 +331,7 @@ class ReplyDialog : BaseDialog(R.layout.dialog_reply) {
item_input.editableText.replace(start, end, "[img]$it[/img]")
}
}
val imageSpan = ImageSpan(drawable, ImageSpan.ALIGN_BASELINE)
val imageSpan = BaseLineImageSpan(drawable)
span = ClickableImageSpan(imageSpan, collapseImageGetter.onClick)
item_input.editableText.insert(
item_input.selectionStart,
Expand Down
25 changes: 10 additions & 15 deletions app/src/main/java/soko/ekibun/bangumi/util/HtmlUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import android.text.Spanned
import android.text.style.*
import android.util.Size
import android.view.View
import android.widget.EditText
import android.widget.TextView
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
Expand Down Expand Up @@ -71,27 +70,24 @@ object HtmlUtil {
fun attachToTextView(span: Spanned, textView: TextView) {
// 结束之前的请求
(textView.text as? Spanned)?.let { text ->
text.getSpans(0, text.length, ImageSpan::class.java).filterNot {
text.getSpans(0, text.length, BaseLineImageSpan::class.java).filterNot {
span.getSpanFlags(it) == 0
}.forEach {
(it.drawable as? UrlDrawable)?.cancel(textView)
it.drawable.cancel(textView)
}
}
// 更新引用
val weakRef = WeakReference(textView)
span.getSpans(0, span.length, ImageSpan::class.java).forEach { imageSpan ->
(imageSpan.drawable as? UrlDrawable)?.let {
span.getSpans(0, span.length, BaseLineImageSpan::class.java).forEach { imageSpan ->
imageSpan.drawable.let {
it.container = weakRef
it.loadImage()
}
}
span.getSpans(0, span.length, MaskSpan::class.java).forEach { maskSpan ->
maskSpan.textView = weakRef
}
// TODO 只有图片的时候补一个零宽字符,不然只有图片的时候会吃掉lineSpacing
textView.text = if (textView !is EditText && span.toString().trim('').isEmpty())
SpannableStringBuilder("\u200B").append(span)
else span
textView.text = span
}

private const val LINE_BREAK = "\n"
Expand Down Expand Up @@ -127,10 +123,9 @@ object HtmlUtil {
val sources = Bangumi.parseUrl(src)
val alt = node.attr("alt")
val isSmile = node.hasAttr("smileid")
val imageSpan = ImageSpan(
val imageSpan = BaseLineImageSpan(
imageGetter.getDrawable(sources),
if (isSmile) alt else src,
ImageSpan.ALIGN_BASELINE
if (isSmile) alt else src
)
createImageSpan(imageSpan).also {
if (!isSmile) {
Expand All @@ -152,7 +147,7 @@ object HtmlUtil {
return span
}

fun createImageSpan(imageSpan: ImageSpan): SpannableStringBuilder {
fun createImageSpan(imageSpan: BaseLineImageSpan): SpannableStringBuilder {
return SpannableStringBuilder("").also {
setSpan(imageSpan, it, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
}
Expand Down Expand Up @@ -207,10 +202,10 @@ object HtmlUtil {
) {
val drawables = ArrayList<String>()

open val onClick: (View, ImageSpan) -> Unit = { itemView, span ->
open val onClick: (View, BaseLineImageSpan) -> Unit = { itemView, span ->
PhotoPagerAdapter.showWindow(
itemView, drawables,
index = drawables.indexOf((span.drawable as UrlDrawable).url)
index = drawables.indexOf(span.drawable.url)
)
}

Expand Down
4 changes: 2 additions & 2 deletions app/src/main/java/soko/ekibun/bangumi/util/SpanFormatter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ abstract class SpanFormatter {
is ForegroundColorSpan -> return "${
String.format("[color=#%06X]", 0xFFFFFF and span.foregroundColor)}${inner()}[/color]"
is MaskSpan -> return "[mask]${inner()}[/mask]"
is ImageSpan -> return if (span.source?.startsWith("(") == true) span.source!!
else "[img]${span.source ?: (span.drawable as? UrlDrawable)?.url}[/img]"
is BaseLineImageSpan -> return if (span.source?.startsWith("(") == true) span.source!!
else "[img]${span.source ?: span.drawable.url}[/img]"
}
return inner()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package soko.ekibun.bangumi.util.span

import android.graphics.Paint
import android.text.style.ImageSpan

class BaseLineImageSpan(drawable: UrlDrawable, private val source: String? = null) :
ImageSpan(drawable, ALIGN_BASELINE) {
override fun getSource(): String? = source
override fun getDrawable(): UrlDrawable = super.getDrawable() as UrlDrawable
override fun getSize(paint: Paint, text: CharSequence?, start: Int, end: Int, fm: Paint.FontMetricsInt?): Int {
val ascent = fm?.ascent
val top = fm?.top
val descent = fm?.descent
val bottom = fm?.bottom
val width = super.getSize(paint, text, start, end, fm)
fm?.descent = descent
fm?.bottom = bottom
fm?.top = Math.min(fm?.top ?: 0, top ?: 0)
fm?.ascent = Math.min(fm?.ascent ?: 0, ascent ?: 0)
return width
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,21 @@
package soko.ekibun.bangumi.util.span

import android.text.style.ClickableSpan
import android.text.style.ImageSpan
import android.util.Log
import android.view.View

/**
*
*/
class ClickableImageSpan(
var image: ImageSpan,
private val onClick: (View, ImageSpan) -> Unit
var image: BaseLineImageSpan,
private val onClick: (View, BaseLineImageSpan) -> Unit
) : ClickableSpan() {
override fun onClick(widget: View) {
Log.v("click", image.drawable.toString())
val drawable = image.drawable
if (drawable is UrlDrawable) {
if (drawable.error == true) drawable.loadImage()
else if (drawable.error == false) onClick(widget, image)
} else onClick(widget, image)
if (drawable.error == true) drawable.loadImage()
else if (drawable.error == false) onClick(widget, image)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import android.graphics.*
import android.graphics.drawable.Animatable
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.style.ImageSpan
import android.util.Size
import android.view.View
import android.widget.TextView
Expand Down Expand Up @@ -35,7 +34,7 @@ open class CollapseUrlDrawable(

container?.get()?.let {
val text = (it.text as? Spannable) ?: return@let
text.getSpans(0, text.length, ImageSpan::class.java)?.filter { span ->
text.getSpans(0, text.length, BaseLineImageSpan::class.java)?.filter { span ->
span.drawable == this
}?.forEach { span ->
val start = text.getSpanStart(span)
Expand Down Expand Up @@ -82,7 +81,7 @@ open class CollapseUrlDrawable(
class CollapseImageGetter(container: TextView) : HtmlUtil.ImageGetter(wrapWidth = {
Math.min(container.width.toFloat(), Math.max(container.textSize, it))
}) {
override val onClick: (View, ImageSpan) -> Unit = { itemView, span ->
override val onClick: (View, BaseLineImageSpan) -> Unit = { itemView, span ->
Toast.makeText(
itemView.context,
span.source ?: (span.drawable as? UrlDrawable)?.url, Toast.LENGTH_LONG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import android.graphics.drawable.Animatable
import android.graphics.drawable.AnimationDrawable
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.style.ImageSpan
import android.widget.TextView
import java.lang.ref.WeakReference

Expand All @@ -26,7 +25,7 @@ open class TextViewDrawable : AnimationDrawable() {

container?.get()?.let {
val text = (it.text as? Spannable) ?: return@let
text.getSpans(0, text.length, ImageSpan::class.java)?.filter { span ->
text.getSpans(0, text.length, BaseLineImageSpan::class.java)?.filter { span ->
span.drawable == this
}?.forEach { span ->
val start = text.getSpanStart(span)
Expand Down
10 changes: 0 additions & 10 deletions app/src/main/res/layout/dialog_reply.xml
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,6 @@
android:layout_height="wrap_content"/>
</LinearLayout>

<TextView
android:visibility="invisible"
android:padding="12dp"
android:textSize="@dimen/textSizeMedium"
app:layout_constraintTop_toBottomOf="@+id/item_title_container"
app:layout_constraintBottom_toTopOf="@+id/item_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<com.awarmisland.android.richedittext.view.RichEditText
android:id="@+id/item_input"
android:layout_width="match_parent"
Expand All @@ -100,7 +91,6 @@
android:inputType="textMultiLine"
app:layout_constraintTop_toBottomOf="@+id/item_title_container"
app:layout_constraintBottom_toTopOf="@+id/item_buttons"
app:layout_constraintVertical_bias="1"
tools:ignore="LabelFor">

<requestFocus/>
Expand Down

0 comments on commit 9b8dfd5

Please sign in to comment.