2

I'm building a note application that must be able to display long texts (10000+ characters)

According to Best practices for text on Android (Google I/O '18), I followed some tips to achieve that:

  • Break huge texts into parts and display them using recyclerview
  • Prefetch Text with PrecomputedTextCompat

My code is looking like this:

inner class DescriptionViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

        private val textView: AppCompatTextView = itemView.adapter_description_text

        fun bindView(descriptionModel: NoteUIModel.DescriptionModel) {
            textView.setTextColor(displayTextColor)

            textView.setTextFuture(PrecomputedTextCompat.getTextFuture(
                descriptionModel.descriptionCell.description,
                TextViewCompat.getTextMetricsParams(textView),
                null
            ))
        }
    }
    with (note_details_recycler) {
        layoutManager = LinearLayoutManager(requireContext(), LinearLayoutManager.VERTICAL, false)
        adapter = mAdapter
    }

    viewModel.viewModelScope.launch {
        mAdapter.submitContent(NoteUIModel.fromNote(note))
    }

The problem:

companion object {
    suspend fun fromNote(note: Note): ArrayList<NoteUIModel> = withContext(Dispatchers.Default) {
        val list: ArrayList<NoteUIModel> = arrayListOf()
        
        val words = note.description.split(" ", ignoreCase = true)
        val paragraphs = words.chunked(30)
        
        paragraphs.forEach { 
            list.add(
                DescriptionModel(
                    DescriptionCell(
                        it.joinToString().replace(",", "")
                    )
                )
            )
        }

        list.add(DateModel(DateCell(note.timestamp)))
        list.add(TagsModel(TagsCell(note.tags)))
        list
    }
}

I'll need an algorithm like that to break the text preventing words from being divided into 2 views.

I'm still having delay and a little bit of stuttering to display the texts

The question is:

  • Is that still worth to have an algorithm making operation across the entire text anyway?
  • There is a cheaper way to break the text?
marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
LLL
  • 101
  • 4

1 Answers1

0

I am not sure how text editors work in general, but I think they rely on the newline character to split (large) text. The space between 2 views can be used to represent a newline.

You can also read line by line and add to ArrayList<NoteUIModel> as soon as you finished reading a single line to avoid initial delay.

If you can't rely on \n, I think you will need to keep track of when the width of a string exceeds the width of the device. If you know that the next word will be displayed in a new line anyway, you can safely put it in another view.

However, I am not sure how slow this approach is and if you can simply "cache" the width of each character width("a") + width("b") == width("ab") to avoid doing expensive computations often.

BPDev
  • 397
  • 1
  • 9