ListView的分页 复用convertView

(一)ListView的分页
  分页的必要性:实际开发中数据量往往都比较大  一次查询太多数据 效率比较低 界面也无法展示那么多数据。
  使用分页展示数据
  http://1000phone.net:8088/app/iAppFree/api/free.php?page=1&number=20
  1.pageIndex     url里面的page  想要展示第几页数据
  2.pageSize      url里面的number 每页展示几条数据
 
  url地址的规范  地址与参数之间使用?隔开    多个参数之间用&(&&)隔开
 
  使用按钮分页:  上一页 下一页 两个按钮
        当点击下一页的时候  重新使用MyAsyncTask查询网络数据
       
  滚动分页:1.给listView添加滚动的监听事件  理解监听事件中的两个方法
 
          给listView添加滚动的监听事件 当我们鼓动listView的时候 它有三种状态
            public static int SCROLL_STATE_IDLE = 0; //停顿的
            public static int SCROLL_STATE_TOUCH_SCROLL = 1; //触摸滚动
            public static int SCROLL_STATE_FLING = 2;  //猛冲  
    
  滑动到末尾加载新数据的条件
  1、当状态是SCROLL_STATE_IDLE (停顿的时候)加载新数据
  2、滑动最底部
     //firstVisibleItem    第一个可见条目 (position)
     //visibleItemCount    可见的条目总数
     //totalItemCount      总条目数
     当第一条可见+ 可见的条目总数  =  总条目数 意味着滑动到最底部

(二)解决复用convertView出现的一些问题
    例如:复选框选择错位 图片加载错位

编写
  activity_main.xml  添加一个ListView
  MainActivity.java  适配器控件使用的五个步骤
  MyAdapter
            getCount()
            getView();    
                条目布局        
                ViewHolder
                
  MyAsyncTask
            doInBackgroud()  
                HttpUtils
            onPostExecute()
                JsonUtils
                
  ImageAsyncTask    
            doInBackgroud()  
                HttpUtils
            onPostExecute()
                imageView.setImageBitmp(bm);
                
    注意: ImageAsyncTask写完之后是在自定义适配器(MyAdapter)中调用


    分页:
    1.listView添加监听器  实现两个对滚动监听的方法
    2.根据两个方法的参数在适当的时候重新加载下一页的数据
    3.添加footerView




ListView 进行数据切换  
        思路 :创建两个适配器


AsyncTask 1.5  串行操作
AsyncTask 2.   并行操作
AsyncTask 4    串行(默认)+并行


回顾
getView(); 会被调用很多
每调用一次都需要创建一个条目布局(View对象)
优化ListView
1.listView的布局 宽和高 都是填充父窗体
2.复用convertView
  convertView是getView方法的一个参数   convertView复用废弃view对象
   使用convertView的好处是复用已经退出屏幕的view对象  而不是重新新的view对象
3.ViewHolder
    ViewHolder的好处  减少findViewById的查找次数
    使用的步骤
    1.第一次加载的时候把查找的控件存到ViewHolder的对象中
    2.把ViewHolder的对象放入convertView中
    3.convertView取出ViewHolder的对象 ,然后从ViewHolder的对象中取出控件对象

当代码量比较多的时候  多去记忆过程(代码运行的流程和步骤)    
第三个例子

package com.qf.day09_listview03;
public class MainActivity extends Activity {
    List<Game> data;
    MyAdapter adapter;
    boolean flag = false;
    int pageIndex = 1;
    View footView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.
        ListView listView = (ListView) findViewById(R.id.lv);
        //2.
        data = new ArrayList<>();
        //3.
        adapter = new MyAdapter(MainActivity.this,data);
        
        footView = getLayoutInflater().inflate(R.layout.footer, null);
        listView.addFooterView(footView);
        
        //4.
        listView.setAdapter(adapter);
        //5.
        new MyAsyncTask(MainActivity.this,data,adapter)
                .execute("http://1000phone.net:8088/app/iAppFree/api/free.php?page="+pageIndex+"&number=20");
        
        listView.setOnScrollListener(new OnScrollListener() {
            
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                    if(flag == true && scrollState == OnScrollListener.SCROLL_STATE_IDLE){
                        pageIndex = pageIndex + 1;
                        new MyAsyncTask(MainActivity.this,data,adapter)
                            .execute("http://1000phone.net:8088/app/iAppFree/api/free.php?page="+pageIndex+"&number=20");
                    }
            }
            
            @Override
            public void onScroll(AbsListView view, int firstVisibleItem,
                    int visibleItemCount, int totalItemCount) {
                    if( firstVisibleItem + visibleItemCount  ==  totalItemCount ){
                            flag = true;
                    }else{
                            flag = false;
                    } }
             });   
    }

}

package com.qf.day09_listview03;
public class MyAdapter extends BaseAdapter{
    Context context;
    List<Game> data;
    
    Map<String,Bitmap> cacheImage  = new HashMap<>();//用来存储已经浏览过的图片
    
    public MyAdapter(Context context, List<Game> data) {
        super();
        this.context = context;
        this.data = data;
    }
    @Override
    public int getCount() {
        return data.size();
    }
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if(convertView == null){
            convertView = View.inflate(context, R.layout.item01, null);
            
            holder = new ViewHolder();
            holder.imageView = (ImageView) convertView.findViewById(R.id.item_iv);
            holder.textView = (TextView) convertView.findViewById(R.id.item_tv);
            
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }
        Game game = data.get(position);
        holder.textView.setText(game.name);
        holder.imageView.setTag(game.iconUrl);
        
        if(cacheImage.containsKey(game.iconUrl)){//从缓存中读取图片
            holder.imageView.setImageBitmap(cacheImage.get(game.iconUrl));
        }else{//如果缓存中不存在该图片则访问网络获取图片
            //设置一个预览图片
            holder.imageView.setImageResource(R.drawable.logo);
            
            new ImageAsyncTask(context, holder.imageView,position,game.iconUrl,cacheImage)
            //.execute(game.iconUrl);
            //子线程并行执行
            .executeOnExecutor(Executors.newFixedThreadPool(1), game.iconUrl);
        }  
        return convertView;
    }
    class ViewHolder{
        ImageView imageView;
        TextView textView;
    }
    //--------------------------------------------------------------------
    @Override
    public Object getItem(int position) {
        return null;
    }
    @Override
    public long getItemId(int position) {
        return 0;
    }
    
}
package com.qf.day09_listview03;import java.util.List;
import android.content.Context;import android.os.AsyncTask;
import android.widget.Toast;
public class MyAsyncTask extends AsyncTask<String, Void, byte[]>{    Context context;  
  List<Game> data;   
   MyAdapter adapter;       
 public MyAsyncTask(Context context, List<Game> data, MyAdapter adapter) {       
  super(); 
   this.context = context;      
    this.data = data;       
     this.adapter = adapter;    
     }   
 @Override    
protected byte[] doInBackground(String... params) {     
   return HttpUtils.getData(params[0]);    }     
@Override   
protected void onPostExecute(byte[] result) {        
super.onPostExecute(result);       
 if(result != null){            
 String jsonString = new String(result);          
   List<Game> data2 = JsonUtils.parseJson(jsonString);                    
       data.addAll(data2);          
         adapter.notifyDataSetChanged();     
          }else{          
            Toast.makeText(context, "网络异常", Toast.LENGTH_SHORT).show();       
             }    }        }
package com.qf.day09_listview03;
public class JsonUtils {
    public static List<Game> parseJson(String jsonString) {
        List<Game> data2 = new ArrayList<>();
        try {
            JSONObject obj1 = new JSONObject(jsonString);
            JSONArray array = obj1.getJSONArray("applications");
            Game game;
            for(int i=0;i<array.length();i++){
                    JSONObject obj2 = array.getJSONObject(i);
                    game = new Game();
                    game.name = obj2.getString("name");
                    game.iconUrl = obj2.getString("iconUrl");
                    data2.add(game);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return data2;
    }
}


你可能感兴趣的:(ListView的分页 复用convertView)