Android - How do you efficiently load a large amount of text in a TextView?
Asked Answered
A

5

14

I'm writing an Android app that reads a single text file and display it on a TextView.

What I'm doing right now is read the whole file into a String (using BufferedReader and StringBuilder) and display it on a TextView using setText(string). A 700KB text file can take about 2 to 3 seconds before it is being displayed on the screen.

But I've used some other ebook readers on the market and they can display the same text almost instantly. Anyone know how I can achieve this?

Thanks you.

Edit: Many suggest ListView, but it doesn't work for my particular case. This is from my reply to one of the answer: ...[ListView] doesn't work for me for a few reasons. (1) To make the Listview look like a TextView, we have to break the text up on new line character. If I load a single large paragraph, it's just as slow as a loading a TextView. (2) Since a ListView only measures the item on the screen, I cannot know ahead of time the total 'pages' or 'height' of the entire text.

Awed answered 29/1, 2013 at 16:39 Comment(0)
S
6

Essentially, the key is to only load the data that you need, when you need it. One way to do this would be to put every paragraph into it's own TextView, which is put into a ListAdapter, which is included into a ListView. There has to be some kind of an index set in place, such that each paragraph knows where in the data file to find. This interface will allow you to load only what you need, when you need it. Your list adapter looks something like this (This code isn't complete, but it should give you an idea at least of what you should do):

class ParagraphAdapter extends ListAdapter{
ArrayList<Integer> mLocations; // Somewhere define this to your locations, I'll leave that for you to figure out
protected View getView(int position,View convertView, ViewGroup parent)
{
  mLocations.get(position); // Read the file starting at this position, until the next value
  String text; // This is the output of the above
  TextView tv=new TextView(context);
  tv.setText(parent.getContext());
}
}

It can be noted that Amazon uses a system of paging for the Kindle App. If you have the app, you can see at the bottom of each page what section you are on. Each "page" is probably closer to a sentence or so in length. Then it's just a matter of getting the right page, which can fairly quickly be done.

Schuller answered 29/1, 2013 at 16:44 Comment(1)
I finally got some time to tackle the problem and this solution doesn't work for me for a few reasons. (1) To make the Listview look like a TextView, we have to break the text up on new line character. If I load a single large paragraph, it's just as slow as a loading a TextView. (2) Since a ListView only measures the item on the screen, I cannot know ahead of time the total 'pages' or 'height' of the entire text.Awed
H
2

To add on what @PearsonArtPhoto has said -

I suggest you implement some sort of paging mechanism, to divide your text into pages.
What you should do is split your text according to let's say N +M number of characters per pages.
N = fixed number of characters.
M = number of characters from N to nearest end of line character (so you won't see the last line being "cut").
I would suggest that if your android device allows you to hold this "in memory" -
do that,
and don't try to fetch this from the file one page after the other, but rather fetch from the "in memory" structure - this will improve performance.
Once you scroll and realize you need to fetch the next page, fetch it from the "in memory" structure.

Horsetail answered 29/1, 2013 at 16:47 Comment(0)
V
2

You can use Android Paging Library from Jetpack with custom View or RecyclerView

https://developer.android.com/topic/libraries/architecture/paging

  1. Implement DataSource abstraction that provides List of data ranges
  2. Implement Storage abstraction that provides real data (from Database, Network, Files, etc)
  3. Use RecyclerView and Adapter to display data

Sample app to display content of large files can be found here https://github.com/YablokovDmitry/FileView

Vaccination answered 22/7, 2019 at 10:8 Comment(0)
M
1

Lucas Rocha built a nice library called Smoothie for that purpose.

http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

At the end of those performance tips for Android listview there's a link to an explanation about Smoothie and finally you'll find the library available on github.

Originally described for loading images, the approach applies for loading text as well.

Mixtec answered 3/11, 2015 at 19:13 Comment(1)
Welcome to SO! Consider improving the quality of your answer and helping it stand on its own (i.e. if the link no longer works) by demonstrating how to apply the library for which you provided a link to the problem at hand.Coppice
O
0

You must to consider if you are using right components. Maybe it is mutch better to read lines and put them to listview.

try

List<String> lines; 
listview.adapter(new ArrayAdapter<String>(...,lines));

And many times that what you see (Look and Feel) is not like you are think.

Oolite answered 29/1, 2013 at 18:1 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.