Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 198aff0a authored by Fahim Salam Chowdhury's avatar Fahim Salam Chowdhury 👽
Browse files

5022-Fix_mailListItem_flicker_issue

parent b51e0cbd
Loading
Loading
Loading
Loading
+2 −20
Original line number Diff line number Diff line
@@ -7,9 +7,7 @@ import android.graphics.Color
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.text.Spannable
import android.text.SpannableStringBuilder
import android.text.style.AbsoluteSizeSpan
import android.text.style.ForegroundColorSpan
import android.text.style.StyleSpan
import android.view.LayoutInflater
import android.view.View
@@ -47,7 +45,6 @@ class MessageListAdapter internal constructor(
    private val forwardedIcon: Drawable = theme.resolveDrawableAttribute(R.attr.messageListForwarded)
    private val answeredIcon: Drawable = theme.resolveDrawableAttribute(R.attr.messageListAnswered)
    private val forwardedAnsweredIcon: Drawable = theme.resolveDrawableAttribute(R.attr.messageListAnsweredForwarded)
    private val previewTextColor: Int = theme.resolveColorAttribute(R.attr.messageListPreviewTextColor)
    private val activeItemBackgroundColor: Int = theme.resolveColorAttribute(R.attr.messageListActiveItemBackgroundColor)
    private val selectedItemBackgroundColor: Int = theme.resolveColorAttribute(R.attr.messageListSelectedBackgroundColor)
    private val readItemBackgroundColor: Int = theme.resolveColorAttribute(R.attr.messageListReadItemBackgroundColor)
@@ -183,7 +180,6 @@ class MessageListAdapter internal constructor(
            if (appearance.previewLines > 0) {
                val preview = getPreview(isMessageEncrypted, previewText)
                holder.preview.setText(preview, TextView.BufferType.SPANNABLE)
                formatPreviewText(holder.preview)
            } else {
                holder.preview.visibility = GONE
            }
@@ -216,20 +212,6 @@ class MessageListAdapter internal constructor(
        addBeforePreviewSpan(displayText, displayText.length, messageRead)
    }

    private fun formatPreviewText(
        preview: TextView
    ) {
        val previewText = preview.text as Spannable

        // Set span (color) for preview message
        previewText.setSpan(
            ForegroundColorSpan(previewTextColor),
            0,
            previewText.length,
            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }

    private fun addBeforePreviewSpan(text: Spannable, length: Int, messageRead: Boolean) {
        val fontSize = if (appearance.senderAboveSubject) {
            appearance.fontSizes.messageListSubject
+0 −184
Original line number Diff line number Diff line
package com.fsck.k9.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Canvas
import android.text.Layout
import android.text.StaticLayout
import android.text.TextUtils.TruncateAt
import android.util.AttributeSet
import android.widget.TextView
import androidx.appcompat.widget.AppCompatTextView

class EllipsizingTextView : AppCompatTextView {
    interface EllipsizeListener {
        fun ellipsizeStateChanged(ellipsized: Boolean)
    }

    private val ellipsizeListeners: MutableList<EllipsizeListener> = ArrayList()
    var isEllipsized = false
        private set
    private var isStale = true
    private var programmaticChange = false
    private var fullText: String? = null
    private var customLineSpacingMultiplier = 1.0f
    private var lineAdditionalVerticalPadding = 0.0f

    constructor(context: Context?) : super(context!!) {}
    constructor(context: Context?, attrs: AttributeSet?) : super(context!!, attrs) {}
    constructor(context: Context?, attrs: AttributeSet?, defStyle: Int) : super(
        context!!, attrs, defStyle
    ) {
    }

    fun addEllipsizeListener(listener: EllipsizeListener?) {
        if (listener == null) {
            throw NullPointerException()
        }
        ellipsizeListeners.add(listener)
    }

    fun removeEllipsizeListener(listener: EllipsizeListener) {
        ellipsizeListeners.remove(listener)
    }

    override fun setLineSpacing(add: Float, mult: Float) {
        lineAdditionalVerticalPadding = add
        customLineSpacingMultiplier = mult
        super.setLineSpacing(add, mult)
    }

    override fun onTextChanged(text: CharSequence, start: Int, before: Int, after: Int) {
        super.onTextChanged(text, start, before, after)
        if (!programmaticChange) {
            fullText = text.toString()
            isStale = true
        }
    }

    override fun onDraw(canvas: Canvas) {
        if (isStale) {
            resetText()
        }
        super.onDraw(canvas)
    }

    @SuppressLint("DiscouragedPrivateApi")
    override fun getMaxLines(): Int {
        val textViewClassInstance = TextView::class.java
        try {
            val MaxMode = textViewClassInstance.getDeclaredField("mMaxMode")
            MaxMode.isAccessible = true
            val mMaxMode = MaxMode.getInt(this)
            val Maximum = textViewClassInstance.getDeclaredField("mMaximum")
            Maximum.isAccessible = true
            val mMaximum = Maximum.getInt(this)
            val LINES = textViewClassInstance.getDeclaredField("LINES")
            LINES.isAccessible = true
            val mLINES = LINES.getInt(this)
            return if (mMaxMode == mLINES) mMaximum else -1
        } catch (e: NoSuchFieldException) {
            e.printStackTrace()
        } catch (e: IllegalAccessException) {
            e.printStackTrace()
        } catch (e: IllegalArgumentException) {
            e.printStackTrace()
        }
        return -1
    }

    private fun resetText() {
        val maxLines = maxLines
        var workingText = fullText
        var ellipsized = false
        if (maxLines != -1) {
            val layout = createWorkingLayout(workingText)
            val originalLineCount = layout.lineCount
            if (originalLineCount > maxLines) {
                if (this.ellipsize == TruncateAt.START) {
                    workingText =
                        fullText!!.substring(layout.getLineStart(originalLineCount - maxLines - 1)).trim { it <= ' ' }
                    while (createWorkingLayout(ELLIPSIS + workingText).lineCount > maxLines) {
                        val firstSpace = workingText!!.indexOf(' ')
                        workingText = if (firstSpace == -1) {
                            workingText.substring(1)
                        } else {
                            workingText.substring(firstSpace + 1)
                        }
                    }
                    workingText = ELLIPSIS + workingText
                } else if (this.ellipsize == TruncateAt.END) {
                    workingText = fullText!!.substring(0, layout.getLineEnd(maxLines - 1)).trim { it <= ' ' }
                    while (createWorkingLayout(workingText + ELLIPSIS).lineCount > maxLines) {
                        val lastSpace = workingText!!.lastIndexOf(' ')
                        workingText = if (lastSpace == -1) {
                            workingText.substring(0, workingText.length - 1)
                        } else {
                            workingText.substring(0, lastSpace)
                        }
                    }
                    workingText = workingText + ELLIPSIS
                } else if (this.ellipsize == TruncateAt.MIDDLE) {
                    var shrinkLeft = false
                    val firstOffset = layout.getLineEnd(maxLines / 2)
                    val secondOffset = layout.getLineEnd(originalLineCount - 1) - firstOffset + 1
                    var firstWorkingText = fullText!!.substring(0, firstOffset).trim { it <= ' ' }
                    var secondWorkingText = fullText!!.substring(secondOffset).trim { it <= ' ' }
                    while (createWorkingLayout(firstWorkingText + ELLIPSIS + secondWorkingText).lineCount > maxLines) {
                        if (shrinkLeft) {
                            shrinkLeft = false
                            val lastSpace = firstWorkingText.lastIndexOf(' ')
                            firstWorkingText = if (lastSpace == -1) {
                                firstWorkingText.substring(
                                    0, firstWorkingText.length - 1
                                )
                            } else {
                                firstWorkingText.substring(
                                    0, lastSpace
                                )
                            }
                        } else {
                            shrinkLeft = true
                            val firstSpace = secondWorkingText.indexOf(' ')
                            secondWorkingText = if (firstSpace == -1) {
                                secondWorkingText
                                    .substring(1)
                            } else {
                                secondWorkingText
                                    .substring(firstSpace + 1)
                            }
                        }
                    }
                    workingText = firstWorkingText + ELLIPSIS + secondWorkingText
                }
                ellipsized = true
            }
        }
        if (workingText != text) {
            programmaticChange = true
            text = try {
                workingText
            } finally {
                programmaticChange = false
            }
        }
        isStale = false
        if (ellipsized != isEllipsized) {
            isEllipsized = ellipsized
            for (listener in ellipsizeListeners) {
                listener.ellipsizeStateChanged(ellipsized)
            }
        }
    }

    private fun createWorkingLayout(workingText: String?): Layout {
        return StaticLayout(
            workingText, paint, width - paddingLeft - paddingRight,
            Layout.Alignment.ALIGN_NORMAL, customLineSpacingMultiplier, lineAdditionalVerticalPadding, false
        )
    }

    companion object {
        private const val ELLIPSIS = "..."
    }
}
 No newline at end of file
+2 −2
Original line number Diff line number Diff line
@@ -115,7 +115,7 @@
            android:textColor="@color/color_default_primary_text"
            tools:text="Message preview" />

        <com.fsck.k9.view.EllipsizingTextView
            <TextView
                android:id="@+id/preview"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
@@ -126,7 +126,7 @@
                android:layout_marginEnd="3dp"
                android:singleLine="false"
                android:textAppearance="@style/TextAppearance.K9.Small"
                android:textColor="@color/color_default_secondary_text"
                android:textColor="?messageListPreviewTextColor"
                android:longClickable="false"
                android:layout_alignWithParentIfMissing="false"
                android:gravity="top"