zoukankan      html  css  js  c++  java
  • Android自定义ScrollView分段加载大文本数据到TextView

    以下内容为原创,转载时请注明链接地址: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.com
    11  * Date: 13-9-6
    12  * Time: 下午2:06
    13  */
    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     @Override
    32     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      * @return
    74      */
    75     public int getTotalVerticalScrollRange() {
    76         return this.computeVerticalScrollRange();
    77     }
    78 
    79     @Override
    80     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 l
    13      * @param t
    14      * @param oldl
    15      * @param oldt
    16      */
    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     @Override
    11     public void onScrollChanged(int l, int t, int oldl, int oldt) {}
    12 
    13     @Override
    14     public void onScrollTop() {}
    15 
    16     @Override
    17     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.com
    13  * Date: 13-9-6
    14  * Time: 上午11:34
    15  */
    16 public class AsyncTextLoadTask extends AsyncTask<Object, String, String> {
    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     @Override
    28     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 + "
    ");
    37                 index++;
    38             }
    39 
    40         } catch (IOException e) {
    41             e.printStackTrace();
    42         }
    43 
    44         return paragraph.toString();
    45     }
    46 
    47 
    48     @Override
    49     protected void onPreExecute() {
    50         super.onPreExecute();
    51     }
    52 
    53     @Override
    54     protected void onPostExecute(String result) {
    55         super.onPostExecute(result);
    56         activity.contentTv.setText(result);
    57         new Handler().postDelayed(new Runnable() {
    58 
    59             @Override
    60             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     @Override
    28     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             @Override
    39             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     @Override
    64     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 <?xml version="1.0" encoding="utf-8"?>
     2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     3               android:orientation="vertical"
     4               android:layout_width="fill_parent"
     5               android:layout_height="fill_parent"
     6         >
     7     <com.wangjie.bigtextloadtest.BorderScrollView
     8             android:id="@+id/contentScroll"
     9             android:layout_width="fill_parent"
    10             android:layout_height="fill_parent"
    11             >
    12         <LinearLayout
    13                 android:orientation="vertical"
    14                 android:layout_width="fill_parent"
    15                 android:layout_height="fill_parent"
    16                 >
    17             <TextView
    18                     android:layout_width="fill_parent"
    19                     android:layout_height="wrap_content"
    20                     android:text="asdfasdf"
    21                     />
    22             <TextView
    23                     android:id="@+id/content"
    24                     android:layout_width="fill_parent"
    25                     android:layout_height="wrap_content"
    26                     android:text="Hello World, MainActivity"
    27                     />
    28         </LinearLayout>
    29 
    30     </com.wangjie.bigtextloadtest.BorderScrollView>
    31 
    32 
    33 </LinearLayout>
  • 相关阅读:
    kubernetes 在pod内无法ping通servicename和ClusterIP的解决方法
    最小安装的服务器怎么使用nm-connection-editor
    CentOS 系统升级系统内核版本
    kubernetes学习资料
    Docker学习笔记--(超详细)
    Cheat Engine 注入++: (密码=31337157)
    Jupyter-Notebook开机自启动
    kali远程桌面-krdp
    Win10 快捷方式小箭头及小盾牌如何替换
    NumPy学习心得(二)
  • 原文地址:https://www.cnblogs.com/tiantianbyconan/p/3311658.html
Copyright © 2011-2022 走看看