简体   繁体   English

Android - 如何在TextView中高效加载大量文本?

[英]Android - How do you efficiently load a large amount of text in a TextView?

I'm writing an Android app that reads a single text file and display it on a TextView . 我正在编写一个Android应用程序,它可以读取单个文本文件并将其显示在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) . 我现在正在做的是将整个文件读入一个String(使用BufferedReaderStringBuilder )并使用setText(string)TextView上显示它。 A 700KB text file can take about 2 to 3 seconds before it is being displayed on the screen. 一个700KB的文本文件可能需要大约2到3秒才能在屏幕上显示。

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. 编辑 :许多建议ListView,但它不适用于我的特定情况。 This is from my reply to one of the answer: ...[ListView] doesn't work for me for a few reasons. 这是我对其中一个答案的回复:... [ListView]由于某些原因对我不起作用。 (1) To make the Listview look like a TextView, we have to break the text up on new line character. (1)为了使Listview看起来像TextView,我们必须在新行字符上打破文本。 If I load a single large paragraph, it's just as slow as a loading a TextView. 如果我加载一个大段落,它就像加载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. (2)由于ListView仅测量屏幕上的项目,因此我无法提前知道整个文本的总“页面”或“高度”。

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. 一种方法是将每个段落放入它自己的TextView中,将其放入ListAdapter中,ListAdapter包含在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. 可以注意到,亚马逊使用Kindle应用程序的寻呼系统。 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. 然后,只需要获得正确的页面,这可以很快完成。

To add on what @PearsonArtPhoto has said - 添加@PearsonArtPhoto所说的内容 -

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 + M个字符数来分割你的文字。
N = fixed number of characters. N =固定的字符数。
M = number of characters from N to nearest end of line character (so you won't see the last line being "cut"). M =从N到最接近的行尾字符的字符数(因此您不会看到最后一行被“剪切”)。
I would suggest that if your android device allows you to hold this "in memory" - 我建议如果你的Android设备允许你把它“保存在内存中” -
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. 滚动并意识到需要获取下一页后,从“内存”结构中获取它。

Lucas Rocha built a nice library called Smoothie for that purpose. Lucas Rocha为此建立了一个名为Smoothie的漂亮图书馆。

http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/ 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. 在Android listview的那些性能提示的最后,有一个关于Smoothie的解释的链接,最后你会在github上找到该库。

Originally described for loading images, the approach applies for loading text as well. 最初描述用于加载图像,该方法也适用于加载文本。

You must to consider if you are using right components. 您必须考虑是否使用正确的组件。 Maybe it is mutch better to read lines and put them to listview. 也许读取行并将它们放到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. 很多时候你所看到的(外观和感觉)并不像你想的那样。

You can use Android Paging Library from Jetpack with custom View or RecyclerView 您可以使用Jetpack的Android Paging Library和自定义View或RecyclerView

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

  1. Implement DataSource abstraction that provides List of data ranges 实现提供数据范围列表的DataSource抽象
  2. Implement Storage abstraction that provides real data (from Database, Network, Files, etc) 实现存储抽象,提供真实数据(来自数据库,网络,文件等)
  3. Use RecyclerView and Adapter to display data 使用RecyclerView和Adapter显示数据

Sample app to display content of large files can be found here https://github.com/YablokovDmitry/FileView 可以在此处找到显示大文件内容的示例应用程序https://github.com/YablokovDmitry/FileView

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM