ListView之BaseAdapter和AsyncTask异步任务

来源:互联网 发布:淘宝贷款在哪里还 编辑:程序博客网 时间:2024/05/22 03:36

BaseAdapter

BaseAdapter是实现了ListAdapter和SpinnerAdapter两个接口,当
然它也可以直接给ListView和Spinner等UI组件直接提供数据。
BaseAdapter的需要重写四个方法:
1、getCount()决定了我们将要绘制的资源数,当然这个数目不能大于资源的总数,不过却可以小于资源的总数。
2、getItemId()该方法的返回值决定第position处的列表项的ID,某些方法(如onclicklistener的onclick方法)有id这个参 数,而这个id参数就是取决于getItemId()这个返回值的。
3、getView():通过传入的参数position,加工成我们想要的View并返回,最终共GridView使用
4、getItem():getItem方法不是在Baseadapter类中被调用的,而是在Adapterview.getItemAtPosition(position) 中被调用的。getItemAtPosition(position) 是在setOnItemClickListener、setOnItemLongClickListener、setOnItemSelectedListener的点击选择处理事件中方便地调用来获取当前行数据的。

LayoutInflater inflater的作用

1、对于一个没有被载入或者想要动态载入的界面, 都需要使用inflate来载入.
2、对于一个已经载入的Activity, 就可以使用实现了这个Activiyt的的findViewById方法来获得其中的界面元素.

AsyncTask:

作用及使用场景:后台线程执行异步任务,将result告知UI线程;子线程和主线程(UI线程)需要通讯的时候,可以使用AsyncTask
使用方法:
1.创建 AsyncTask 的子类,并为三个泛型参数指定类型。不需要则可指定Void。
Params:输入参数。对应的是调用自定义的AsyncTask的类中调用excute()方法中传递的。
Progress:子线程执行的百分比。
Result:返回值类型。和doInBackground()方法的返回值类型保持一致。
2.根据需要,实现 AsyncTask 的如下方法:
doInBackground(Params…)重写该方法就是后台线程将要完成的任务。该方法可调用 publishProgress(Progress… values)方法更新任务的执行进度。
onProgressUpdate(Progress… values)在doInBackground() 方法中调用publishProgress()方法更新任务的执行进度后,该方法被触发。
onPreExecute() :该方法将在执行后台耗时操作前被调用。通常用于完成一些初始化的准备工作,比如在界面上显示进度条。
onPostExecute(Result result) :当 doInBackground() 完成后,系统会自动调用该方法,并将 doInBackground() 的返回值传给该方法。
3.调用 AsyncTask 子类的实例的 execute(Params… params) 开始执行耗时任务。
使用AsyncTask 时必须遵守如下规则:
必须在 UI 线程中创建 AsyncTask 的实例。
必须在 UI 线程中调用 AsyncTask 的 execute() 方法。
AsyncTask的实例只能启动一次(若要多次调用,则每次调用都需要新创建一个AsyncTask实例)

实例(从网络上(”http://api.1-blog.com/biz/bizserver/xiaohua/list.do?size=100&page=5“)下载json数据、解析后设置到页面上):

1、创建一个自定义的BaseAdapter : MyBaseAdapter 类,继承BaseAdapter,重写四个方法

public class MyBaseAdapter extends BaseAdapter {    // 声明变量,供getCount和getView使用    Context context;    List<JokeBean> data;    LayoutInflater inflater;// 用来实现对页面的动态载入    public MyBaseAdapter(Context context, List<JokeBean> data) {        this.context = context;        this.data = data;        // 载入传递过来的Activity,这里是载入MainActivity.class        inflater = LayoutInflater.from(context);    }    @Override    public int getCount() {        return data.size();    }    @Override    public Object getItem(int position) {        return data.get(position);    }    @Override    public long getItemId(int position) {        return data.get(position).id;    }    // getView:返回每一个Item的View    // 步骤:    /*     * 1.写一个内部类ViewHolder,用来保存需要设置值的控件(以空间换时间)     * 2.在getView方法中,声明一个ViewHolder对象,并置为null     * 3.根据convertView是否为null,决定是否创建新的View还是复用View     * 4.如果是创建新的View,利用LayoutInflater把xml文件转换成View,并赋值给convertView     * 创建一个新的ViewHoder,并对ViewHoder中的控件进行初始化 把创建的ViewHoder关联到convertView     * 5.如果是复用的View,说明已经有ViewHoder与convertView进行关联过,直接取出对应的Tag     * 6.对ViewHoder中的控件进行赋值     */    @Override    public View getView(int position, View convertView, ViewGroup parent) {        // 创建ViewHoder对象        Viewhondler hondler = null;        // 根据convertView判断是否创建新的View        if (convertView == null) {            hondler = new Viewhondler();            // 通过inflate方法来载入layout的xml            convertView = inflater.inflate(R.layout.my_listview_item, null);            hondler.tv_id = (TextView) convertView.findViewById(R.id.tv_id);            hondler.tv_author = (TextView) convertView                    .findViewById(R.id.tv_author);            hondler.tv_content = (TextView) convertView                    .findViewById(R.id.tv_content);            hondler.iv = (ImageView) convertView.findViewById(R.id.img);            // 把hoder与convertView关联            convertView.setTag(hondler);        } else {            // 已经有可用视图,说明已经有holder与convertView进行关联过,取出Tag,并赋值给holder对象            hondler = (Viewhondler) convertView.getTag();        }        // 给各个控件设置初始值,解决图片错位等问题        hondler.iv.setImageResource(R.drawable.ic_launcher);        hondler.tv_author.setText("");        hondler.tv_content.setText("");        hondler.tv_id.setText("");        // 取消前面的下载任务,要在新下载任务启动之前先取消        if (hondler.task != null) {            hondler.task.cancel(true);        }        // 给相应控件设置值        JokeBean bean = data.get(position);        hondler.tv_id.setText("id:" + bean.id);        hondler.tv_author.setText("作者:" + bean.author);        hondler.tv_content.setText(bean.content);        DownLoadImage task = new DownLoadImage(hondler.iv);        hondler.task = task;        task.execute(bean.picUrl);        // 返回设置好的值的View        return convertView;    }    class Viewhondler {        DownLoadImage task;// 图片下载任务        TextView tv_id;        TextView tv_xhid;        TextView tv_author;        TextView tv_content;        ImageView iv;    }}

2、通过异步从网络上下载数据
MyTask .class 继承了AsyncTask,里面自定义了MyCallBack接口,用于接口回调传回下载后的数据。

public class MyTask extends AsyncTask<String, Void, List<JokeBean>> {    interface MyCallBack{        public void getData(List<JokeBean> list);    }    MyCallBack cb;    public MyTask(MyCallBack cb) {        super();        this.cb = cb;    }    @Override    protected List<JokeBean> doInBackground(String... params) {        try {            String str = HttpUtils.getStringByHttp(params[0]);            List<JokeBean> jokeBeans = HttpUtils.getJokeBeans(str);            return jokeBeans;        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }    @Override    protected void onPostExecute(List<JokeBean> result) {        // TODO Auto-generated method stub        super.onPostExecute(result);        cb.getData(result);    }}

3、通过异步实现图片的下载并设置到ImageView上:

/** * 通过异步实现图片的下载 *  */public class DownLoadImage extends AsyncTask<String, Void, Bitmap> {    ImageView iv;    public DownLoadImage(ImageView iv) {// 接收传递过来的ImageView控件        this.iv = iv;    }    @Override    protected Bitmap doInBackground(String... params) {        try {            // 调用HttpUtils的getBitmapByHttp()方法联网下载图片            Bitmap bitmap = HttpUtils.getBitmapByHttp(params[0]);            return bitmap;        } catch (Exception e) {            e.printStackTrace();        }        return null;    }    @Override    protected void onPostExecute(Bitmap result) {        // TODO Auto-generated method stub        super.onPostExecute(result);        // 下载完成后得到Bitmap,给ImageView设置值,判断当前任务是否被取消,如果当前任务被取消,就不再设置图片,        //避免异步加载时图片连闪和错位问题        if (result != null && !isCancelled()) {            iv.setImageBitmap(result);        }    }}

4、下载工具类

/** * 下载工具类 *  */public class HttpUtils {    public static String getStringByHttp(String http) throws Exception {        HttpURLConnection connection = null;        URL url = new URL(http);        connection = (HttpURLConnection) url.openConnection();        InputStream in = connection.getInputStream();        StringBuilder sb = new StringBuilder();        BufferedReader br = new BufferedReader(new InputStreamReader(in));        String temp = null;        while ((temp = br.readLine()) != null) {            sb.append(temp);        }        br.close();        connection.disconnect();        return sb.toString();    }    public static List<JokeBean> getJokeBeans(String str) throws JSONException {        ArrayList<JokeBean> data = new ArrayList<JokeBean>();        JSONObject object = new JSONObject(str);        JSONArray arr = object.getJSONArray("detail");        int len = arr.length();        for (int i = 0; i < len; i++) {            JSONObject obj  = arr.getJSONObject(i);            JokeBean bean1 = new JokeBean();            bean1.id = obj.getInt("id");            bean1.xhid = obj.getInt("xhid");            bean1.author = obj.getString("author");            bean1.content = obj.getString("content");            bean1.picUrl = obj.getString("picUrl");            data.add(bean1);        }        return data;    }    public static Bitmap getBitmapByHttp(String http) throws Exception {        HttpURLConnection conn = null;        URL url = new URL(http);        conn = (HttpURLConnection) url.openConnection();        InputStream in = conn.getInputStream();        Bitmap bitmap = BitmapFactory.decodeStream(in);        in.close();        conn.disconnect();        return bitmap;    }}

5、MainActivity类,主入口

public class MainActivity extends Activity {    private ListView lv;    private MyBaseAdapter adapter;    private List<JokeBean> data;    Context context;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        lv = (ListView) findViewById(R.id.lv);        initData();    }    private void initData() {        data = new ArrayList<JokeBean>();        adapter = new MyBaseAdapter(this,data);        lv.setAdapter(adapter);        MyTask task = new MyTask(new MyCallBack() {            @Override            public void getData(List<JokeBean> list) {                data.addAll(list);                adapter.notifyDataSetChanged();            }        });        task.execute("http://api.1-blog.com/biz/bizserver/xiaohua/list.do?size=200&page=5");    }}

注意:要到配置清单里配置联网权限:

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

6、布局:my_listview_item.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:orientation="vertical" >    <TextView        android:id="@+id/tv_id"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textSize="20sp" />    <TextView        android:id="@+id/tv_author"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:textSize="25sp" />    <TextView        android:id="@+id/tv_content"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:background="@drawable/input_over"        android:textSize="20sp" />    <ImageView        android:id="@+id/img"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center_horizontal"        android:src="@drawable/ic_launcher" /></LinearLayout>

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:paddingBottom="@dimen/activity_vertical_margin"    android:paddingLeft="@dimen/activity_horizontal_margin"    android:paddingRight="@dimen/activity_horizontal_margin"    android:paddingTop="@dimen/activity_vertical_margin"    tools:context="ljw.day009_night_baseadapter.MainActivity" >    <ListView        android:id="@+id/lv"        android:layout_width="match_parent"        android:layout_height="match_parent" /></RelativeLayout>

效果图1
效果图2

0 0
原创粉丝点击