《转载》Android大TXT文本文档读取(1)

原文地址:http://wangliping.net/read-big-txt

 

由于现在TXT文本很多,特别是好多小说也是以这个文件格式出现,毕竟这个格式所占用不必要的空间比较小。像我这样的人就非常喜欢在手机上看小说, 经常下载好多的TXT格式小说存到手机上以便空闲时候看。于是乎也试图做了一下如何在Android上实现看大文本的txt文档。

 

  虽然现在类似的应用还真不少,不过个人看到的基本不公布源码,而公布源码的基本都是不能看大文本的,所以自己去实现了一下。现在只是粗 略实现了,实现方法是每次当滑动到屏幕底端时,从文件读2048字节出来显示到屏幕上。到屏幕底端再读是为了不给用户有刷屏的感觉,使用起来感觉不到只读 了2048字节出来,比较流畅。现在由于只是试验流畅性,所以只写了向下浏览的,而没有写往回读,也就是说往回翻是无效的。

  废话不多说,代码是王道。这个是主文件:

package net . wangliping . filemanager ;

import java.io.FileInputStream ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.nio.CharBuffer ;

import android.app.Activity ;
import android.net.Uri ;
import android.os.AsyncTask ;
import android.os.Bundle ;
import android.os.Handler ;
import android.os.Message ;
import android.text.TextUtils ;
import android.util.Log ;
import android.widget.ScrollView ;

import net.wangliping.test.R ;

public class TxtReader extends Activity implements
        RealTimeTextView . OnTextChangedListener {

    private static final String LOG_TAG = "TxtReader" ;
    private static final int SHOW_TXT = 1 ;

    private SwanTextView mTextShow ;
    private ScrollView mScrollView ;
    private String mStringShow = null ;

    private boolean mContinueRead = true ;
    private boolean mHaveNewText   = false ;
   
    private int mCurBottom = - 1 ;
    private int mNum = - 1 ;

    private final Handler mHandler = new Handler () {
        @Override
        public void handleMessage (Message msg ) {
            switch (msg . what ) {
            case SHOW_TXT:
                mTextShow . setText ((CharBuffer ) msg . obj );
                break ;
            default :
                super . handleMessage (msg );
            }
        }
    };

    public void onCreate (Bundle savedInstanceState ) {
        super . onCreate (savedInstanceState );
        setContentView (R . layout . txt_reader );

        Uri uri = getIntent (). getData ();

        mScrollView = (ScrollView ) findViewById (R . id . text_show_scroll );

        mTextShow = (RealTimeTextView ) findViewById (R . id . text_show );   
        mTextShow . setOnTextChangedListener (this );

        new TextShowTask (). execute (uri );
    }

    private void showText (Uri uri ) throws IOException , InterruptedException {
       
        InputStreamReader is = new InputStreamReader (new FileInputStream (
                uri . getPath ()), "GB2312" );
       
        StringBuilder sb = new StringBuilder ();
        char [] buf = new char [ 1024 * 2 ];
        while (true ) {
            if (mCurBottom == mScrollView . getScrollY ()) {
                Log . d (LOG_TAG , "curBtm:" + mCurBottom + " scroll:"
                        + mScrollView . getScrollY ());
               
                mCurBottom = - 1 ;
                mNum ++;
               
                if (mNum % 2 == 0 ) {
                    mContinueRead = true ;                   
                    Log . d (LOG_TAG , "YES" );
                }
            }
           
            if (mContinueRead && is . read (buf ) > 0 ) {
                mContinueRead = false ;

                if (sb. length () > 4096 ) {
                    sb. delete (0 , 2048 );
                   
                    Message msg = mHandler . obtainMessage (SHOW_TXT );               
                    msg . obj = CharBuffer . wrap (sb. toString ());
                    mHandler . sendMessage (msg );
                   
                    mStringShow = sb. append (buf ). toString ();
                    mHaveNewText = true ;
                } else {
                    while (sb. length () < 4096 ) {
                        sb. append (buf );
                        is . read (buf );
                    }

                    sb. append (buf );
                    Message msg = mHandler . obtainMessage (SHOW_TXT );
                    msg . obj = CharBuffer . wrap (sb. toString ());
                    mHandler . sendMessage (msg );
                }
            }
        }
    }

    private class TextShowTask extends AsyncTask < Object , Object , Object > {
        @Override
        protected void onPostExecute (Object param ) {
            Log . d (LOG_TAG , "Send broadcast" );
        }

        @Override
        protected Object doInBackground (Object ... params ) {
            Uri uri = (Uri ) params [ 0 ];

            try {
                showText (uri );
            } catch (Exception e ) {
                Log . d (LOG_TAG , "Exception" , e );
            }

            return null ;
        }
    }

    @Override
    public void onPreOnDraw (int bottom ) {        
        mCurBottom = bottom - mScrollView . getHeight ();
       
        if (mHaveNewText && ! TextUtils . isEmpty (mStringShow )) {
            mHaveNewText = false ;
           
            Message msg = mHandler . obtainMessage (SHOW_TXT );
            msg . obj = CharBuffer . wrap (mStringShow );
            mHandler . sendMessage (msg );
        }
    }
}

  这个为了得到TextView底部的位置而扩展了TextView类:

package net . wangliping . filemanager ;

import android.content.Context ;
import android.graphics.Canvas ;
import android.util.AttributeSet ;
import android.widget.TextView ;

public class SwanTextView extends TextView {

    private int mPreBottom = - 1 ;
    private OnTextChangedListener textChangedListener = null ;
   
    public SwanTextView (Context context ) {
        super (context );
    }

    public SwanTextView (Context context , AttributeSet attrs ) {
        super (context , attrs );
    }

    public SwanTextView (Context context , AttributeSet attrs ,
            int defStyle ) {
        super (context , attrs , defStyle );
    }
   
    @Override
    protected void onDraw (Canvas canvas ) {
       
        if (mPreBottom != getBottom ()) {
            mPreBottom = getBottom ();

            if (textChangedListener != null )
                textChangedListener . onPreOnDraw (mPreBottom );
        }

        super . onDraw (canvas );
    }
   
    public static interface OnTextChangedListener {
        public void onPreOnDraw (int bottom );
    }

    public void setOnTextChangedListener (OnTextChangedListener listener ) {
        textChangedListener = listener ;
    }
}

  这个就是资源文件了:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
    android:id= "@+id/text_show_linear" android:layout_width= "wrap_content"
    android:layout_height= "wrap_content" >
    <ScrollView android:id= "@+id/text_show_scroll"
        android:layout_width= "fill_parent" android:layout_height= "fill_parent" >
        <net.wangliping.filemanager.SwanTextView
            android:id= "@+id/text_show" android:layout_width= "fill_parent"
            android:layout_height= "wrap_content" android:scrollbars= "none" >
        </net.wangliping.filemanager.SwanTextView>
    </ScrollView>
</LinearLayout>

  代码不成熟,见笑了

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值