編輯:Android開發實例
這是我現在碰到的一個問題,如果需要在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:[email protected]
- * 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:[email protected]
- * 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:[email protected]
- * 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:[email protected]
- * 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>
轉自:http://www.cnblogs.com/tiantianbyconan/archive/2013/09/10/3311658.html
此方法適用於所有母控件無法獲取焦點的情況 開發中很常見的一個問題,項目中的listview不僅僅是簡單的文字,常常需要自己定義listview,自己的Adapte
繪制圓環其實很簡單,有大概以下三種思路. 這裡先說網上提到的一種方法。思路是先繪制內圓,然後繪制圓環(圓環的寬度就是paint設置的paint.setStroke
本文概述: 滑動解鎖九宮格的分析: 1、需要自定義控件; 2、需要重寫事件onTouchEvent(); 3、需要給九個點設置序號和坐標,這裡用
Android提供了許多方法來控制播放的音頻/視頻文件和流。其中該方法是通過一類稱為MediaPlayer。Android是提供MediaPlayer類訪問內置的媒體播放