以下内容为原创,转载时请注明链接地址:http://www.cnblogs.com/tiantianbyconan/p/3311658.html

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

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

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

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

 package com.wangjie.bigtextloadtest;

 import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.ScrollView; /**
* Created with IntelliJ IDEA.
* Author: wangjie email:tiantian.china.2@gmail.com
* Date: 13-9-6
* Time: 下午2:06
*/
public class BorderScrollView extends ScrollView{
private long millis;
// 滚动监听者
private OnScrollChangedListener onScrollChangedListener; public BorderScrollView(Context context) {
super(context);
} public BorderScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} public BorderScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt); if(null == onScrollChangedListener){
return;
} long now = System.currentTimeMillis(); // 通知监听者当前滚动的具体信息
onScrollChangedListener.onScrollChanged(l, t, oldl, oldt); if(now - millis > 1000l){
// 滚动到底部(前提:从不是底部滚动到底部)
if((this.getHeight() + oldt) != this.getTotalVerticalScrollRange()
&& (this.getHeight() + t) == this.getTotalVerticalScrollRange()){ onScrollChangedListener.onScrollBottom(); // 通知监听者滚动到底部 millis = now;
}
} // 滚动到顶部(前提:从不是顶部滚动到顶部)
if(oldt != 0 && t == 0){
onScrollChangedListener.onScrollTop(); // 通知监听者滚动到顶部
} } public OnScrollChangedListener getOnScrollChangedListener() {
return onScrollChangedListener;
} public void setOnScrollChangedListener(OnScrollChangedListener onScrollChangedListener) {
this.onScrollChangedListener = onScrollChangedListener;
} /**
* 获得滚动总长度
* @return
*/
public int getTotalVerticalScrollRange() {
return this.computeVerticalScrollRange();
} @Override
protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
return 0; // 禁止ScrollView在子控件的布局改变时自动滚动
} }

滚动监听器接口OnScrollChangedListener:

 package com.wangjie.bigtextloadtest;

 /**
* Created with IntelliJ IDEA.
* Author: wangjie email:tiantian.china.2@gmail.com
* Date: 13-9-6
* Time: 下午2:53
*/
public interface OnScrollChangedListener {
/**
* 监听滚动变化
* @param l
* @param t
* @param oldl
* @param oldt
*/
public void onScrollChanged(int l, int t, int oldl, int oldt); /**
* 监听滚动到顶部
*/
public void onScrollTop(); /**
* 监听滚动到底部
*/
public void onScrollBottom(); }

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

 package com.wangjie.bigtextloadtest;

 /**
* Created with IntelliJ IDEA.
* Author: wangjie email:tiantian.china.2@gmail.com
* Date: 13-9-9
* Time: 下午2:39
*/
public class OnScrollChangedListenerSimple implements OnScrollChangedListener{
@Override
public void onScrollChanged(int l, int t, int oldl, int oldt) {} @Override
public void onScrollTop() {} @Override
public void onScrollBottom() {}
}

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

 package com.wangjie.bigtextloadtest;

 import android.content.Context;
import android.os.AsyncTask;
import android.os.Handler;
import android.view.View; import java.io.*; /**
* Created with IntelliJ IDEA.
* Author: wangjie email:tiantian.china.2@gmail.com
* Date: 13-9-6
* Time: 上午11:34
*/
public class AsyncTextLoadTask extends AsyncTask<Object, String, String> {
private Context context;
private MainActivity activity;
private BufferedReader br; public AsyncTextLoadTask(Context context, BufferedReader br) {
this.context = context;
this.br = br;
activity = (MainActivity)context;
} @Override
protected String doInBackground(Object... params) {
StringBuilder paragraph = new StringBuilder();
try { String line = ""; int index = 0;
while(index < 50 && (line = br.readLine()) != null){
paragraph.append(line + "\n");
index++;
} } catch (IOException e) {
e.printStackTrace();
} return paragraph.toString();
} @Override
protected void onPreExecute() {
super.onPreExecute();
} @Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
activity.contentTv.setText(result);
new Handler().postDelayed(new Runnable() { @Override
public void run() {
activity.contentScroll.scrollTo(0, 0); // 记载完新数据后滚动到顶部
}
}, 100);
activity.isLoading = false;
} }

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

 package com.wangjie.bigtextloadtest;

 import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.widget.TextView; import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader; public class MainActivity extends Activity {
public BorderScrollView contentScroll;
public TextView contentTv; private BufferedReader br; private Context context; public boolean isLoading; /**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context = this; contentTv = (TextView) findViewById(R.id.content);
contentScroll = (BorderScrollView) findViewById(R.id.contentScroll); // 注册刚写的滚动监听器
contentScroll.setOnScrollChangedListener(new OnScrollChangedListenerSimple(){
@Override
public void onScrollBottom() {
synchronized (MainActivity.class){
if(!isLoading){
isLoading = true;
new AsyncTextLoadTask(context, br).execute();
}
}
}
}); try{
InputStream is = context.getAssets().open("bngd.txt");
br = new BufferedReader(new InputStreamReader(is)); new AsyncTextLoadTask(context, br).execute(); }catch(Exception ex){
ex.printStackTrace();
} } @Override
protected void onDestroy() {
super.onDestroy();
if(null != br){
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
} }

贴上布局:

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.wangjie.bigtextloadtest.BorderScrollView
android:id="@+id/contentScroll"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="asdfasdf"
/>
<TextView
android:id="@+id/content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, MainActivity"
/>
</LinearLayout> </com.wangjie.bigtextloadtest.BorderScrollView> </LinearLayout>

Android自定义ScrollView分段加载大文本数据到TextView的更多相关文章

  1. Android 自定义ScrollView ListView 体验各种纵向滑动的需求

      分类: [android 进阶之路]2014-08-31 12:59 6190人阅读 评论(10) 收藏 举报 Android自定义ScrollView纵向拖动     转载请标明出处:http: ...

  2. android 自定义ScrollView实现背景图片伸缩(阻尼效果)

    android 自定义ScrollView实现强调内容背景图片伸缩(仿多米,qq空间背景的刷新) 看到一篇文章,自己更改了一下bug: 原文地址:http://www.aiuxian.com/arti ...

  3. JDBC 关于大文本数据

    大文本数据Clob,在不同的数据库中类型名不一致,有的是text格式,有的是clob,还有其他一些格式   package test; import java.io.BufferedReader; i ...

  4. android 自定义scrollview 仿QQ空间效果 下拉伸缩顶部图片,上拉回弹 上拉滚动顶部title 颜色渐变

    首先要知道  自定义scrollview 仿QQ效果 下拉伸缩放大顶部图片 的原理是监听ontouch事件,在MotionEvent.ACTION_MOVE事件时候,使用不同倍数的系数,重置布局位置[ ...

  5. Android自定义ScrollView实现一键置顶功能

    效果图如下: (ps:动态图有太大了,上传不了,就给大家口述一下要实现的功能吧) 要实现的功能:当ScrollView向上滑动超过一定距离后,就渐变的出现一个置顶的按钮,当滑动距离小于我们指定的距离时 ...

  6. pandas处理大文本数据

    当数据文件是百万级数据时,设置chunksize来分批次处理数据 案例:美国总统竞选时的数据分析 读取数据 import numpy as np import pandas as pdfrom pan ...

  7. Android 自定义ScrollView的滑动监听事件

    项目结构: 1.LazyScrollView类(自定义ScrollView) package android.zhh.com.myapplicationscrollview; /** * Create ...

  8. Android -- 自定义ScrollView实现放大回弹效果

    1,刚刚在别人开源的项目中看到了一个挺不错的用户体验,效果图如下: 2,那下面我们就来实现一下,首先看一下布局,由于一般只是我们包含头像的那部分方法,所以这里我们要把布局分成两部分,对应的布局文件效果 ...

  9. Android 自定义ScrollView(具有反弹效果的ScrollView,能够兼容横向的滑动)

    package com.itau.jingdong.widgets; import android.content.Context; import android.graphics.Rect; imp ...

随机推荐

  1. MAC与HMAC的介绍及其在AWS和Azure中的应用

    MAC 在密码学中,(消息认证码)Message Authentication Code是用来认证消息的比较短的信息.换言之,MAC用来保证消息的数据完整性和消息的数据源认证. MAC由消息本身和一个 ...

  2. 让微信扫描直接下载你的APK

    去年在做一个项目的时候,用微信扫描apk下载失效,显示空白页,网上找找发现在后面加一个字符串即可,于是简单搞定.过了一阵子,今年不行了,我的敏捷个人下载二维码也失效了,今天和大家说一下,现在如何解决这 ...

  3. 解决在IE中获取数据的缓存问题,运行环境为node.js

    IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,url是uri(统一资源定位符)的实例,url就是资源的标识符. 写一个demo进行验证,测试环境:IE8,node.j ...

  4. hibernate------java-delete-insert-update

    **************************************************************************************************** ...

  5. java servlet上传centos服务器

    前面一篇随笔说了Centos上架设javaWeb运行环境的方法,这篇主要讲打包上传服务器. 一.数据库连接文件.propeties 为了数据库安全,mysql3306端口访问我做了ip访问限制,由于m ...

  6. 对Java并发编程的几点思考

    1. Threads 和 Runnables 所有的现代操作系统都通过进程和线程来支持并发.进程是通常彼此独立运行的程序的实例,比如,如果你启动了一个Java程序,操作系统产生一个新的进程,与其他程序 ...

  7. 容器--Map和AbstractMap

    一.前言 前面我们介绍了Collection接口的定义及一系列实现,并重点介绍了List体系下的一些实现,对于Collection来说,其实还有Set系列同样很重要,但由于Set是依赖于Map实现的, ...

  8. CI框架源码阅读笔记2 一切的入口 index.php

    上一节(CI框架源码阅读笔记1 - 环境准备.基本术语和框架流程)中,我们提到了CI框架的基本流程,这里再次贴出流程图,以备参考: 作为CI框架的入口文件,源码阅读,自然由此开始.在源码阅读的过程中, ...

  9. rabbitmq connection/channel/consumer/queue的数量关系详细分析

    最近,MQ经常有丢包的现象,看各connection/channel/consumer/queue的组成情况,发现差别比较大. channel与消费者: [root@iZ23nn1p4mjZ bin] ...

  10. mysql登录时闪退的问题

    之前mysql用着好着,可是今天在启动mysql后输入密码出现了闪退,在任务管理器中发现mysql服务没有启动,当手动启动时提示拒绝访问.在网上查找原因发现问题所在. 问题原因:mysql服务没有安装 ...