ListView之BaseAdapter和AsyncTask异步任务

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值