android中listview实现分页的解决办法

方法一
问题  
ListView  内容循环显示大家试想 假如ListView待显示的数据很庞大 从0-100  如果按照ListView默认行为 用户要找到50记录 可能要滚动很久 这显然会影响用户体验  本文的宗旨:解决这一问题
思路
1.  自定义BaseAdapter
2.  其 getCount() 返回一个固定值 比如:5   那么ListView就会只显示5个记录
3.  其 getView()  必须返回0-100记录 但需要分批显示 那如何实现呢?
定义 int index = 0;  用于记录显示当前数据的次序  用户显示下批数据 那么index++  反之 显示以前 就index-
遗留问题
 1.  当数据已经取到最后一批 那么应该使"向下翻页"Button 反白  即:不可单击
 2. 同理 若此前目标是第一批数据 "向上翻页"Button 也应该反白
  Android <wbr> <wbr>ListView专题之十二 <wbr> <wbr>分页不同的解决方案

Java代码       
public class ItemAdapter extends BaseAdapter {    
Activity a;    
  String[] data = {    
           //.......        
  };    
  @Override  
public int getCount()
  {    
   // TODO Auto-generated method stub    
            return 5;    
}    
 
   @Override  
     public Object getItem(int position) 
{    
            // TODO Auto-generated method stub    
            return position;    
      }    
   
      @Override  
public long getItemId(int position)
  {    
            // TODO Auto-generated method stub    
            return position;    
      }    
   
      @Override  
public View getView(int position, View convertView, ViewGroup parent)
  {    
            // TODO Auto-generated method stub    
            TextView tv = new TextView(a);    
             
            tv.setText(data[position+index*VIEW_COUNT]);    
            return null;    
      }    
   
}  
public class ListMoreTest extends Activity {
  ListView lv;
  Button btnLeft, btnRight;
  View.OnClickListener cl;
  MoreAdapter ma;
  String[] data = {"0","1","2","3","4","5","6","7","8","9","10",
   …..};
  int VIEW_COUNT = 5;
  int index = 0;
    
      @Override
       public void onCreate(Bundle savedInstanceState) 
     {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main); 
            initView();
            ma = new MoreAdapter(this);
            lv.setAdapter(ma);
            cl = new Button.OnClickListener()
            {
               @Override
              public void onClick(View v) 
              {
                  // TODO Auto-generated method stub
                  switch(v.getId())
                  {
                     case R.id.btnLeft:
                              leftView();
                              break;
                     case R.id.btnRight:
                              rightView();
                              break;
                 }
            }
         };
         btnLeft.setOnClickListener(cl);
         btnRight.setOnClickListener(cl);
         checkButton();
      }
      
       public void initView()
     {
         lv = (ListView)findViewById(R.id.list);
         btnLeft = (Button)findViewById(R.id.btnLeft);
         btnRight = (Button)findViewById(R.id.btnRight);
      }
       public void leftView()
      {
           index--;
           ma.notifyDataSetChanged();
           checkButton();
      }
       public void rightView()
     {
         index++;
         ma.notifyDataSetChanged();
         checkButton();
      }
       public void checkButton()
     {
         if(index <=0)
         {
            btnLeft.setEnabled(false);
         }
        else 
           if(data.length - index*VIEW_COUNT <= VIEW_COUNT)
        {
           btnRight.setEnabled(false);
        }
      else 
      {
         btnLeft.setEnabled(true);
         btnRight.setEnabled(true);
      }
   }
}
方法二
     Android应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过分页的形式来展示数据,个人觉得这样会有更好的用户体验。因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据
Android <wbr> <wbr>ListView专题之十二 <wbr> <wbr>分页不同的解决方案

  com.andyidea.bean中News.java类是新闻实体类,包com.andyidea.listview中paginationListViewActivity.java类是用来展示ListView列表。布局layout中包含三个布局文件,分别为:list_item.xml , loadmore.xml , main.xml 。下面分别贴下源码:
layout中的 list_item.xml源码:
view plain
1. <span style="font-size:13px;"><?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout  
3.  xmlns:android="http://schemas.android.com/apk/res/android"  
4.  android:layout_width="fill_parent"  
5.  android:layout_height="fill_parent"  
6.  android:orientation="vertical">  
7.  <TextView  
8.     android:id="@+id/newstitle"  
9.     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源码:
view plain
1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout  
3.  xmlns:android="http://schemas.android.com/apk/res/android"  
4.  android:layout_width="fill_parent"  
5.  android:layout_height="fill_parent">  
6.  <Button    
7.      android:id="@+id/loadMoreButton"    
8.      android:layout_width="fill_parent"    
9.      android:layout_height="wrap_content"  
10.      android:text="查看更多..." />   
11. </LinearLayout>  

layout中main.xml源码:

1. <?xml version="1.0" encoding="utf-8"?>  
2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
3.    android:orientation="vertical"  
4.    android:layout_width="fill_parent"  
5.    android:layout_height="fill_parent">  
6.    <ListView  
7.       android:id="@+id/lvNews"  
8.       android:layout_width="fill_parent"  
9.       android:layout_height="wrap_content"/>  
10. </LinearLayou  

包 com.andyidea.bean中News.java类源码:

1.  public class News {  
2.        
3.      private String title;      //标题  
4.      private String content;   //内容  
5.        
6.      public String getTitle() {  
7.            return title;  
8.      }  
9.      public void setTitle(String title) {  
10.            this.title = title;  
11.      }  
12.      public String getContent() {  
13.            return content;  
14.      }  
15.      public void setContent(String content) {  
16.            this.content = content;  
17.      }  
18.  
19. }  

包com.andyidea.listview中paginationListViewActivity.java类源码:

2.  public class PaginationListViewActivity extends Activity implements OnScrollListener {  
3.        
4.      private ListView listView;     
5.      private int visibleLastIndex = 0;     //最后的可视项索引    
6.      private int visibleItemCount;           // 当前窗口可见项总数    
7.      private int datasize = 38;               //模拟数据集的条数  
8.      private PaginationAdapter adapter;     
9.      private View loadMoreView;     
10.    private Button loadMoreButton;     
11.    private Handler handler = new Handler();    
    
14.      @Override  
15.      public void onCreate(Bundle savedInstanceState) {  
16.            super.onCreate(savedInstanceState);  
17.            setContentView(R.layout.main);  
18.              
19.            loadMoreView = getLayoutInflater().inflate(R.layout.loadmore, null);  
20.            loadMoreButton = (Button)loadMoreView.findViewById(R.id.loadMoreButton);  
21.            loadMoreButton.setOnClickListener(new View.OnClickListener() {  
22.                    
23.                  @Override  
24.                  public void onClick(View v) {  
25.                        loadMoreButton.setText("正在加载中...");     //设置按钮文字  
26.                        handler.postDelayed(new Runnable() {  
27.                                
28.                              @Override  
29.                              public void run() {  
30.                                    loadMoreData();  
31.                                    adapter.notifyDataSetChanged();  
32.                                    loadMoreButton.setText("查看更多...");   //恢复按钮文字  
33.                              }  
34.                        },2000);  
35.                          
36.                  }  
37.            });  
38.              
39.            listView = (ListView)findViewById(R.id.lvNews);  
40.            listView.addFooterView(loadMoreView);      //设置列表底部视图  
41.            initializeAdapter();  
42.            listView.setAdapter(adapter);  
43.            listView.setOnScrollListener(this);  
44.      }  
45.        
46.      @Override  
47.      public void onScrollStateChanged(AbsListView view, int scrollState) {  
48.            int itemsLastIndex = adapter.getCount()-1;   //数据集最后一项的索引    
49.            int lastIndex = itemsLastIndex + 1;  
50.            if (scrollState == OnScrollListener.SCROLL_STATE_IDLE  
51.                        && visibleLastIndex == lastIndex) {  
52.                  // 如果是自动加载,可以在这里放置异步加载数据的代码  
53.            }  
54.      }  
55.  
56.  
57.      @Override  
58.    public void onScroll(AbsListView view, int firstVisibleItem,  
59.            int visibleItemCount, int totalItemCount) {  
60.            this.visibleItemCount = visibleItemCount;  
61.            visibleLastIndex = firstVisibleItem + visibleItemCount - 1;  
62.              
63.            Log.e("========================= ","========================");  
64.            Log.e("firstVisibleItem = ",firstVisibleItem+"");  
65.            Log.e("visibleItemCount = ",visibleItemCount+"");  
66.            Log.e("totalItemCount = ",totalItemCount+"");  
67.            Log.e("========================= ","========================");  
68.              
69.            //如果所有的记录选项等于数据集的条数,则移除列表底部视图  
70.            if(totalItemCount == datasize+1){  
71.                  listView.removeFooterView(loadMoreView);  
72.                  Toast.makeText(this, "数据全部加载完!", Toast.LENGTH_LONG).show();  
73.            }  
74.      }  
75.        
76.        
79.      private void initializeAdapter(){  
80.            List<News> newnews = new ArrayList<News>();  
81.            for(int i=1;i<=10;i++){  
82.                  News items = new News();  
83.                  items.setTitle("Title"+i);  
84.                  items.setContent("This is News Content"+i);  
85.                  news.add(items);  
86.            }  
87.            adapter = new PaginationAdapter(news);  
88.      }  
89.        
90.        
93.      private void loadMoreData(){  
94.            int count = adapter.getCount();  
95.              
96.            if(count+10 <= datasize){  
97.                  for(int i=count+1; i<=count+10; i++){  
98.                        News item = new News();  
99.                        item.setTitle("Title"+i);  
100.                        item.setContent("This is News Content"+i);  
101.                        adapter.addNewsItem(item);  
102.                  }  
103.            }else{  
104.                  for(int i=count+1; i<=datasize; i++){  
105.                        News item = new News();  
106.                        item.setTitle("Title"+i);  
107.                        item.setContent("This is News Content"+i);  
108.                        adapter.addNewsItem(item);  
109.                  }  
110.            }  
111.              
112.      }  
113.        
114.        
115.      class PaginationAdapter extends BaseAdapter{  
116.              
117.            List<News> newsItems;  
118.              
119.            public PaginationAdapter(List<News> newsitems){  
120.                  this.newsItems = newsitems;  
121.            }  
122.  
123.            @Override  
124.            public int getCount() {  
125.                  return newsItems.size();  
126.            }  
127.  
128.            @Override  
129.            public Object getItem(int position) {  
130.                  return newsItems.get(position);  
131.            }  
132.  
133.            @Override  
134.            public long getItemId(int position) {  
135.                  return position;  
136.            }  
137.  
138.            @Override  
139.            public View getView(int position, View view, ViewGroup parent) {  
140.                  if(view == null){  
141.                        view = getLayoutInflater().inflate(R.layout.list_item, null);  
142.                  }  
143.                    
144.                  //新闻标题  
145.                  TextView tvTitle = (TextView)view.findViewById(R.id.newstitle);  
146.                  tvTitle.setText(newsItems.get(position).getTitle());  
147.                  //新闻内容  
148.                  TextView tvContent = (TextView)view.findViewById(R.id.newscontent);  
149.                  tvContent.setText(newsItems.get(position).getContent());  
150.                    
151.                  return view;  
152.            }  
153.              
154.              
158.            public void addNewsItem(News newsitem){  
159.                  newsItems.add(newsitem);  
160.            }  
161.              
162.      }  
163.  
164. }  
  最后,运行程序的结果截图如下:
 
通过上面的截图,当我们点击"查看更多..."按钮时,就会加载下10条记录,当加载完所有的记录后,ListView的底部视图将会移除。
方法三
        Android market里软件列表,每页显示10条记录,没有显示上一页,下一页的按钮,依靠手滑动动态加载数据,当向下滚动时,最下边显示 Loading… 。数据加载结束,Loading底栏消失。
   关于ListView的分段显示,有现成的库可用,比如 cwac-endless, 这个库不好之处,就是底部Loading的View无法定制。还有一个在google code上的androidpageablelistview 这个可以实现基本的分页,有手动操作显示上一页,下一页的按钮。
   查阅了很多资料,发现其实ListView自带一个实现分页加载的方法,用到addFooterView/removeView 这两个函数“添加”或“去掉“ListView页脚。下面是一个研究ListView分页时做的一个Demo,比较简单,我把思路我源码和大家分享一下,希望对大家有所帮助
  Android <wbr> <wbr>ListView专题之十二 <wbr> <wbr>分页不同的解决方案

实现思路如下:
    用onScroll方法实现”滑动“后处理检查是否还有新的记录,如果有,调用addFooterView,添加记录到adapter, adapter调用 notifyDataSetChanged 更新数据;如果没有记录了, 把自定义的mFooterView去掉。这里没有重写onScrollStateChanged函数,那么在onScroll就需要一个外部变量mFirstCell记录滑动位置。

public class MainActivity extends ListActivity implements OnScrollListener {
     private static final String TAG = "MainActivity";
   private listViewAdapter adapter = new listViewAdapter();
            ListView listView ;
   private int lastItem = 0;
            LinearLayout loadingLayout;
   private LayoutParams mLayoutParams =new
             LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
             LinearLayout.LayoutParams.WRAP_CONTENT);
   private LayoutParams FFlayoutParams =new
             LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
             LinearLayout.LayoutParams.FILL_PARENT);  
   private ProgressBar progressBar;
    
     @Override
     protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i(TAG, "onCreate(Bundle savedInstanceState)>>>>>>>>>>>>>>>" );
         //线性布局
        LinearLayout layout = new LinearLayout(this);
        //设置布局 水平方向
        layout.setOrientation(LinearLayout.HORIZONTAL);
        //进度条
        progressBar = new ProgressBar(this);
        //进度条显示位置
        progressBar.setPadding(0, 0, 15, 0);
        //把进度条加入到layout中
        layout.addView(progressBar, mLayoutParams);
        //文本内容
        TextView textView = new TextView(this);
        textView.setText("加载中...");
        textView.setGravity(Gravity.CENTER_VERTICAL);
        //把文本加入到layout中
        layout.addView(textView, FFlayoutParams);
        //设置layout的重力方向,即对齐方式是
        layout.setGravity(Gravity.CENTER);
        //设置ListView的页脚layout
        loadingLayout = new LinearLayout(this);
        loadingLayout.addView(layout, mLayoutParams);
        loadingLayout.setGravity(Gravity.CENTER);
        //得到一个ListView用来显示条目
        listView = getListView();
        //添加到脚页显示
        listView.addFooterView(loadingLayout);
        //给ListView添加适配器
        setListAdapter(adapter);
        //给ListView注册滚动监听
        listView.setOnScrollListener(this);
   }
    @Override
  public void onScroll(AbsListView v, int firstVisibleItem,
     int visibleItemCount, int totalItemCount)
   {
         Log.i(TAG , "Scroll>>>first: " + firstVisibleItem + ", visible: " + visibleItemCount + ",           total: " + totalItemCount);
        lastItem = firstVisibleItem + visibleItemCount - 1;
        Log.i(TAG , "Scroll>>>lastItem:" + lastItem);
        //显示50条ListItem,即0-49,因为onScroll是在“滑动”执行过之后才触发,所以用adapter.count<=
      41 作条件
        if (adapter.count<=41) {
           if (firstVisibleItem+visibleItemCount==totalItemCount)
           {
              adapter.count += 10;
              adapter.notifyDataSetChanged();
              listView.setSelection(lastItem);
              int currentPage=adapter.count/10;
              Toast.makeText(getApplicationContext(), "第"+currentPage+"页", Toast.LENGTH_LONG).show();
         }
      }
     else 
     {
        listView.removeFooterView(loadingLayout); 
     }

  }
    @Override
  public void onScrollStateChanged(AbsListView v, int state)
   {
      if (lastItem == adapter.count && state == OnScrollListener.SCROLL_STATE_IDLE)
     {
           Log.i(TAG,"ScrollStateChanged>>>state:"+state+"lastItem:" + lastItem);
           //显示50条ListItem,即0-49,因为onScrollStateChanged是在“拖动滑动”执行过之后才触发,所以
        用 adapter.count<=41作条件
         if (adapter.count<=41)
         {
           adapter.count += 10;
           adapter.notifyDataSetChanged();
         }
      }
}
 
 class listViewAdapter extends BaseAdapter {
     int count = 10;
     public int getCount() 
   {
        Log.i(TAG, "getCount>>>count:" + count);
        return count;
     }

    public Object getItem(int pos) 
   {
      Log.i(TAG, "getItem>>>pos:" + pos);
      return pos;
   }

    public long getItemId(int pos) 
   {
     Log.i(TAG, "getItemId>>>ItemId:" + pos);
     return pos;
   }

  public View getView(int pos, View v, ViewGroup p)
  {
     Log.i(TAG, "getView>>>pos:" + pos);
     TextView view;
     if (v==null) 
   {
      view = new TextView(MainActivity.this);
     }
   else
   {
     view=(TextView)v;
  }
   view.setText("ListItem " + pos);
   view.setTextSize(20f);
   view.setGravity(Gravity.CENTER);
   view.setHeight(60);
   return view;
   }
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值