Android中ListView数据处理优化

来源:互联网 发布:西南财经网络教育 编辑:程序博客网 时间:2024/05/29 11:06

来自:OPEN经验库

原帖:http://www.open-open.com/lib/view/open1330132229874.html

         Android 应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过 分页的形式来展示数据,个人觉得这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑 动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据。

           下面通过一个Demo来展示ListView功能如何实现:该Demo通过在ListView列表的底部添加一个“查看更多...”按钮来加载新闻(模拟 新闻客户端)分页数据。同时限定每次加载10条记录,但完全加载完数据后,就把ListView列表底部视图“查看更多...”删除。假设加载的数据总数 为 38 条记录。先看下该Demo工程的程序结构图:

Android中ListView分页加载数据

其中包 com.andyidea.bean中News.java类是新闻实体类,包com.andyidea.listview中 paginationListViewActivity.java类是用来展示ListView列表。布局layout中包含三个布局文件,分别 为:list_item.xml , loadmore.xml , main.xml 。下面分别贴下源码:

layout中的 list_item.xml源码:

 
01<spanstyle="font-size:13px;"><?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayout
03  xmlns:android="http://schemas.android.com/apk/res/android"
04  android:layout_width="fill_parent"
05  android:layout_height="fill_parent"
06  android:orientation="vertical">
07  <TextView
08     android:id="@+id/newstitle"
09     android:layout_width="fill_parent"
10     android:layout_height="wrap_content"/>
11  <TextView
12     android:id="@+id/newscontent"
13     android:layout_width="fill_parent"
14     android:layout_height="wrap_content"/>
15</LinearLayout></span>
layout中loadmore.xml源码:
 
01<?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayout
03  xmlns:android="http://schemas.android.com/apk/res/android"
04  android:layout_width="fill_parent"
05  android:layout_height="fill_parent">
06  <Button  
07      android:id="@+id/loadMoreButton"  
08      android:layout_width="fill_parent"  
09      android:layout_height="wrap_content"
10      android:text="查看更多..."/> 
11</LinearLayout>
layout中main.xml源码:
 
01<?xmlversion="1.0"encoding="utf-8"?>
02<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
03    android:orientation="vertical"
04    android:layout_width="fill_parent"
05    android:layout_height="fill_parent">
06    <ListView
07       android:id="@+id/lvNews"
08       android:layout_width="fill_parent"
09       android:layout_height="wrap_content"/>
10</LinearLayou
包 com.andyidea.bean中News.java类源码:
 
01package com.andyidea.bean;
02  
03/**
04 * 新闻实体类
05 * @author Andy.Chen
06 * @mail Chenjunjun.ZJ@gmail.com
07 *
08 */
09public class News {
10      
11    privateString title;    //标题
12    privateString content;  //内容
13      
14    publicString getTitle() {
15        returntitle;
16    }
17    publicvoid setTitle(String title) {
18        this.title = title;
19    }
20    publicString getContent() {
21        returncontent;
22    }
23    publicvoid setContent(String content) {
24        this.content = content;
25    }
26  
27}
包com.andyidea.listview中paginationListViewActivity.java类源码:
 
001package com.andyidea.listview;
002  
003import java.util.ArrayList;
004import java.util.List;
005  
006import com.andyidea.bean.News;
007  
008import android.app.Activity;
009import android.os.Bundle;
010import android.os.Handler;
011import android.util.Log;
012import android.view.View;
013import android.view.ViewGroup;
014import android.widget.AbsListView;
015import android.widget.AbsListView.OnScrollListener;
016import android.widget.BaseAdapter;
017import android.widget.Button;
018import android.widget.ListView;
019import android.widget.TextView;
020import android.widget.Toast;
021  
022public class PaginationListViewActivity extendsActivity implementsOnScrollListener {
023      
024    privateListView listView;  
025    privateint visibleLastIndex =0;   //最后的可视项索引  
026    privateint visibleItemCount;      // 当前窗口可见项总数  
027    privateint datasize = 38;          //模拟数据集的条数
028    privatePaginationAdapter adapter;  
029    privateView loadMoreView;  
030    privateButton loadMoreButton;  
031    privateHandler handler = newHandler(); 
032      
033    /** Called when the activity is first created. */
034    @Override
035    publicvoid onCreate(Bundle savedInstanceState) {
036        super.onCreate(savedInstanceState);
037        setContentView(R.layout.main);
038          
039        loadMoreView = getLayoutInflater().inflate(R.layout.loadmore,null);
040        loadMoreButton = (Button)loadMoreView.findViewById(R.id.loadMoreButton);
041        loadMoreButton.setOnClickListener(newView.OnClickListener() {
042              
043            @Override
044            publicvoid onClick(View v) {
045                loadMoreButton.setText("正在加载中...");  //设置按钮文字
046                handler.postDelayed(newRunnable() {
047                      
048                    @Override
049                    publicvoid run() {
050                        loadMoreData();
051                        adapter.notifyDataSetChanged();
052                        loadMoreButton.setText("查看更多..."); //恢复按钮文字
053                    }
054                },2000);
055                  
056            }
057        });
058          
059        listView = (ListView)findViewById(R.id.lvNews);
060        listView.addFooterView(loadMoreView);   //设置列表底部视图
061        initializeAdapter();
062        listView.setAdapter(adapter);
063        listView.setOnScrollListener(this);
064    }
065      
066    @Override
067    publicvoid onScrollStateChanged(AbsListView view,int scrollState) {
068        intitemsLastIndex = adapter.getCount()-1//数据集最后一项的索引  
069        intlastIndex = itemsLastIndex + 1;
070        if(scrollState == OnScrollListener.SCROLL_STATE_IDLE
071                && visibleLastIndex == lastIndex) {
072            // 如果是自动加载,可以在这里放置异步加载数据的代码
073        }
074    }
075  
076  
077    @Override
078    publicvoid onScroll(AbsListView view,int firstVisibleItem,
079            intvisibleItemCount, inttotalItemCount) {
080        this.visibleItemCount = visibleItemCount;
081        visibleLastIndex = firstVisibleItem + visibleItemCount -1;
082          
083        Log.e("========================= ","========================");
084        Log.e("firstVisibleItem = ",firstVisibleItem+"");
085        Log.e("visibleItemCount = ",visibleItemCount+"");
086        Log.e("totalItemCount = ",totalItemCount+"");
087        Log.e("========================= ","========================");
088          
089        //如果所有的记录选项等于数据集的条数,则移除列表底部视图
090        if(totalItemCount == datasize+1){
091            listView.removeFooterView(loadMoreView);
092            Toast.makeText(this,"数据全部加载完!", Toast.LENGTH_LONG).show();
093        }
094    }
095      
096    /**
097     * 初始化ListView的适配器
098     */
099    privatevoid initializeAdapter(){
100        List<News> news =new ArrayList<News>();
101        for(inti=1;i<=10;i++){
102            News items =new News();
103            items.setTitle("Title"+i);
104            items.setContent("This is News Content"+i);
105            news.add(items);
106        }
107        adapter =new PaginationAdapter(news);
108    }
109      
110    /**
111     * 加载更多数据
112     */
113    privatevoid loadMoreData(){
114        intcount = adapter.getCount();
115          
116        if(count+10<= datasize){
117            for(inti=count+1; i<=count+10; i++){
118                News item =new News();
119                item.setTitle("Title"+i);
120                item.setContent("This is News Content"+i);
121                adapter.addNewsItem(item);
122            }
123        }else{
124            for(inti=count+1; i<=datasize; i++){
125                News item =new News();
126                item.setTitle("Title"+i);
127                item.setContent("This is News Content"+i);
128                adapter.addNewsItem(item);
129            }
130        }
131          
132    }
133      
134      
135    classPaginationAdapter extendsBaseAdapter{
136          
137        List<News> newsItems;
138          
139        publicPaginationAdapter(List<News> newsitems){
140            this.newsItems = newsitems;
141        }
142  
143        @Override
144        publicint getCount() {
145            returnnewsItems.size();
146        }
147  
148        @Override
149        publicObject getItem(intposition) {
150            returnnewsItems.get(position);
151        }
152  
153        @Override
154        publiclong getItemId(intposition) {
155            returnposition;
156        }
157  
158        @Override
159        publicView getView(intposition, View view, ViewGroup parent) {
160            if(view ==null){
161                view = getLayoutInflater().inflate(R.layout.list_item,null);
162            }
163              
164            //新闻标题
165            TextView tvTitle = (TextView)view.findViewById(R.id.newstitle);
166            tvTitle.setText(newsItems.get(position).getTitle());
167            //新闻内容
168            TextView tvContent = (TextView)view.findViewById(R.id.newscontent);
169            tvContent.setText(newsItems.get(position).getContent());
170              
171            returnview;
172        }
173          
174        /**
175         * 添加数据列表项
176         * @param newsitem
177         */
178        publicvoid addNewsItem(News newsitem){
179            newsItems.add(newsitem);
180        }
181          
182    }
183  
184}


最后,运行程序的结果截图如下:

Android中ListView分页加载数据

通过上面的截图,当我们点击"查看更多..."按钮时,就会加载下10条记录,当加载完所有的记录后,ListView的底部视图将会移除。

 

来自:csdn mayingcai1987

原文:http://blog.csdn.net/mayingcai1987/article/details/6273606

 

1. 引言:

 

为了提高ListView的效率和应用程序的性能,在Android应用程序中不应该一次性加载ListView所要显示的全部信息,而是采取分批加载策略,随着用户的滑动,动态的从后台加载所需的数据,并渲染到ListView组件中,这样可以极大的改善应用程序的性能和用户体验。

2. 交互:

 

进入ListView组件,首先预加载N条记录,当用户滑动到最后一条记录显示加载提示信息,并从后台加载N条数据,接着渲染UI界面。

3. 效果图:

ListView动态加载数据

4. 程序实现:

[java] view plaincopyprint?
  1. package com.focus.loading;  
  2. import android.app.ListActivity;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.view.Gravity;  
  6. import android.view.View;  
  7. import android.view.ViewGroup;  
  8. import android.widget.AbsListView;  
  9. import android.widget.BaseAdapter;  
  10. import android.widget.LinearLayout;  
  11. import android.widget.ListView;  
  12. import android.widget.ProgressBar;  
  13. import android.widget.TextView;  
  14. import android.widget.AbsListView.OnScrollListener;  
  15. import android.widget.LinearLayout.LayoutParams;  
  16. public class ListViewLoadingActivity extends ListActivity implements  
  17.         OnScrollListener {  
  18.     @Override  
  19.     public void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         /** 
  22.          * "加载项"布局,此布局被添加到ListView的Footer中。 
  23.          */  
  24.         mLoadLayout = new LinearLayout(this);  
  25.         mLoadLayout.setMinimumHeight(60);  
  26.         mLoadLayout.setGravity(Gravity.CENTER);  
  27.         mLoadLayout.setOrientation(LinearLayout.HORIZONTAL);  
  28.         /** 
  29.          * 向"加载项"布局中添加一个圆型进度条。 
  30.          */  
  31.         ProgressBar mProgressBar = new ProgressBar(this);  
  32.         mProgressBar.setPadding(00150);  
  33.         mLoadLayout.addView(mProgressBar, mProgressBarLayoutParams);  
  34.         /** 
  35.          * 向"加载项"布局中添加提示信息。 
  36.          */  
  37.         TextView mTipContent = new TextView(this);  
  38.         mTipContent.setText("加载中...");  
  39.         mLoadLayout.addView(mTipContent, mTipContentLayoutParams);  
  40.         /** 
  41.          * 获取ListView组件,并将"加载项"布局添加到ListView组件的Footer中。 
  42.          */  
  43.         mListView = getListView();  
  44.         mListView.addFooterView(mLoadLayout);  
  45.         /** 
  46.          * 组ListView组件设置Adapter,并设置滑动监听事件。 
  47.          */  
  48.         setListAdapter(mListViewAdapter);  
  49.         mListView.setOnScrollListener(this);  
  50.     }  
  51.     public void onScroll(AbsListView view, int mFirstVisibleItem,  
  52.             int mVisibleItemCount, int mTotalItemCount) {  
  53.         mLastItem = mFirstVisibleItem + mVisibleItemCount - 1;  
  54.         if (mListViewAdapter.count > mCount) {  
  55.             mListView.removeFooterView(mLoadLayout);  
  56.         }  
  57.     }  
  58.     public void onScrollStateChanged(AbsListView view, int mScrollState) {  
  59.           
  60.         /** 
  61.          * 当ListView滑动到最后一条记录时这时,我们会看到已经被添加到ListView的"加载项"布局, 这时应该加载剩余数据。 
  62.          */  
  63.         if (mLastItem == mListViewAdapter.count  
  64.                 && mScrollState == OnScrollListener.SCROLL_STATE_IDLE) {  
  65.             if (mListViewAdapter.count <= mCount) {  
  66.                 mHandler.postDelayed(new Runnable() {  
  67.                     @Override  
  68.                     public void run() {  
  69.                         mListViewAdapter.count += 10;  
  70.                         mListViewAdapter.notifyDataSetChanged();  
  71.                         mListView.setSelection(mLastItem);  
  72.                     }  
  73.                 }, 1000);  
  74.             }  
  75.         }  
  76.     }  
  77.     class ListViewAdapter extends BaseAdapter {  
  78.         int count = 10;  
  79.         public int getCount() {  
  80.             return count;  
  81.         }  
  82.         public Object getItem(int position) {  
  83.             return position;  
  84.         }  
  85.         public long getItemId(int position) {  
  86.             return position;  
  87.         }  
  88.         public View getView(int position, View view, ViewGroup parent) {  
  89.             TextView mTextView;  
  90.             if (view == null) {  
  91.                 mTextView = new TextView(ListViewLoadingActivity.this);  
  92.             } else {  
  93.                 mTextView = (TextView) view;  
  94.             }  
  95.             mTextView.setText("Item " + position);  
  96.             mTextView.setTextSize(20f);  
  97.             mTextView.setGravity(Gravity.CENTER);  
  98.             mTextView.setHeight(60);  
  99.             return mTextView;  
  100.         }  
  101.     }  
  102.     private LinearLayout mLoadLayout;  
  103.     private ListView mListView;  
  104.     private ListViewAdapter mListViewAdapter = new ListViewAdapter();  
  105.     private int mLastItem = 0;  
  106.     private int mCount = 41;  
  107.     private final Handler mHandler = new Handler();  
  108.     private final LayoutParams mProgressBarLayoutParams = new LinearLayout.LayoutParams(  
  109.             LinearLayout.LayoutParams.WRAP_CONTENT,  
  110.             LinearLayout.LayoutParams.WRAP_CONTENT);  
  111.     private final LayoutParams mTipContentLayoutParams = new LinearLayout.LayoutParams(  
  112.             LinearLayout.LayoutParams.WRAP_CONTENT,  
  113.             LinearLayout.LayoutParams.WRAP_CONTENT);  
  114. }  

来自:51CTO论坛

原文:http://mobile.51cto.com/android-265878.htm

对于做Android应用程序来说,ListView一定用得非常多,经常解析xml文件然后在ListView中显示,往往我们需要让它动态地加载内容,也就是不一次性地加载完成,对于手机来说,这点很重要!笔者之前也是弄的不明白,用的时候直接在网上找代码,复制粘贴,再修改一下就是自己的了,笔者的这个小Demo灵感来自于新浪或者腾讯微博手机客户端,比如第一页加载十条Item,当翻到最后一个Item的时候,会出来一个Button,当点击Button的时候就会继续加载更多的,当然如果不点,就不会加载的,节约用户流量,先看效果图

 

 

如果觉得满意的话就继续看下面的代码吧,笔者这里没有用到main.xml文件,全部在java文件中定义的,如果理解了的话自己可以在xml文件里面写布局

  1. package com.focus.loading;  
  2. import android.app.ListActivity;  
  3. import android.os.Bundle;  
  4. import android.os.Handler;  
  5. import android.view.Gravity;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.view.ViewGroup;  
  9. import android.view.ViewGroup.LayoutParams;  
  10. import android.widget.AbsListView;  
  11. import android.widget.AbsListView.OnScrollListener;  
  12. import android.widget.BaseAdapter;  
  13. import android.widget.Button;  
  14. import android.widget.LinearLayout;  
  15. import android.widget.ListView;  
  16. import android.widget.ProgressBar;  
  17. import android.widget.TextView;  
  18. public class ListViewActivity extends ListActivity implements OnScrollListener {  
  19.     private LinearLayout mLoadLayout;  
  20.     private LinearLayout mProgressLoadLayout;  
  21.     private ListView mListView;  
  22.     private ListViewAdapter mListViewAdapter = new ListViewAdapter();  
  23.     private int mLastItem = 0;  
  24.     private int mCount = 41;  
  25.     private final Handler mHandler = new Handler();// 在Handler中加载数据  
  26.     private final LayoutParams mLayoutParams = new LinearLayout.LayoutParams(  
  27.             LinearLayout.LayoutParams.WRAP_CONTENT,  
  28. LinearLayout.LayoutParams.WRAP_CONTENT);  
  29.     int scrollState;// 全局变量,用来记录ScrollView的滚动状态,1表示开始滚动,2表示正在滚动,0表示滚动停止  
  30.     int visibleItemCount;// 当前可见页面中的Item总数  
  31.     @Override  
  32.     public void onCreate(Bundle savedInstanceState) {  
  33.         super.onCreate(savedInstanceState);  
  34.         /**  
  35.          * "加载项"布局,此布局被添加到ListView的Footer中。  
  36.          */  
  37.         mLoadLayout = new LinearLayout(this);  
  38.         mLoadLayout.setMinimumHeight(30);  
  39.         mLoadLayout.setGravity(Gravity.CENTER);  
  40.         mLoadLayout.setOrientation(LinearLayout.VERTICAL);  
  41.         /*  
  42.          * 当点击按钮的时候显示这个View,此View使用水平方式布局,左边是一个进度条,右边是文本,默认设为不可见  
  43.          */  
  44.         mProgressLoadLayout = new LinearLayout(this);  
  45.         mProgressLoadLayout.setMinimumHeight(30);  
  46.         mProgressLoadLayout.setGravity(Gravity.CENTER);  
  47.         mProgressLoadLayout.setOrientation(LinearLayout.HORIZONTAL);  
  48.  
  49.         ProgressBar mProgressBar = new ProgressBar(this);  
  50.         mProgressBar.setPadding(0, 0, 15, 0);  
  51.         mProgressLoadLayout.addView(mProgressBar, mLayoutParams);// 为布局添加进度条  
  52.  
  53.         TextView mTipContent = new TextView(this);  
  54.         mTipContent.setText("加载中...");  
  55.         mProgressLoadLayout.addView(mTipContent, mLayoutParams);// 为布局添加文本  
  56.         mProgressLoadLayout.setVisibility(View.GONE);// 默认设为不可见,注意View.GONE和View.INVISIBLE的区别  
  57.  
  58.         mLoadLayout.addView(mProgressLoadLayout);// 把之前的布局以View对象添加进来  
  59.         final Button button = new Button(this);  
  60.         button.setText("加载更多");  
  61.         // 添加按钮  
  62.         mLoadLayout.addView(button, new LayoutParams(LayoutParams.FILL_PARENT,  
  63.                 LayoutParams.WRAP_CONTENT));  
  64.         button.setOnClickListener(new OnClickListener() {  
  65.             @Override  
  66.             public void onClick(View v) {  
  67.                 if (mLastItem == mListViewAdapter.count  
  68.                         && scrollState == OnScrollListener.SCROLL_STATE_IDLE) {  
  69.                     // 当点击时把带进度条的Layout设为可见,把Button设为不可见  
  70.                     mProgressLoadLayout.setVisibility(View.VISIBLE);  
  71.                     button.setVisibility(View.GONE);  
  72.                     if (mListViewAdapter.count <= mCount) {  
  73.                         mHandler.postDelayed(new Runnable() {  
  74.                             @Override  
  75.                             public void run() {  
  76.                                 mListViewAdapter.count += 10;  
  77.                                 mListViewAdapter.notifyDataSetChanged();  
  78.                                 mListView.setSelection(mLastItem  
  79.                                         - visibleItemCount + 1);  
  80.                                 // 获取数据成功时把Layout设为不可见,把Button设为可见  
  81.                                 mProgressLoadLayout.setVisibility(View.GONE);  
  82.                                 button.setVisibility(View.VISIBLE);  
  83.                             }  
  84.                         }, 2000);  
  85.                     }  
  86.                 }  
  87.             }  
  88.         });  
  89.  
  90.         mListView = getListView();  
  91.         mListView.addFooterView(mLoadLayout);  
  92.         setListAdapter(mListViewAdapter);  
  93.         mListView.setOnScrollListener(this);  
  94.     }  
  95.     @Override  
  96.     public void onScroll(AbsListView view, int firstVisibleItem,  
  97.             int visibleItemCount, int totalItemCount) {  
  98.         this.visibleItemCount = visibleItemCount;  
  99.         mLastItem = firstVisibleItem + visibleItemCount - 1;  
  100.         if (mListViewAdapter.count > mCount) {  
  101.             mListView.removeFooterView(mLoadLayout);  
  102.         }  
  103.     }  
  104.     @Override  
  105.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  106.         this.scrollState = scrollState;  
  107.  
  108.     }  
  109.     class ListViewAdapter extends BaseAdapter {  
  110.         int count = 10;  
  111.  
  112.         public int getCount() {  
  113.             return count;  
  114.         }  
  115.         public Object getItem(int position) {  
  116.             return position;  
  117.         }  
  118.  
  119.         public long getItemId(int position) {  
  120.             return position;  
  121.         }  
  122.         public View getView(int position, View view, ViewGroup parent) {  
  123.             TextView mTextView;  
  124.             if (view == null) {  
  125.                 mTextView = new TextView(ListViewActivity.this);  
  126.             } else {  
  127.                 mTextView = (TextView) view;  
  128.             }  
  129.             mTextView.setText("Item " + position);  
  130.             mTextView.setTextSize(20f);  
  131.             mTextView.setGravity(Gravity.CENTER);  
  132.             mTextView.setHeight(60);  
  133.             return mTextView;  
  134.         }  
  135.     }  

【编辑推荐】

Android ListView详解

使用ListView 显示数据

Android开发:自定义GridView/ListView数据源

Android开发:实现带图片和checkbox的listview

Android开发:实现带图片和checkbox的listview

 

原创粉丝点击