android listview下拉刷新(listview 分页),数据来源数据库

Android 应用开发中,采用ListView组件来展示数据是很常用的功能,当一个应用要展现很多的数据时,一般情况下都不会把所有的数据一次就展示出来,而是通过 分页的形式来展示数据,

因此,很多应用都是采用分批次加载的形式来获取用户所需的数据。例如:微博客户端可能会在用户滑 动至列表底端时自动加载下一页数据,也可能在底部放置一个"查看更多"按钮,用户点击后,加载下一页数据。

下面通过一个例子来展示listview下拉自动刷新;数据来源数据库,虽然网上有很多listview下拉刷新的例子;但大多都是使用静态数据,数据库取数据的非常少,今天就花点时间给大家介绍下Android访问数据库的流程,

希望能解开新手的困惑,,因为小弟也是初学者,高手别吐槽,路过就好。

数据库:SQL Server 2008

服务端:Servlet

Android sdk 4.2.2

数据格式:json

先来看下数据库里面的数据;通过分页加载数据库中的 影片类型表,展示部分数据

上面展示的是我数据里面影片类型的部分数据,通过加载数据以json的格式返回给Android客户端;在客户端解析json显示在listview中

服务端项目

关于服务端servlet的代码,贴出来给大家看看;一切都准备好了之后,部署在 Tomcat上面,如果不知道如何部署的话,

可以去我以前写的关于如何部署项目的博客:http://www.cnblogs.com/zhoujian315/p/3165943.html

int size=Integer.parseInt(req.getParameter("size"));
        int index=Integer.parseInt(req.getParameter("index"));
        
        GetAll g=new GetAll();
        //返回影片类型对象
        List<GoodTypeModel> list=g.getGoodAll(index,size); 
        int num=g.getGoodTypeCount();
        List<HashMap<String, Object>> arraylist=new ArrayList<HashMap<String,Object>>();
        JSONObject json=new JSONObject();
        if(list!=null)
        {
            try {
                
                for(int i=0;i<list.size();i++)
                {
                    HashMap<String, Object> map=new HashMap<String, Object>();
                    map.put("id", list.get(i).getgT_id());
                    map.put("namg", list.get(i).getgT_Name());
                    map.put("parent", list.get(i).getgT_ParentID());
                    arraylist.add(map);
                }
                //返回json格式的数据
                JSONObject json2=new JSONObject();
                json2.put("commentlist", arraylist);
                json.put("isok", 0);
                json.put("num", num);
                json.put("data", json2);
                out.print(json);
                out.close();
                
            } catch (Exception e) {
                try {
                    json.put("isok", 1);
                    json.put("data", "");
                    out.print(json);
                    out.close();
                } catch (JSONException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        }

上面的代码将一个影片对象转换成 json数据并返回给 客户端

转换之后前 10条json数据

{"num":37,"data":{"commentlist":[{"id":1,"namg":"所有类型","parent":0},{"id":2,"namg":"影视","parent":1},{"id":3,"namg":"音乐","parent":1},{"id":4,"namg":"电影","parent":1},{"id":5,"namg":"内地","parent":2},{"id":6,"namg":"港台","parent":2},{"id":7,"namg":"欧美","parent":2},{"id":8,"namg":"日韩","parent":2},{"id":9,"namg":"动作","parent":2},{"id":10,"namg":"犯罪","parent":2}]},"isok":0}

其中:isok:成功返回的标志,“0”表示成功  “1”  失败返回

  num:数据库中表的总记录数

  data:影片类型数据总条数

 

到这里json数据已经准备好了;

下面我们来看看Android客户端

MainActivity的布局文件很简单;就一个listview控件

footer.xml布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:id="@+id/footer_lin"
    android:visibility="visible"
    android:orientation="horizontal" >
	
    <ProgressBar 
        android:id="@+id/footer_progress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleSmall"
        />
    <TextView 
        android:id="@+id/footer_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="18sp"
        android:text="@string/footer_more"
        />
    
</LinearLayout>

 listview_item.xm文件也很简单,包括3个TextView控件,代码就不贴出来了;

下面看MainActivity.java代码

private LinearLayout lin;
    private ListView listview;
    private final static String URL = "http://localhost:8080/listviewManager/getListViewScroll";
    private String index = "1"; //默认当前页
    private String size="10";    //每页的大小
    private int num; //数据总记录数
    private View footer; //listview脚部视图
    private MyAdapter adapter;
    private List<HashMap<String, Object>> datalist = new ArrayList<HashMap<String, Object>>();
    private int lastitem=0;  //可视最后索引

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        lin=(LinearLayout)findViewById(R.id.footer_lin);
        footer=getLayoutInflater().inflate(R.layout.footer, null);
        listview = (ListView) findViewById(R.id.listview);
        listview.setOnScrollListener(scrollListener);
        
        new MyThread().start();
        adapter = new MyAdapter(MainActivity.this, datalist);
        listview.addFooterView(footer);
        listview.setAdapter(adapter);

    }

下面代码是通过子线程异步加载json数据

 

class MyThread extends Thread
    {
        @Override
        public void run() {
            String re=getListItem(index,size);
            Message msg=new Message();
            msg.obj=re;
            myHandler.sendMessage(msg);
        }
    }
    
    private Handler myHandler=new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
                if(msg.obj.toString().equals("0"))
                {
                    //通知listview更新数据
                    adapter.notifyDataSetChanged();
                }else if(msg.obj.toString().equals("1"))
                {
                    SyncHttp.showToast(MainActivity.this, "加载数据失败");
                }else
                {
                    SyncHttp.showToast(MainActivity.this, "网络异常");
                }
            }
        };

下面是listview的OnScrollListener事件,当listview滑动到最下面的时候,去数据库在取15条数据

/**
     * listview滑动事件,滑动到最下面的时候取数据库加载15条数据
     * 如果数据已经全部加载完了;移除listview脚部的view
     */
    private OnScrollListener scrollListener=new OnScrollListener() {
        @Override
        public void onScrollStateChanged(AbsListView arg0, int state) {
            if(lastitem==adapter.getCount() && state==OnScrollListener.SCROLL_STATE_IDLE)
            {
                if(lastitem==num)
                {
                    listview.removeFooterView(footer);
                    SyncHttp.showToast(MainActivity.this, "全部数据加载完成");
                }else
                {
                    index=String.valueOf(Integer.parseInt(index)+1);
                    Log.i("msg", "index="+index);
                    new MyThread().start();
                    adapter.notifyDataSetChanged();
                }
                Log.i("msg", "onScrollStateChanged--lastitem"+lastitem);
                Log.i("msg", "onScrollStateChanged--adapter.getCount"+adapter.getCount());
                Log.i("msg", "onScrollStateChanged--num"+num);
            }
        }
        @Override
        public void onScroll(AbsListView arg0, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
            lastitem=firstVisibleItem+visibleItemCount-1;
            Log.i("msg", "lastitem="+lastitem);
        }
    };

下面的代码是访问网络,(前面写的servlet返回json的方法) 并且返回json数据的方法 

/**
     * 访问网络并且返回json数据
     * @param indexs 当前页
     * @param sizes 每页的记录数
     * @return    0:返回数据成功  1:获取数据失败    2:异常错误
     */
    public String getListItem(String indexs,String sizes)
    {
        String re="0";
        try {
            String result= SyncHttp.httpGet(URL, "index="+indexs+"&size="+sizes);
//            Log.i("msg", "result="+result);
            JSONObject json = new JSONObject(result.toString());
            String isok = json.getString("isok");
            num = json.getInt("num");
            if ("0".equals(isok)) {
                JSONObject object = json.getJSONObject("data");
                JSONArray array = object.getJSONArray("commentlist");
                for (int i = 0; i < array.length(); i++) {
                    JSONObject obj = (JSONObject) array.opt(i);
                    HashMap<String, Object> map = new HashMap<String, Object>();
                    map.put("id", obj.getString("id"));
                    map.put("name", obj.getString("namg"));
                    map.put("patent", obj.getString("parent"));
                    datalist.add(map);
                }
            } else {
                //SyncHttp.showToast(MainActivity.this, "获取数据失败");
                re="1";
            }
        } catch (Exception e) {
            e.printStackTrace();
            re="2";
        }
        return re;
    }

因为我们要访问网络,在AndroidManifest.xml中加上

 <uses-permission android:name="android.permission.INTERNET" />

需要注意,不管是模拟器还是 真机测试;URL都要写本地的真是ip地址;否则会出现访问不了网络的情况

本实例模拟器 和真机都测试过,都是可以正常运行的

模拟器测试效果图

 

到此,Android客户端访问数据库基本已经完成。如果有错误的地方希望 高手指出。

 

posted @ 2013-08-23 14:55  最後的輕語  阅读(1736)  评论(4编辑  收藏  举报