Android中ListView数据处理优化

时间:2020-12-02 18:30:00

来自: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类源码:  
01 package com.andyidea.bean;
02   
03 /**
04  * 新闻实体类
05  * @author Andy.Chen
06  * @mail Chenjunjun.ZJ@gmail.com
07  *
08  */
09 public 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类 源码:  
001 package com.andyidea.listview;
002   
003 import java.util.ArrayList;
004 import java.util.List;
005   
006 import com.andyidea.bean.News;
007   
008 import android.app.Activity;
009 import android.os.Bundle;
010 import android.os.Handler;
011 import android.util.Log;
012 import android.view.View;
013 import android.view.ViewGroup;
014 import android.widget.AbsListView;
015 import android.widget.AbsListView.OnScrollListener;
016 import android.widget.BaseAdapter;
017 import android.widget.Button;
018 import android.widget.ListView;
019 import android.widget.TextView;
020 import android.widget.Toast;
021   
022 public 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. 效果图:

Android中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的时候就会继续加载更多的,当然如果不点,就不会加载的,节约用户流量,先看效果图

Android中ListView数据处理优化 

Android中ListView数据处理优化 

Android中ListView数据处理优化

如果觉得满意的话就继续看下面的代码吧,笔者这里没有用到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