Android開源代碼解讀のOnScrollListener實現ListView滾屏時不加載數據

使用ListView過程中,如果滾動加載數據的操作比較費時,很容易在滾屏時出現屏幕卡住的現象,一個解決的辦法就是不要在滾動時加載數據,而是等到滾動停止後再進行數據的加載。這同樣要實現OnScrollListener接口,關於該接口的簡要描述見上一篇文章,這裡直接進行代碼的分析:
[java]
package hust.iprai.asce1885; 
 
import android.app.ListActivity; 
import android.content.Context; 
import android.os.Bundle; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.AbsListView; 
import android.widget.AbsListView.OnScrollListener; 
import android.widget.BaseAdapter; 
import android.widget.TextView; 
 
public class MainActivity extends ListActivity implements OnScrollListener { 
     
    private TextView mStatus; //顯示滾屏狀態 
    private boolean mBusy = false; //標識是否存在滾屏操作 
     
    /**
     * 自定義Adapter,實現ListView中view的顯示
     *
     */ 
    private class SlowAdapter extends BaseAdapter { 
        private LayoutInflater mInflater; 
         
        public SlowAdapter(Context context) { 
            mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
        } 
 
        /**
         * 列表中元素個數取決於數據的個數
         */ 
        public int getCount() { 
            return mStrings.length; 
        } 
 
        /**
         * 我們的模擬數據是從數組中獲取的,因此這裡直接返回索引值就可以獲取相應的數據瞭
         */ 
        public Object getItem(int position) { 
            return position; 
        } 
 
        /**
         * 使用數組的索引作為唯一的id
         */ 
        public long getItemId(int position) { 
            return position; 
        } 
 
        /**
         * 獲取List中每一行的view
         */ 
        public View getView(int position, View convertView, ViewGroup parent) { 
            TextView text; 
             
            //給text賦值 
            if (null == convertView) { 
                text = (TextView) mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); 
            } else { 
                text = (TextView) convertView; 
            } 
             
            if (!mBusy) { 
                //當前不處於加載數據的忙碌時期(沒有滾屏),則顯示數據 
                text.setText(mStrings[position]); 
                //這裡約定將tag設置為null說明這個view已經有瞭正確的數據 
                text.setTag(null); 
            } else { 
                //當前處於滾屏階段,不加載數據,直接顯示數據加載中提示 
                text.setText("Loading…"); 
                //tag非空說明這個view仍然需要進行數據加載並顯示 
                text.setTag(this); 
            } 
             
            return text; 
        } 
         
    } 
     
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 
        setContentView(R.layout.main); 
         
        mStatus = (TextView) findViewById(R.id.status); 
        mStatus.setText("Idle"); 
         
        //使用自定義的ListAdapter將數據映射到TextView中 
        setListAdapter(new SlowAdapter(this)); 
         
        //設置滾動監聽器 
        getListView().setOnScrollListener(this); 
    } 
 
    public void onScroll(AbsListView view, int firstVisibleItem, 
            int visibleItemCount, int totalItemCount) { 
         
    } 
 
    public void onScrollStateChanged(AbsListView view, int scrollState) { 
        switch (scrollState) { 
        case OnScrollListener.SCROLL_STATE_IDLE: //Idle態,進行實際數據的加載顯示 
            mBusy = false; 
             
            int first = view.getFirstVisiblePosition(); 
            int count = view.getChildCount(); 
            for (int i = 0; i < count; i++) { 
                TextView tv = (TextView) view.getChildAt(i); 
                if (tv.getTag() != null) { //非null說明需要加載數據 
                    tv.setText(mStrings[first + i]); 
                    tv.setTag(null); 
                } 
            } 
             
            mStatus.setText("Idle"); 
            break;   
        case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: 
            mBusy = true; 
            mStatus.setText("Touch Scroll"); 
            break; 
        case OnScrollListener.SCROLL_STATE_FLING: 
            mBusy = true; 
            mStatus.setText("Fling"); 
            break; 
        default: 
            mStatus.setText("Are you kidding me!"); 
            break; 
        } 
    } 
     
    private String[] mStrings = { 
            "Abbaye de Belloc", "Abbaye du Mont des Cats", "Abertam", 
            "Abondance", "Ackawi", "Acorn", "Adelost", "Affidelice au Chablis", 
            "Afuega'l Pitu", "Airag", "Airedale", "Aisy Cendre", 
            "Allgauer Emmentaler", "Alverca", "Ambert", "American Cheese", 
            "Ami du Chambertin", "Anejo Enchilado", "Anneau du Vic-Bilh", 
            "Anthoriro", "Appenzell", "Aragon", "Ardi Gasna", "Ardrahan", 
            "Armenian String", "Aromes au Gene de Marc", "Asadero", "Asiago", 
            "Aubisque Pyrenees", "Autun", "Avaxtskyr", "Baby Swiss", "Babybel", 
            "Baguette Laonnaise", "Bakers", "Baladi", "Balaton", "Bandal", 
            "Banon", "Barry's Bay Cheddar", "Basing", "Basket Cheese", 
            "Bath Cheese", "Bavarian Bergkase", "Baylough", "Beaufort", 
            "Beauvoorde", "Beenleigh Blue", "Beer Cheese", "Bel Paese", 
            "Bergader", "Bergere Bleue", "Berkswell", "Beyaz Peynir", 
            "Bierkase", "Bishop Kennedy", "Blarney", "Bleu d'Auvergne", 
            "Bleu de Gex", "Bleu de Laqueuille", "Bleu de Septmoncel", 
            "Bleu Des Causses", "Blue", "Blue Castello", "Blue Rathgore", 
            "Blue Vein (Australian)", "Blue Vein Cheeses", "Bocconcini", 
            "Bocconcini (Australian)", "Boeren Leidenkaas", "Bonchester", 
            "Bosworth"}; 
     
     

下面是佈局文件main.xml:
[html]
<?xml version="1.0" encoding="utf-8"?> 
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" 
    android:layout_width="match_parent"  
    android:layout_height="match_parent"> 
     
    <ListView android:id="@android:id/list" 
        android:layout_width="match_parent"  
        android:layout_height="0dip" 
        android:layout_weight="1" 
        android:drawSelectorOnTop="false"/> 
         
    <TextView android:id="@+id/status" 
        android:layout_width="match_parent"  
        android:layout_height="wrap_content" 
        android:paddingLeft="8dip" 
        android:paddingRight="8dip"/> 
         
</LinearLayout> 
程序運行結果如下圖所示:

摘自 ASCE1885

發佈留言