Android自定义ScrollView分段加载大文本数据到TextView
发布日期:2021-11-12 07:57:09 浏览次数:25 分类:技术文章

本文共 7752 字,大约阅读时间需要 25 分钟。

原文地址:http://www.cnblogs.com/tiantianbyconan/p/3311658.html

这是我现在碰到的一个问题,如果需要在TextView中加载大文本的时候,比如几M的txt文件时,TextView载入的时候会出现卡死的现象,甚至会出现异常等待退出出现。

解决办法之一就是通过“分段”或“分页”来显示数据,在TextView(嵌入在ScrollView之中实现了TextView的滚动)中滚动到底部的时候,再去加载下一部分的数据,依次类推,这样每次加载的数据相对来说都比较小,不会出现卡顿的现象。

遇到的问题是,如何监听ScrollView滚动的位置(滚动到顶部还是底部?)。

 

如下,通过自定义ScrollView类(BorderScrollView):

1 package com.wangjie.bigtextloadtest; 2  3 import android.content.Context; 4 import android.graphics.Rect; 5 import android.util.AttributeSet; 6 import android.widget.ScrollView; 7  8 /** 9  * Created with IntelliJ IDEA.10  * Author: wangjie  email:tiantian.china.2@gmail.com11  * Date: 13-9-612  * Time: 下午2:0613  */14 public class BorderScrollView extends ScrollView{15     private long millis;16     // 滚动监听者17     private OnScrollChangedListener onScrollChangedListener;18 19     public BorderScrollView(Context context) {20         super(context);21     }22 23     public BorderScrollView(Context context, AttributeSet attrs) {24         super(context, attrs);25     }26 27     public BorderScrollView(Context context, AttributeSet attrs, int defStyle) {28         super(context, attrs, defStyle);29     }30 31     @Override32     protected void onScrollChanged(int l, int t, int oldl, int oldt) {33         super.onScrollChanged(l, t, oldl, oldt);34 35         if(null == onScrollChangedListener){36             return;37         }38 39         long now = System.currentTimeMillis();40 41         // 通知监听者当前滚动的具体信息42         onScrollChangedListener.onScrollChanged(l, t, oldl, oldt);43 44         if(now - millis > 1000l){45             // 滚动到底部(前提:从不是底部滚动到底部)46             if((this.getHeight() + oldt) != this.getTotalVerticalScrollRange()47                     && (this.getHeight() + t) == this.getTotalVerticalScrollRange()){48 49                 onScrollChangedListener.onScrollBottom(); // 通知监听者滚动到底部50 51                 millis = now;52             }53         }54 55         // 滚动到顶部(前提:从不是顶部滚动到顶部)56         if(oldt != 0 && t == 0){57             onScrollChangedListener.onScrollTop(); // 通知监听者滚动到顶部58         }59 60 61     }62 63     public OnScrollChangedListener getOnScrollChangedListener() {64         return onScrollChangedListener;65     }66 67     public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {68         this.onScrollChangedListener = onScrollChangedListener;69     }70 71     /**72      * 获得滚动总长度73      * @return74      */75     public int getTotalVerticalScrollRange() {76         return this.computeVerticalScrollRange();77     }78 79     @Override80     protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {81         return 0; // 禁止ScrollView在子控件的布局改变时自动滚动82     }83 84 }

 

滚动监听器接口OnScrollChangedListener:

1 package com.wangjie.bigtextloadtest; 2  3 /** 4  * Created with IntelliJ IDEA. 5  * Author: wangjie  email:tiantian.china.2@gmail.com 6  * Date: 13-9-6 7  * Time: 下午2:53 8  */ 9 public interface OnScrollChangedListener {10     /**11      * 监听滚动变化12      * @param l13      * @param t14      * @param oldl15      * @param oldt16      */17     public void onScrollChanged(int l, int t, int oldl, int oldt);18 19     /**20      * 监听滚动到顶部21      */22     public void onScrollTop();23 24     /**25      * 监听滚动到底部26      */27     public void onScrollBottom();28 29 }

 

滚动监听器的空实现OnScrollChangedListenerSimple(简洁真正用时候的代码):

1 package com.wangjie.bigtextloadtest; 2  3 /** 4  * Created with IntelliJ IDEA. 5  * Author: wangjie  email:tiantian.china.2@gmail.com 6  * Date: 13-9-9 7  * Time: 下午2:39 8  */ 9 public class OnScrollChangedListenerSimple implements OnScrollChangedListener{10     @Override11     public void onScrollChanged(int l, int t, int oldl, int oldt) {}12 13     @Override14     public void onScrollTop() {}15 16     @Override17     public void onScrollBottom() {}18 }

 

异步加载分段文本(这里每次加载50行):

1 package com.wangjie.bigtextloadtest; 2  3 import android.content.Context; 4 import android.os.AsyncTask; 5 import android.os.Handler; 6 import android.view.View; 7  8 import java.io.*; 9 10 /**11  * Created with IntelliJ IDEA.12  * Author: wangjie  email:tiantian.china.2@gmail.com13  * Date: 13-9-614  * Time: 上午11:3415  */16 public class AsyncTextLoadTask extends AsyncTask
{17 private Context context;18 private MainActivity activity;19 private BufferedReader br;20 21 public AsyncTextLoadTask(Context context, BufferedReader br) {22 this.context = context;23 this.br = br;24 activity = (MainActivity)context;25 }26 27 @Override28 protected String doInBackground(Object... params) {29 StringBuilder paragraph = new StringBuilder();30 try {31 32 String line = "";33 34 int index = 0;35 while(index < 50 && (line = br.readLine()) != null){36 paragraph.append(line + "\n");37 index++;38 }39 40 } catch (IOException e) {41 e.printStackTrace();42 }43 44 return paragraph.toString();45 }46 47 48 @Override49 protected void onPreExecute() {50 super.onPreExecute();51 }52 53 @Override54 protected void onPostExecute(String result) {55 super.onPostExecute(result);56 activity.contentTv.setText(result);57 new Handler().postDelayed(new Runnable() {58 59 @Override60 public void run() {61 activity.contentScroll.scrollTo(0, 0); // 记载完新数据后滚动到顶部62 }63 }, 100);64 activity.isLoading = false;65 }66 67 }

 

真正使用分段加载数据Activity(这里加载一本小说《百年孤独》):

1 package com.wangjie.bigtextloadtest; 2  3 import android.app.Activity; 4 import android.content.Context; 5 import android.os.Bundle; 6 import android.widget.TextView; 7  8 import java.io.BufferedReader; 9 import java.io.IOException;10 import java.io.InputStream;11 import java.io.InputStreamReader;12 13 public class MainActivity extends Activity {14     public BorderScrollView contentScroll;15     public TextView contentTv;16 17     private BufferedReader br;18 19     private Context context;20 21     public boolean isLoading;22 23 24     /**25      * Called when the activity is first created.26      */27     @Override28     public void onCreate(Bundle savedInstanceState) {29         super.onCreate(savedInstanceState);30         setContentView(R.layout.main);31         context = this;32 33         contentTv = (TextView) findViewById(R.id.content);34         contentScroll = (BorderScrollView) findViewById(R.id.contentScroll);35         36         // 注册刚写的滚动监听器37         contentScroll.setOnScrollChangedListener(new OnScrollChangedListenerSimple(){38             @Override39             public void onScrollBottom() {40                 synchronized (MainActivity.class){41                     if(!isLoading){42                         isLoading = true;43                         new AsyncTextLoadTask(context, br).execute();44                     }45                 }46             }47         });48 49         try{50             InputStream is = context.getAssets().open("bngd.txt");51             br = new BufferedReader(new InputStreamReader(is));52 53             new AsyncTextLoadTask(context, br).execute();54 55         }catch(Exception ex){56             ex.printStackTrace();57         }58 59 60     }61 62 63     @Override64     protected void onDestroy() {65         super.onDestroy();66         if(null != br){67             try {68                 br.close();69             } catch (IOException e) {70                 e.printStackTrace();71             }72         }73     }74 75 }

 

贴上布局:

1 
2
7
12
17
22
28
29 30 31 32 33

转载地址:https://blog.csdn.net/happy_love1990/article/details/69487369 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:Android用户引导页实现,圆点实现动画效果
下一篇:给 Android 开发者的 RxJava 详解

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月06日 17时40分59秒