使用ListView過程中,如果滾動加載數據的操作比較費時,很容易在滾屏時出現屏幕卡住的現象,一個解決的辦法就是不要在滾動時加載數據,而是等到滾動停止後再進行數據的加載。這同樣要實現OnScrollListener接口,關於該接口的簡要描述見這篇文章(http://www.linuxidc.com/Linux/2012-02/54745.htm),這裡直接進行代碼的分析:
[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>
程序運行結果如下圖所示: