閱讀576 返回首頁    go 阿裏雲 go 技術社區[雲棲]


Android逐條加載ListView,實現動畫更新

在Android應用中,如果ListView或是GridView裏麵的數據比較多的時候,加載會比較費時間,特別是裏麵有圖片的時候,需要花費的時間就更長,這樣就會出現一個長時間的等待黑屏界麵,這樣有時會給用戶造成一種錯覺,就是這個程序已經“死”了,,,

對於這個問題可以的一個方法是,添加一個ProgressDialog,顯示正在處理的窗口,等待加載完之後再關閉這個窗口,

但是這樣等所有的數據加載完之後,就是特別突然的顯示, 這樣用戶體驗也不佳,

以前看Android優化大師的時候,打開進程管理的時候,它是前麵顯示正在加載的ProgressDialog,然後也可以看到後台的數據正在逐條加載,這樣給人的感覺就好很多,現在就是要做這個效果~~~~

 

主要實現的思路是這樣的,新建一個線程,然後在線程裏麵獲取已經安裝的程序,再逐條把這些程序(數據)添加到緩衝數組中,再發送一個消息,更新顯示ListView的內容,當線程中所有的數據已經加載完的時候,再把ProgressDialog關掉,總的完成效果如下:




程序源代碼

    package com.sf.test;  
    import java.util.ArrayList;  
    import java.util.List;  
    import android.app.Activity;  
    import android.app.ProgressDialog;  
    import android.content.Context;  
    import android.content.Intent;  
    import android.content.pm.PackageManager;  
    import android.content.pm.ResolveInfo;  
    import android.os.Bundle;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.view.KeyEvent;  
    import android.widget.ArrayAdapter;  
    import android.widget.ListView;  
    /** 
     * @author Yao.GUET 
     * blog: https://blog.csdn.net/Yao_GUET 
     * 實現動態加載一個ListView 
     */  
    public class ProcessorBarTest extends Activity {  
        public static final int MSG_UPDATE_LIST = 18;  
          
        private ListView mApps;  
        private Context mContext;  
        private List<String> mAppList;  
        private ProgressDialog dialog;  
          
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            // TODO Auto-generated method stub  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.processorbar_test);  
              
            // ListView 列表 mApps  
            mApps = (ListView)findViewById(R.id.lvProcessbar);  
            mContext = this;  
            mAppList = new ArrayList<String>();  
              
            // 設置正在處理窗口  
            dialog = new ProgressDialog(mContext);  
            dialog.setIcon(R.drawable.icon);  
            dialog.setTitle("ProgressDialog");  
            dialog.setMessage("Please wait while loading application list...");  
            dialog.setCancelable(false);  
            dialog.show();  
              
            // 開始動態加載線程  
            mThreadLoadApps.start();  
        }  
          
        private Thread mThreadLoadApps = new Thread(){  
            @Override  
            public void run() {  
                int i = 0;  
                // TODO Auto-generated method stub  
                  
                // 獲取已經安裝程序列表  
                PackageManager pm = mContext.getPackageManager();  
                Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
                mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
                List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);  
                  
                // 逐項添加程序,並發送消息更新ListView列表。  
                for (i=0; i<list.size(); i++) {  
                    mAppList.add(list.get(i).loadLabel(pm).toString());  
                    handler.sendEmptyMessage(MSG_UPDATE_LIST);  
                }  
                // 關閉正在處理窗口  
                dialog.dismiss();  
            }  
              
        };  
          
        private Handler handler = new Handler(){  
            @Override  
            public void handleMessage(Message msg) {  
                // TODO Auto-generated method stub  
                switch (msg.what) {  
                case MSG_UPDATE_LIST:  
                    // 更新應用程序列表  
                    mApps.setAdapter(new ArrayAdapter(mContext,   
                            android.R.layout.simple_list_item_1, mAppList));  
                    break;  
                }  
                super.handleMessage(msg);  
            }  
        };  
    }  

後麵發現有效率更高的方法,其實不用每次更新一項都需要構建一個Adapter的,,,
把Adapter和一個List<?>綁定在一起之後,可以直接改變List<?>的內容,然後再使用Adapter的數據集更新通知,即可改變ListView的內容,所以後麵改了一下源碼變成這個樣子:

    package com.Yao_GUET.test;  
    import java.util.ArrayList;  
    import java.util.List;  
    import android.app.Activity;  
    import android.app.ProgressDialog;  
    import android.content.Context;  
    import android.content.Intent;  
    import android.content.pm.PackageManager;  
    import android.content.pm.ResolveInfo;  
    import android.os.Bundle;  
    import android.os.Handler;  
    import android.os.Message;  
    import android.view.View;  
    import android.widget.AdapterView;  
    import android.widget.ArrayAdapter;  
    import android.widget.ListView;  
    /** 
     * @author Yao.GUET 
     * blog: https://blog.csdn.net/Yao_GUET 
     * 實現動態加載一個ListView 
     */  
    public class ProcessorBarTest extends Activity {  
        public static final int MSG_UPDATE_LIST = 18;  
          
        private ListView mApps;  
        private Context mContext;  
        private List<String> mAppList;  
        private ProgressDialog dialog;  
        private ArrayAdapter mAdapter;  
        private boolean mIsLoaded = false;  
          
        @Override  
        protected void onCreate(Bundle savedInstanceState) {  
            // TODO Auto-generated method stub  
            super.onCreate(savedInstanceState);  
            setContentView(R.layout.processorbar_test);  
              
            // ListView 列表 mApps  
            mApps = (ListView)findViewById(R.id.lvProcessbar);  
            mContext = this;  
            mAppList = new ArrayList<String>();  
            mAdapter = new ArrayAdapter(mContext,   
                    android.R.layout.simple_list_item_1, mAppList);  
            mApps.setAdapter(mAdapter);  
              
            // 設置正在處理窗口  
            dialog = new ProgressDialog(mContext);  
            dialog.setIcon(R.drawable.icon);  
            dialog.setTitle("ProgressDialog");  
            dialog.setMessage("Please wait while loading application list...");  
            dialog.setCancelable(false);  
            dialog.show();  
              
            // 開始動態加載線程  
            mThreadLoadApps.start();  
              
            mApps.setOnItemClickListener(new AdapterView.OnItemClickListener(){  
                public void onItemClick(AdapterView<?> parent, View v, int position,  
                        long id) {  
                    // TODO Auto-generated method stub  
                    mAppList.remove(position);  
                    mAdapter.notifyDataSetChanged();  
                }  
                  
            });  
              
            // 獲取已經安裝程序列表  
            PackageManager pm = mContext.getPackageManager();  
            Intent mainIntent = new Intent(Intent.ACTION_MAIN, null);  
            mainIntent.addCategory(Intent.CATEGORY_LAUNCHER);  
            List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);  
              
            // 逐項添加程序,並發送消息更新ListView列表。  
            for (int i=0; i<list.size(); i++) {  
                mAppList.add(list.get(i).loadLabel(pm).toString());  
                mAdapter.notifyDataSetChanged();  
            }  
            mIsLoaded = true;  
        }  
          
        private Thread mThreadLoadApps = new Thread(){  
            @Override  
            public void run() {  
                int i = 0;  
                // TODO Auto-generated method stub  
                while (!mIsLoaded) {  
                    try {  
                        sleep(100);  
                    } catch (InterruptedException e) {  
                        e.printStackTrace();  
                    }  
                }  
                // 關閉正在處理窗口  
                dialog.dismiss();  
            }  
              
        };  
    }  



最後更新:2017-04-02 15:14:44

  上一篇:go 代碼之謎 - 其實,你不懂代碼
  下一篇:go Google到底有多強大