Android--ListView及BaseAdapter的使用

ListView適用於顯示數組或集合類型的數據;
BaseAdapter是數據轉化成UI,並將UI添加到ListView中。java

使用步驟

1)在佈局文件中引用<ListView>
2)在res/layout目錄下建立一個item佈局,用在BaseAdapter中;Item佈局是顯示一條數據的佈局頁面
3)建立BaseAdapter的子類,並接受一個數據源
    重寫四個核心方法:android

  • int getCount()  返回數據源的大小
  • long getItemId(int position)  返回指定位置數據的ID
  • Object getItem(int position)  返回指定位置的數據
  • View getView(int position, View convertView, ViewGroup parent) 

                將指定的位置數據轉化爲UI並返回json

4)在MainActivity中查找ListView和實例化BaseAdapter子類對象,並向BaseAdapter類中傳入一解析json的數據源,最後將ABaseAdapter子類對象綁定到ListView中。api

項目實例

實現一個新聞APP的瀏覽頁面:每條新聞包括標題、圖片及簡介。數組

從網上找到一個農業新聞API:網絡

http://www.tngou.net/api/info/news併發

能夠獲得json數據app

{
    "status": true,
    "total": 6739,
    "tngou": [
        {
            "count": 4892,
            "description": "將建設省灰霾重點實驗室,開展霧霾的造成機理、區域大氣環流與污染物擴散輸送規律、大氣環境中二次污染物造成機理及轉化等科學性、基礎性研究,解析河北省大氣複合污染的特徵及成因,解決對霧霾成因、機理及防治對策缺少深刻研究的不足",
            "fcount": 0,
            "id": 1,
            "img": "/info/150729/1da9250d7071e3ef82601a596d37e320.jpg",
            "infoclass": 6,
            "keywords": "河北省 萬噸 生產線 實驗室 北京 ",
            "message": "<p>  </p> \n<p> 在京津冀協同應對大氣污染上,河北省今年將減煤1500萬噸,壓減鋼鐵產能1500萬噸,同時,環首都圈將再也不佈局新的水泥企業。此外,河北省還將建設灰霾實驗室,從技術層面應對大氣污染。 </p> \n<p> <strong>今年減煤1500萬噸</strong> </p> \n<p> 在污染物控制上,河北省今年將主要從減煤、控車、降塵、治企等方面作工做。根據《河北省削減煤炭消費及壓減鋼鐵等產能任務分解方案》,到2017年末河北省煤炭削減總量要比2012年淨削減4000萬噸。按照這一目標,河北省肯定了2014年比2012年壓減1500萬噸煤炭消費的目標任務,並分解落實到各設區市。 </p> \n<p> <strong>環首都圈將不佈局新的水泥企業</strong> </p> \n<p> 河北省提出了「6643」工程(到2017年壓減6000萬噸鋼鐵、6000萬噸水泥、4000萬噸煤、3000萬重量箱玻璃) 。河北省工信廳相關負責人表示,河北省下一步工做將組織好鋼鐵、水泥、平板玻璃三個行業結構調整方案的實施。進一步優化太行山—燕山一帶水泥產業佈局,在環首都圈、環省會圈地區堅定再也不佈局新的水泥企業。 </p> \n<p> <strong>將建灰霾實驗室</strong> </p> \n<p> 此外,河北省還將藉助科技手段,加大對空氣污染的防治。將建設省灰霾重點實驗室,開展霧霾的造成機理、區域大氣環流與污染物擴散輸送規律、大氣環境中二次污染物造成機理及轉化等科學性、基礎性研究,解析河北省大氣複合污染的特徵及成因,解決對霧霾成因、機理及防治對策缺少深刻研究的不足。河北省環保廳相關負責人透露,從2013年6月開始組織專家到全國進行調研,一些建設方案目前已經基本編制完成並經過第一次專家論證,下一步將繼續完善。 </p> \n<p> 河北省環境監測中心站總工程師嚴永路表示,這個灰霾實驗室將立足河北現有的監測力量,採用衛星遙感結合實驗室分析、地面監測技術。實驗室除了開展預警預測外,還將重點研究河北省灰霾發生的機理,爲全省的環境管理提供技術層面的支持。 </p> \n<p> 他表示,他們爭取在2015年初步造成監測、研究能力。他說,灰霾實驗室可能會在河北環繞北京、天津的各地分佈監測點,以配合京津冀大氣污染聯防聯控工做。 </p> \n<p> <strong>相關新聞</strong> </p> \n<p> <strong>北京「小蘇打」生產線外遷邯鄲</strong> </p> \n<p> 昨天上午,「北京凌雲」建材化工總體搬遷現場對接會在河北邯鄲舉行。伴隨着國內龍頭醫藥級「小蘇打」生產線總體遷出北京,北京第一家外遷企業正式在河北邯鄲落成,率先按下「京津冀」一體化啓動鍵。 </p> \n<p> 做爲擁有50多年「小蘇打」生產歷史、產品在國內藥用市場佔有率第一的建材化工有限公司,北京凌雲擁有國內高端食用碳酸氫鈉第一品牌「山花」生產線。然而因爲建廠時間較長,生產設備老化,自動化程度低,能源資源消耗高,加之用煤炭生產CO2,污染較重,已不適合在首都生存。 </p> \n<p> 這次搬遷,凌雲醫藥化工有限公司將醫藥級碳酸氫鈉生產線從北京豐臺區總體搬遷轉移到河北邯鄲。據測算,生產線總體搬遷後,項目一期可實現北京和河北每一年綜合下降二氧化碳排放2.2萬噸,耗電量將減小1080萬度,用水量減小58.8萬噸,煤炭消耗和粉塵排放也將分別由原來的5.29萬噸和0.12萬噸減小到0。同時可吸納當地150人左右就業。 </p> \n<p> 「小蘇打」生產線遷出後,據瞭解,凌雲公司原址將「騰籠換鳥」,着力發展應急救援產業。 </p> \n<br>",
            "rcount": 0,
            "time": 1438141075000,
            "title": "河北北京天津治療大氣污染 將建灰霾實驗室"
        },
        {
            "count": 3358,
            "description": "到了當地醫院後,進行了鋇餐和食道鏡的檢查,發現食道黏膜有點損傷,但沒有發現有什麼異物,吃了一些消炎藥,李師傅也忘記了被雞骨頭卡的事情",
            "fcount": 0,
            "id": 2,
            "img": "/info/150729/c96da5303be57a916e62ca79ecb9930d.jpg",
            "infoclass": 3,
            "keywords": "雞骨頭 李師傅 食道 病人 醫院 ",
            "message": "<p> 高淳的李師傅怎麼也沒想到,他爲一塊雞骨頭付出如此昂貴的代價。這塊雞骨頭真是「尖銳」,不但穿破食道壁,可能滑進身體的一個「三角地帶」,還形成感染休克,一個多月瘦了30斤,開胸引流手術也花費17萬元。今天,李師傅通過治療後,能夠出院了,他想起這一個多月的惡夢般經歷仍是心有餘悸。通信員 劉敏 現代快報記者 安瑩 </p> \n<p>  </p> \n<br> \n<p> <strong>雞骨頭劃破食道,繼續吃飯</strong> </p> \n<p> 今年3月初,40多歲的李師傅和朋友一塊兒吃飯的時候,不當心將一小塊雞骨頭給吞進去了。吃完以後,感受到咽喉的地方有點疼痛,猜想多是雞骨頭卡住了,想吃饅頭來把骨頭給嚥下去,但做用不大。到了當地醫院後,進行了鋇餐和食道鏡的檢查,發現食道黏膜有點損傷,但沒有發現有什麼異物,吃了一些消炎藥,李師傅也忘記了被雞骨頭卡的事情。 </p> \n<p> 四天後,李師傅忽然胸部疼得很厲害,併發高燒,達到39℃。家裏人懷疑與「雞骨頭」有關,就到當地醫院作CT,查找這塊雞骨頭,但也僅僅檢查到縱膈裏有積液,沒有找到雞骨頭。而在這時候,李師傅的病情開始嚴重了,屢次出現重度休克。 </p> \n<p> <strong>雞骨頭究竟滑到哪裏去了?</strong> </p> \n<p> 3月5日,李師傅被家人送到了南京中大醫院。該院胸心外科主任薛濤介紹,他們經過各類醫學手段反覆尋找,這塊雞骨頭可能滑進了縱隔裏。 </p> \n<p> 縱膈在哪?薛濤說,它不是器官,而是一個解剖的區域。縱膈位於雙側胸腔之間,胸骨以後,脊柱側面,上爲頸部入口,下達膈肌。爲了便於診斷和治療,人爲地將它分爲上下先後四個區域。在這個區域裏有心臟及出入心臟的大血管、食管、氣管、胸腺、神經及淋巴組織等,因此它是重要生命器官的所在地。 </p> \n<p> 薛濤說,李師傅入院的時候,已經處於重度感染性休克的狀態。因爲異物已經劃破食道,他又在當地醫院,進行了鋇餐的檢查,引起化學性的感染,再加上他自己已經存在細菌性的感染。 </p> \n<p> 據薛濤主任介紹:「這個手術有很是大的難度。由於病人存在大範圍的縱隔感染、心包積液等問題,可是若是不及時救治,病人可能會因感染性休克而病重。在告知病人家眷的狀況下,咱們開始了驚險的手術。」 </p> \n<p> 薛濤回想手術過程,仍心有餘悸:「手術中,病人麻醉後,病人的心率不是很穩定,再加上心包積液壓迫心臟等緣由,心率最快時飆到180次/分。迫使咱們要等到病人平穩後,再給病人手術。這種反覆的心率不穩定,手術中有四、5次,每一次咱們的心都是懸着的。」 </p> \n<p> <strong>一個多月瘦了30斤,花了17萬</strong> </p> \n<p> 據介紹,目前李師傅已經差很少康復,今天就要出院了。「真沒想到,小小的雞骨頭,居然差點要了個人命。在醫院待了這一個多月的時間,花了17萬,全身插着各類管子,體重也從原來的170斤左右,降低到140斤。」李師傅語氣中有些懊悔,「我平時吃飯就快,卻沒想到會有這麼嚴重的後果。」 </p> \n<p> 專家指出,若是吞食了異物感到不舒服,在24小時內的話,早期破裂口未造成炎症水腫,能夠在胸外科直接進行修補,而後加以引流。若是是24小時以後的話,就要開胸引流。李師傅要是不耽誤了4天時間,病情也不至於這麼重。 </p> \n<p> <strong>男性吃東西更要注意細嚼慢嚥</strong> </p> \n<p> 中大醫院胸心外科主任薛濤說:「咱們接診過魚刺、骨頭卡住的比較嚴重的病人,80%是男性。因爲男性吃飯廣泛比較快,咀嚼不充分,加上喝酒,話也比較多,很容易被細小的魚刺、骨頭卡住。」專家提醒,若是硬物卡住喉嚨,民間經常使用一些土辦法如吃饅頭、吃白飯、喝醋軟化等來解決,這樣都是不科學的,甚至會加劇病情。 </p> \n<p> 薛濤建議,魚刺、骨頭等異物卡住食道,多在內鏡下就能夠取出。若是骨頭卡住的位置在胸部,並造成隱性穿孔,如不及時處理,有可能局部出現膿腫或食道瘻,甚至可能穿出食道,刺破主動脈,引發致命性大出血。所以,一旦喉嚨裏被尖銳異物卡住,最好能儘快到醫院取出。 </p> \n<br>",
            "rcount": 0,
            "time": 1438141077000,
            "title": "誤吞雞骨頭卡在食道里 一個多月瘦了30斤,花了17萬"
        }
    ]
}

處理該數據,而且顯示到界面上ide

步驟:工具

1.activity_main.xml文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    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="com.example.wang.hnews.MainActivity">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</RelativeLayout>

2.新建佈局文件item_healthnews.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/titleText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="新聞標題"/>

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_below="@id/titleText" />

    <TextView
        android:id="@+id/descriptionText"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:layout_below="@id/titleText"
        android:layout_toRightOf="@id/imageView"
        android:textSize="15sp"
        android:textColor="#515151"
        android:text="在這裏顯示新聞概要"/>

</RelativeLayout>

界面效果以下:

3.建立新聞數據類

//HealthNews.java

package com.wang.entity;

/**
 * 新聞類:包含新聞的標題、描述、圖片及發佈時間
 *
 * Created by WANG on 2016/9/20 0020.
 */

public class HealthNews {
    private String title;
    private String description;
    private String image;
    private long time;

    public HealthNews() {
    }

    public HealthNews(String title, long time, String image, String description) {
        this.title = title;
        this.time = time;
        this.image = image;
        this.description = description;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getImage() {
        return image;
    }

    public void setImage(String image) {
        this.image = image;
    }

    public long getTime() {
        return time;
    }

    public void setTime(long time) {
        this.time = time;
    }
}

4.建立資源類

//URLs.java

package com.wang.resources;

/**
 * URL資源類
 *   1.要請求的URL
 *   
 * Created by WANG on 2016/9/20 0020.
 */

public class URLs {
    public static final String news_URL = "http://www.tngou.net/api/info/news";
}

5.建立工具類

//X.java

package com.wang.utils;

import android.util.Log;

import com.wang.entity.HealthNews;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

/**
 * 工具類
 *   1.Http網絡請求
 *   2.解析JSON數據
 *   
 * Created by WANG on 2016/9/20 0020.
 */

public final class X {
    //Http請求
    public static byte[] get(String url) throws Exception{
        URL url1 = new URL(url);
        HttpURLConnection conn = (HttpURLConnection) url1.openConnection();
        InputStream inputStream = conn.getInputStream();

        byte[] buffer = new byte[10*1024];  //緩衝區大小
        int len = -1; //讀取長度
        //用於保存網絡讀取的數據的輸出流
        ByteArrayOutputStream baos = new ByteArrayOutputStream(0);
        //獲取網絡資源總長度
        long sumLength = conn.getContentLength();
        //當前讀取的長度
        long curLength = 0;

        //判斷打開連接是否成功
        if(conn.getResponseCode() == 200) {
            while((len = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, len);
                //打印讀取的進度: 當前已讀取的長度/網絡資源的總長度
                curLength += len; //累加本次讀取的資源大小
                int progress = (int) (curLength*100 / sumLength);
                Log.d("wang", "已下載:" + progress +"%");
            }
            return baos.toByteArray();
        }
        return null;
    }

    //解析json數據
    public static List<HealthNews> parseHealthNews(String json) throws Exception {
        List<HealthNews> list = new ArrayList<HealthNews>();

        JSONObject obj = new JSONObject(json);
        JSONArray array = obj.getJSONArray("tngou");

        for(int i = 0; i < array.length(); ++i) {
            JSONObject data = array.getJSONObject(i);

            String title = data.getString("title");
            String description = data.getString("description");
            String image = data.getString("img");
            long time = data.getLong("time");

            list.add(new HealthNews(title, time, image, description));
        }
        return list;
    }
}

6.HealthNewsAdapter適配器

//HealthNewsAdapter.java

package com.wang.adapter;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.Looper;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.example.wang.hnews.R;
import com.wang.entity.HealthNews;
import com.wang.utils.X;

import java.util.List;

/**
 * Created by WANG on 2016/9/20 0020.
 */

public class HealthNewsAdapter extends BaseAdapter {
    private List<HealthNews> mDatas; //數據源
    private Handler mHandler;

    public HealthNewsAdapter(List<HealthNews> datas) {
        this.mDatas = datas;
        mHandler = new Handler(Looper.getMainLooper());
    }

    @Override
    public int getCount() {
        return mDatas.size();
    }

    @Override
    public HealthNews getItem(int i) {
        return mDatas.get(i);
    }

    @Override
    public long getItemId(int i) {
        return i;
    }

    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {
        //加載item佈局,並返回View
        view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_healthnews, null);

        final ImageView imageView = (ImageView) view.findViewById(R.id.imageView);
        TextView titleText = (TextView) view.findViewById(R.id.titleText);
        TextView descriptionText = (TextView) view.findViewById(R.id.descriptionText);

        titleText.setText(getItem(i).getTitle());
        descriptionText.setText(getItem(i).getDescription());

        final String imagePath = "http://tnfs.tngou.net/img" + getItem(i).getImage();
        new Thread() {
            @Override
            public void run() {
                try {
                    byte[] bs = X.get(imagePath);
                    final Bitmap bitmap = BitmapFactory.decodeByteArray(bs, 0, bs.length);
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            imageView.setImageBitmap(bitmap);
                        }
                    });
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
        return view;
    }

    //封裝Item佈局中的控件,爲了減小在複用item時findViewById()方法的執行次數
    class ViewHolder{
        TextView titleText;
        TextView descriptionText;
        ImageView imageView;
    }
}

6.MainActivity.java文件添加代碼

//MainActivity.java

package com.example.wang.hnews;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;

import com.wang.adapter.HealthNewsAdapter;
import com.wang.entity.HealthNews;
import com.wang.resources.URLs;
import com.wang.utils.X;

import java.io.IOException;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private ListView listView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = (ListView) findViewById(R.id.listView);

        new Thread() {
            @Override
            public void run() {
                try {
                    byte[] result = X.get(URLs.news_URL);
                    Log.d("wang", "請求成功");

                    final String resultStr = new String(result);

                    //解析Json數據
                    final List<HealthNews> list = X.parseHealthNews(resultStr);

                    //將數據顯示到UI控件上
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            HealthNewsAdapter adapter = new HealthNewsAdapter(list);
                            listView.setAdapter(adapter);
                        }
                    });
                } catch (IOException e) {
                    e.printStackTrace();
                    Log.d("wang", "請求失敗。。。");
                } catch (Exception e1) {
                    e1.printStackTrace();
                    Log.d("wang", "解析失敗。。。");
                }
            }
        }.start();
    }
}

7.添加網絡訪問權限

必須在AndroidManifest.xml中添加代碼:

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

至此,能夠運行程序了,截圖以下:

相關文章
相關標籤/搜索