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"/>

至此,能够运行程序了,截图以下:

相关文章
相关标签/搜索