Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> ListView之BaseAdapter和AsyncTask異步任務

ListView之BaseAdapter和AsyncTask異步任務

編輯:關於Android編程

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實例)

實例(從網絡上下載json數據、解析後設置到頁面上):

1、創建一個自定義的BaseAdapter : MyBaseAdapter 類,繼承BaseAdapter,重寫四個方法

public class MyBaseAdapter extends BaseAdapter {
    // 聲明變量,供getCount和getView使用
    Context context;
    List data;
    LayoutInflater inflater;// 用來實現對頁面的動態載入

    public MyBaseAdapter(Context context, List 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> {

    interface MyCallBack{
        public void getData(List list);
    }
    MyCallBack cb;

    public MyTask(MyCallBack cb) {
        super();
        this.cb = cb;
    }

    @Override
    protected List doInBackground(String... params) {
        try {
            String str = HttpUtils.getStringByHttp(params[0]);
            List jokeBeans = HttpUtils.getJokeBeans(str);
            return jokeBeans;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(List result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        cb.getData(result);

    }
}

3、通過異步實現圖片的下載並設置到ImageView上:

/**
 * 通過異步實現圖片的下載
 * 
 */
public class DownLoadImage extends AsyncTask {

    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 getJokeBeans(String str) throws JSONException {
        ArrayList data = new ArrayList();
        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 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();
        adapter = new MyBaseAdapter(this,data);
        lv.setAdapter(adapter);
        MyTask task = new MyTask(new MyCallBack() {

            @Override
            public void getData(List list) {
                data.addAll(list);
                adapter.notifyDataSetChanged();
            }
        });
        task.execute("http://api.1-blog.com/biz/bizserver/xiaohua/list.do?size=200&page=5");
    }

}

注意:要到配置清單裡配置聯網權限:

 

6、布局:my_listview_item.xml




    

    

    

    

activity_main.xml



    

效果圖1
效果圖2

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved