Adapter之大数据滑动效率优化和分页加载数据

原创 2015年11月17日 17:36:11

         在Android中如果要做到大数据分页加载则需要我们的Activity实现OnScrollListener滚动条监听接口。当如果要做的更加高大上。比如需要在用户滑动至列表的底部,触碰摸个区域,则需要实现OnTouchListener接口,等等。

       这里先讲加载大数据

       首先需要在main.xml申明一个ListView,存放数据  

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    android:paddingLeft="3dp"  
    android:paddingRight="3dp">
    
    <!-- 当ListActivity时,ListView中就需要@id/android:list,否则logCat会报错
    	 Android内置的名为list的id,因为我们后面要使用到ListActivity,我们的MainActivity继承于它 -->
    <TextView android:id="@+id/txtView"
        android:text="编号"
        android:textSize="24dp"
        android:textColor="#ff00FF"
        android:background="#80D640"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center_horizontal"/>	 
    <ListView android:id="@id/android:list"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"/>  
</LinearLayout>  
       由于ListView试图组件中,需要封装每一个item,所以需要layout中申明:

        list_item.xml

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent">  
    <!-- 它是ListView中单个列表项的布局文件,从效果图中可以看到,这里只使用到了一个TextView组件 -->
    <!-- 在getView或者bindview里面首先用一文本TextView显示在本地,同时启动线程去网上获取图片资源,一旦某TextView的数据得到就立马刷新将那张本地的TextView换掉 -->
    <TextView  android:id="@+id/list_item_text"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
        android:gravity="center"  
        android:textSize="20sp"  
        android:paddingTop="10dp"  
        android:paddingBottom="10dp"/>  
</LinearLayout> 
       在加上我们的效果时,当滑动至列表的底部也就是应用程序窗体底部时,想要加载下一行,所以需要一个按钮来触发 load_more.xml

<?xml version="1.0" encoding="utf-8"?>  
<LinearLayout  
  xmlns:android="http://schemas.android.com/apk/res/android"  
  android:orientation="vertical"  
  android:layout_width="fill_parent"  
  android:layout_height="wrap_content">  
  <Button android:id="@+id/loadMoreButton"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="load more"  
        android:onClick="loadMore"/>  
</LinearLayout>  
        在使用BaseAdapter适配器加载大量数据

        

package com.lol.huixin.adapter;

import java.util.List;
import java.util.Map;

import com.lol.huixin.loaddatamore.R;
import com.lol.huixin.views.ViewHolder;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class ListViewAdapter extends BaseAdapter {
	private List<Map<String,Object>> items;  
    private LayoutInflater inflater;
	
    public ListViewAdapter(Context context, List<Map<String,Object>> items) {  
        this.items = items;  
        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);        
    }
    
	@Override
	public int getCount() {
		return items.size();
	}

	@Override
	public Object getItem(int position) {
		return items.get(position);
	}

	@Override
	public long getItemId(int position) {
		return position;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder=null;
		if (convertView == null) {  
			holder=new ViewHolder();
			convertView = inflater.inflate(R.layout.list_item, null);  
			holder.list_item_text=(TextView) convertView.findViewById(R.id.list_item_text);
			convertView.setTag(holder);
        } else{
        	holder=(ViewHolder)convertView.getTag();
        } 
		holder.list_item_text.setText((String)items.get(position).get("bianhao"));
        return convertView; 
	}

	/** 
     * 添加列表项 
     * @param item 
     */  
    public void addItem(Map<String,Object> listmap) {  
        items.add(listmap);  
    }
}
      MainActivity.java中调用

 

package com.lol.huixin.loaddatamore;

import android.os.Bundle;
import android.os.Handler;
import android.util.Log;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.lol.huixin.adapter.ListViewAdapter;

import android.app.ListActivity;
import android.view.Menu;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Button;
import android.widget.ListView;

//由于我们这里模拟加载大量数据的样本,所以就需要有个滚动条,所以需要实现滚动条的接口
public class MainActivity extends ListActivity implements OnScrollListener{
	private ListView listView;  
    private int visibleLastIndex = 0;   //最后的可视项索引  
    private int visibleItemCount;       // 当前窗口可见项总数  
    private ListViewAdapter adapter;    //数据适配器
    private View loadMoreView;  
    private Button loadMoreButton;  
    private Handler handler = new Handler(); 
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//相当于实例化一个Layout,并在这个实例化的Layout中加一个按钮
		loadMoreView = getLayoutInflater().inflate(R.layout.load_more, null);  
        loadMoreButton = (Button) loadMoreView.findViewById(R.id.loadMoreButton);  
        listView = getListView();               //获取id是list的ListView  
        listView.addFooterView(loadMoreView);   //设置列表底部视图  
        //初始化数据
        initAdapter();  
        setListAdapter(adapter);                //自动为id是list的ListView设置适配器  
        listView.setOnScrollListener(this);     //添加滑动监听
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}
	
	/** 
     * 初始化适配器 
     */  
    private void initAdapter() {  
    	List<Map<String,Object>> listMap=new ArrayList<Map<String,Object>>();
        for (int i = 0; i < 10; i++) {  
        	Map<String,Object> map=new HashMap<String,Object>();
        	map.put("bianhao",String.valueOf(i+1)); 
        	listMap.add(map);
        }  
        adapter = new ListViewAdapter(this, listMap);  
    }

    /** 
     * 滑动状态改变时被调用 
     */
	@Override
	public void onScrollStateChanged(AbsListView view, int scrollState) {
		int itemsLastIndex = adapter.getCount() - 1;    //数据集最后一项的索引  
        int lastIndex = itemsLastIndex + 1;             //加上底部的loadMoreView项  
        if (scrollState == OnScrollListener.SCROLL_STATE_IDLE && visibleLastIndex == lastIndex) {  
            //如果是自动加载,可以在这里放置异步加载数据的代码  
            Log.i("LOADMORE", "loading...");  
        }
	}

	/** 
     * 滑动时被调用 
     */
	@Override
	public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
		this.visibleItemCount = visibleItemCount;  
        visibleLastIndex = firstVisibleItem + visibleItemCount - 1;  
	}

	  /** 
     * 点击按钮事件 
     * @param view 
     */  
    public void loadMore(View view) {  
        loadMoreButton.setText("loading...");   //设置按钮文字loading  
        handler.postDelayed(new Runnable() {  
            @Override  
            public void run() {  
                loadData();  
                adapter.notifyDataSetChanged(); //数据集变化后,通知adapter  
                listView.setSelection(visibleLastIndex - visibleItemCount + 1); //设置选中项  
                  
                loadMoreButton.setText("load more");    //恢复按钮文字  
            }  
        }, 2000);  
    }  
      
    /** 
     * 模拟加载数据 
     */  
    private void loadData() {  
        int count = adapter.getCount();  
        for (int i = count; i < count + 10; i++) {  
        	Map<String,Object> map=new HashMap<String,Object>();
        	map.put("bianhao",String.valueOf(i+1));
            adapter.addItem(map);  
        }  
    }  
    
}
   这个时候我们注意到了一个奇怪的现象:ViewHolder类

   

package com.lol.huixin.views;

import java.io.Serializable;

import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

@SuppressWarnings("serial")
public class ViewHolder implements Serializable{
	public ImageView img;
	//public TextView title;
	public TextView list_item_text;
	public TextView info;
	public Button viewBtn;
}
      项目结构:

      
        运行效果:也是ok的。

        然后我就在想为什么这样写了?

       1.首先ListViewAdapter中有一个有参构造方法,我们在MainActivity调用时传入了两个参数,参数一是需要装载值ListView中的数据,参数二是当前上下文对象Context,

        inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)

        从当前layout的上下文作用域中得到SystemService中的LAYOUT_INFLATER_SERVICE东东,那么LAYOUT_INFLATER_SERVICE是什么东东,Android官网给与了解释:

String android.content.Context.LAYOUT_INFLATER_SERVICE = "layout_inflater"

Use with getSystemService to retrieve a android.view.LayoutInflater for inflating layout resources in this context.

See Also:
getSystemService
android.view.LayoutInflater
Google说:使用带有getSystemService检索android.view.LayoutInflater进行充气布局资源于该上下文。
也就是说我们通过LayoutInflater这个类实例化一个layout,将我们load_more.xml中的按钮给动态加至ListView中
2.我们知道Android中提高滑动效率,就意味着需要修改GetView方法,那么我们那样写的目的何在
   原因有两点:
          一>adapter每次加载时,都需要去创建一个item中的内容,也就是Layout和其中的组件,很影响效率,如果我们把组件进行封装是不是会优化效率呢?在这,如果在内存中已经分配了使用LayoutInflater创建了一个Layout呢?我们是不是不需要在此创建
         二>我们都知道在看书的时候,要想定位到上次看过的地方,最简单的方法就是在书中做个标记,同样的android也支持这样一种写法
       convertView.setTag(holder);   //做数据标记





 


版权声明:本文为博主原创文章,未经博主允许不得转载。

慕课网ListView分页笔记(简化的Adapter)

1.    设置分页加载更多的提示页面footer_layout.xml:
  • lw18751836671
  • lw18751836671
  • 2014年11月09日 17:06
  • 725

android中的ListView数据量大时如何提高效率。。。。

数据量大,这牵涉到2个问题。 1. 一个空ListView加载的数据项很多 2. 已加载很多数据项的ListView如何优化效率 对于问题1:一个空ListView加载的数据项很多 一...
  • oldmtn
  • oldmtn
  • 2013年04月15日 17:03
  • 10821

ListView怎么处理大量的加载数据;比如有10万条数据,你在ListView怎么处理?

题目:ListView怎么处理大量的加载数据;比如有10万条数据,你在ListView怎么处理?...
  • huangxiaominglipeng
  • huangxiaominglipeng
  • 2014年10月11日 10:34
  • 3771

rownum与Oracle分页SQL 以及提高分页查询效率

SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (SELECT * FROM TABLE_NAME) T1 WHERE ROWNUM = 20
  • zhouxzcsdn
  • zhouxzcsdn
  • 2016年11月23日 17:11
  • 1156

xListView分页加载数据

android开发中有的时候不可能一次性把所有的数据加载进去所以必须要分页加载数据,所以xlistview是很多开发中常用的一种方式进行分页加载数据。网络上很容易找到类库,但是分页加载的倒是比较少见,...
  • flower_danni
  • flower_danni
  • 2016年01月21日 10:09
  • 938

MySQL单表百万数据记录分页性能优化 limit优化

背景: 自己的一个网站,由于单表的数据记录高达了一百万条,造成数据访问很慢,Google分析的后台经常报告超时,尤其是页码大的页面更是慢的不行。 测试环境: 先让我们熟悉下基本的sq...
  • u012889638
  • u012889638
  • 2016年01月09日 17:02
  • 1810

Ajax动态滚动加载数据

看新浪微博,人人网都有这样的效果:滚动条滚动到最下面的时候,新的数据就被自动加载出来了,今天亲自尝试了一下这个效果的实现。 首先,准备一个分页的存储过程: CREATE PROCEDURE pr...
  • dannywj1371
  • dannywj1371
  • 2013年09月22日 15:50
  • 15608

Mybatis分页插件 - PageHelper很好很强大,转载

1.引入分页插件 1.引入Jar包 如果你想使用本项目的jar包而不是直接引入类,你可以在这里下载各个版本的jar包(点击Download下的jar即可下载) https:/...
  • callmedarcy
  • callmedarcy
  • 2015年04月26日 16:26
  • 2006

H5手机页面滑动异步加载数据

怎样实现手机版的web页面在滑动的时候异步加载数据,直接贴代码,可以直接新建一个html页面进行测试哦,注意这里要引用jQuery插件                     $(d...
  • xiaxiaoying2012
  • xiaxiaoying2012
  • 2016年10月13日 20:53
  • 4126

easyui下的datagrid后台数据加载和分页

Datagrid的创建需要做以下几件事情,   第一步,我们需要引入以下几个个包,少一个都不可以,否则你会发现你无论做的再怎么对结果都会出错,       第二步,引入了这些包之后,我们需...
  • m0_37560267
  • m0_37560267
  • 2017年04月27日 10:08
  • 1743
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Adapter之大数据滑动效率优化和分页加载数据
举报原因:
原因补充:

(最多只允许输入30个字)