新闻客户端

从服务器中获取新闻,然后以列表的形式显示到界面上,每一个条目有图片/标题/正文/评论数
服务器把新闻保存在数据库里,把新闻给客户端就是把数据从数据库里取出来,封装到xml文件里,然后把xml给客户端,客户端再解析xml
也就是说客户端请求新闻信息的时候是请求所有新闻的文本信息以及新闻所属图片的网址,拿到网址,再对网址单独请求一次图片

界面布局

加一个ListView就可以了

<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"
    tools:context=".MainActivity" >

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

</RelativeLayout>

每个条目的布局

<?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="wrap_content" >

    <com.loopj.android.image.SmartImageView  开源项目自定义控件
        android:id="@+id/iv"
        //宽高要写死防止不匹配
        android:layout_width="100dp"
        android:layout_height="80dp"
        android:src="@drawable/ic_launcher"
        //图片竖直居中
        android:layout_centerVertical="true"
        />
    <TextView 
        android:id="@+id/tv_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这是大标题"
        //不要换行,多余的部分会用...显示
        android:singleLine="true"
        android:layout_toRightOf="@id/iv"
        android:textSize="22sp"
        />
    <TextView 
        android:id="@+id/tv_detail"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="这里是正文kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk"
        android:layout_toRightOf="@id/iv"
        android:layout_below="@id/tv_title"
        android:textSize="14sp"
        android:textColor="@android:color/darker_gray"
        //正文只能是两行
        android:lines="2"
        />
    <TextView 
        android:id="@+id/tv_comment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="2333条评论"
        android:textColor="#ff0000"
        //位于条目右下方
        android:layout_alignParentRight="true"
        android:layout_below="@id/tv_detail"
        />
</RelativeLayout>

获取xml文件并解析

点击启动客户端时新闻就已经下载了

    //获取新闻信息
    private void getNewsInfo() {
        //开一个子线程去下载新闻信息
        Thread t = new Thread(){
            @Override
            public void run() {
                //先确定新闻的网址
                String path = "http://10.66.98.197/news.xml";
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(5000);
                    conn.setReadTimeout(5000);
                    //发送http GET请求获取响应码
                    if(conn.getResponseCode() == 200){
                        InputStream is = conn.getInputStream();
                        //使用pull解析器,解析这个流
                        parseNewsXml(is);
                    }
                } catch (Exception e) {

                    e.printStackTrace();
                }

            }
        };
        t.start();
    }

对news.xml文件进行pull解析

    private void parseNewsXml(InputStream is) {
        XmlPullParser xp = Xml.newPullParser();
        try {
            xp.setInput(is, "utf-8");
            //对结点的事件类型进行判断,就可以知道当前结点是什么节点
            int type = xp.getEventType();
            News news = null;

            while(type != XmlPullParser.END_DOCUMENT){
                switch(type){
                case XmlPullParser.START_TAG:
                    if("newslist".equals(xp.getName())){
                        newsList = new ArrayList<News>();
                    }
                    else if("news".equals(xp.getName())){
                        news = new News();
                    }
                    else if("title".equals(xp.getName())){
                        String title = xp.nextText();
                        news.setTitle(title);
                    }
                    else if("detail".equals(xp.getName())){
                        String detail = xp.nextText();
                        news.setDetail(detail);
                    }
                    else if("comment".equals(xp.getName())){
                        String comment = xp.nextText();
                        news.setComment(comment);
                    }
                    else if("image".equals(xp.getName())){
                        String image = xp.nextText();
                        news.setImageUrl(image);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if("news".equals(xp.getName())){
                        newsList.add(news);
                    }
                    break;
                }

                //解析完当前节点后,把指针移动到下一个节点,并返回它的事件类型
                type = xp.next();
            }

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

主线程中进行调用

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

        getNewsInfo();
//        ListView lv = (ListView) findViewById(R.id.lv);
//        //要保证在设置适配器时,新闻xml文件已经解析完毕,又来Handler
//        lv.setAdapter(new MyAdapter());
    }

    class MyAdapter extends BaseAdapter{

        //得到模型层元素的数量,用来确定listview需要有多少个条目
        @Override
        public int getCount() {

            return newsList.size();
        }

        @Override
        public Object getItem(int position) {

            return null;
        }

        @Override
        public long getItemId(int position) {

            return 0;
        }

        //需要返回一个View对象,作为Listview条目显示至界面
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            View v = View.inflate(MainActivity.this, R.layout.item_listview, null);
            return v;
        }

    }

因为pull解析是在子线程中完成,如果没有完成就执行ListViewAdapter就会报空指针异常,因此要在子线程pull解析完后用Handler

            //发消息,让主线程设置ListView的适配器,消息队列中不带任何数据
            //如果消息不需要携带数据,可以发送空消息
            handler.sendEmptyMessage(1);

Handler中重写HandleMessage方法

    Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            ListView lv = (ListView) findViewById(R.id.lv);
            //要保证在设置适配器时,新闻xml文件已经解析完毕,又来Handler
            lv.setAdapter(new MyAdapter()); 
        }
    };

将各条目里的数据分别写入各条目中

        //需要返回一个View对象,作为Listview条目显示至界面
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            News news = newsList.get(position);

            View v = View.inflate(MainActivity.this, R.layout.item_listview, null);

            //给三个文本框设置内容
            TextView tv_title = (TextView) v.findViewById(R.id.tv_title);
            tv_title.setText(news.getTitle());

            TextView tv_detail = (TextView) v.findViewById(R.id.tv_detail);
            tv_detail.setText(news.getDetail());

            TextView tv_comment = (TextView) v.findViewById(R.id.tv_comment);
            tv_comment.setText(news.getComment() + "条评论");

            //给新闻图片imageview设置内容
            //使用开源项目smartImageView
            SmartImageView siv = (SmartImageView) v.findViewById(R.id.iv);
            siv.setImageUrl(news.getImageUrl());
            return v;
        }

代码优化:

1,ListView缓存条目

            News news = newsList.get(position);

            View v = null;
            if(convertView == null){
                //无缓存
                v = View.inflate(MainActivity.this, R.layout.item_listview, null);
            }
            else{
                //有缓存
                v = convertView;
            }

进一步优化
findViewById经常执行也是浪费时间的,因此可创建内部类,然后缓存,省去findViewById的时间

        //创建内部类,省去findViewById的时间
        class ViewHolder{
            //条目的布局文件中有什么组件,这里就定义什么属性
            TextView tv_title;
            TextView tv_detail;
            TextView tv_comment;
            SmartImageView siv;
        }
            News news = newsList.get(position);

            View v = null;
            ViewHolder mHolder;
            if(convertView == null){
                //无缓存
                v = View.inflate(MainActivity.this, R.layout.item_listview, null);
                //把布局文件中所有组件都封装到mHolder对象中
                mHolder = new ViewHolder();
                mHolder.tv_title = (TextView) v.findViewById(R.id.tv_title);
                mHolder.tv_detail = (TextView) v.findViewById(R.id.tv_detail);
                mHolder.tv_comment = (TextView) v.findViewById(R.id.tv_comment);
                mHolder.siv = (SmartImageView) v.findViewById(R.id.iv);

                //再把mHolder封装到view对象中
                //意义:
                v.setTag(mHolder);
            }
            else{
                //有缓存
                v = convertView;
                //重新拿到mHolder
                mHolder = (ViewHolder) v.getTag();
            }

            //给三个文本框设置内容
            mHolder.tv_title.setText(news.getTitle());

            mHolder.tv_detail.setText(news.getDetail());

            mHolder.tv_comment.setText(news.getComment() + "条评论");

            //给新闻图片imageview设置内容
            //使用开源项目smartImageView
            mHolder.siv.setImageUrl(news.getImageUrl());
            return v;
        }

全部代码:

public class MainActivity extends Activity {

    List<News> newsList;

    Handler handler = new Handler(){
        public void handleMessage(android.os.Message msg) {
            ListView lv = (ListView) findViewById(R.id.lv);
            //要保证在设置适配器时,新闻xml文件已经解析完毕,又来Handler
            lv.setAdapter(new MyAdapter()); 
        }
    };

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

        getNewsInfo();
//        ListView lv = (ListView) findViewById(R.id.lv);
//        //要保证在设置适配器时,新闻xml文件已经解析完毕,又来Handler
//        lv.setAdapter(new MyAdapter());
    }

    class MyAdapter extends BaseAdapter{

        //得到模型层元素的数量,用来确定listview需要有多少个条目
        @Override
        public int getCount() {

            return newsList.size();
        }

        @Override
        public Object getItem(int position) {

            return null;
        }

        @Override
        public long getItemId(int position) {

            return 0;
        }

        //需要返回一个View对象,作为Listview条目显示至界面
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {

            News news = newsList.get(position);

            View v = null;
            ViewHolder mHolder;
            if(convertView == null){
                //无缓存
                v = View.inflate(MainActivity.this, R.layout.item_listview, null);
                //把布局文件中所有组件都封装到mHolder对象中
                mHolder = new ViewHolder();
                mHolder.tv_title = (TextView) v.findViewById(R.id.tv_title);
                mHolder.tv_detail = (TextView) v.findViewById(R.id.tv_detail);
                mHolder.tv_comment = (TextView) v.findViewById(R.id.tv_comment);
                mHolder.siv = (SmartImageView) v.findViewById(R.id.iv);

                //再把mHolder封装到view对象中
                //意义:
                v.setTag(mHolder);
            }
            else{
                //有缓存
                v = convertView;
                //重新拿到mHolder
                mHolder = (ViewHolder) v.getTag();
            }

            //给三个文本框设置内容
            mHolder.tv_title.setText(news.getTitle());

            mHolder.tv_detail.setText(news.getDetail());

            mHolder.tv_comment.setText(news.getComment() + "条评论");

            //给新闻图片imageview设置内容
            //使用开源项目smartImageView
            mHolder.siv.setImageUrl(news.getImageUrl());
            return v;
        }

        //创建内部类,省去findViewById的时间
        class ViewHolder{
            //条目的布局文件中有什么组件,这里就定义什么属性
            TextView tv_title;
            TextView tv_detail;
            TextView tv_comment;
            SmartImageView siv;
        }

    }

    //获取新闻信息
    private void getNewsInfo() {
        //开一个子线程去下载新闻信息
        Thread t = new Thread(){
            @Override
            public void run() {
                //先确定新闻的网址
                String path = "http://10.66.98.197/news.xml";
                try {
                    URL url = new URL(path);
                    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                    conn.setRequestMethod("GET");
                    conn.setReadTimeout(5000);
                    conn.setReadTimeout(5000);
                    //发送http GET请求获取响应码
                    if(conn.getResponseCode() == 200){
                        InputStream is = conn.getInputStream();
                        //使用pull解析器,解析这个流
                        parseNewsXml(is);
                    }
                } catch (Exception e) {

                    e.printStackTrace();
                }

            }
        };
        t.start();
    }

    private void parseNewsXml(InputStream is) {
        XmlPullParser xp = Xml.newPullParser();
        try {
            xp.setInput(is, "utf-8");
            //对结点的事件类型进行判断,就可以知道当前结点是什么节点
            int type = xp.getEventType();
            News news = null;

            while(type != XmlPullParser.END_DOCUMENT){
                switch(type){
                case XmlPullParser.START_TAG:
                    if("newslist".equals(xp.getName())){
                        newsList = new ArrayList<News>();
                    }
                    else if("news".equals(xp.getName())){
                        news = new News();
                    }
                    else if("title".equals(xp.getName())){
                        String title = xp.nextText();
                        news.setTitle(title);
                    }
                    else if("detail".equals(xp.getName())){
                        String detail = xp.nextText();
                        news.setDetail(detail);
                    }
                    else if("comment".equals(xp.getName())){
                        String comment = xp.nextText();
                        news.setComment(comment);
                    }
                    else if("image".equals(xp.getName())){
                        String image = xp.nextText();
                        news.setImageUrl(image);
                    }
                    break;
                case XmlPullParser.END_TAG:
                    if("news".equals(xp.getName())){
                        newsList.add(news);
                    }
                    break;
                }

                //解析完当前节点后,把指针移动到下一个节点,并返回它的事件类型
                type = xp.next();
            }

            //发消息,让主线程设置ListView的适配器,消息队列中不带任何数据
            //如果消息不需要携带数据,可以发送空消息
            handler.sendEmptyMessage(1);

        } catch (Exception e) {

            e.printStackTrace();
        }
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Android新闻客户端是一种运行在Android平台上的应用程序,旨在为用户提供便捷、实时的新闻信息。通过Android新闻客户端,用户可以轻松地浏览、阅读各种新闻类别和各种来源的新闻内容,了解最新的时事动态和全球新闻Android新闻客户端具有以下几个主要功能: 1. 新闻浏览:Android新闻客户端为用户提供了一个方便的平台,使用户可以浏览各种新闻类别,如国内新闻、国际新闻、财经新闻等。用户可以根据自己的兴趣选择浏览特定类别的新闻,从而获得所需的信息。 2. 定制化推荐:Android新闻客户端通常会根据用户的浏览历史和兴趣爱好为其推荐相关的新闻内容。这样,用户可以更加容易地找到自己感兴趣的新闻,节约浏览时间。 3. 多媒体内容:Android新闻客户端不仅提供新闻的文字内容,还可以包含图片、视频和音频等多媒体形式的内容。这样,用户可以更加生动地了解新闻内容,融入更多元化的视听体验。 4. 分享和评论:Android新闻客户端通常允许用户在社交媒体上分享自己感兴趣的新闻内容,与朋友、家人等人交流和讨论。同时,用户还可以在新闻客户端上发表自己的评论和观点,与其他用户进行互动。 5. 离线浏览:有些Android新闻客户端支持离线浏览功能,用户可以在有网络连接时将感兴趣的新闻保存到手机上,以便在没有网络连接的情况下继续阅读。 总之,Android新闻客户端为用户提供了方便、实时、多媒体的新闻阅读体验。用户可以根据自己的兴趣和需求,方便地获取各种新闻内容,以及与他人交流和互动。 ### 回答2: Android新闻客户端是一种运行在Android操作系统上的应用程序,旨在为用户提供快速、方便的新闻浏览体验。 首先,Android新闻客户端可以通过与各种新闻源的接口进行连接,从不同的媒体网站、新闻社交平台、博客等抓取最新的新闻内容。这意味着用户可以在一个应用程序中获取来自多个来源的多种类型的新闻,轻松地获取各种新闻。 其次,Android新闻客户端通常具备个性化推荐功能。根据用户的浏览历史、阅读喜好和实时趋势,客户端可以智能地为用户推荐相关的新闻内容,提供更贴合用户兴趣的新闻浏览体验。 此外,Android新闻客户端还具备多样的展示形式和交互方式。用户可以根据自己的习惯选择不同的新闻列表展示方式,如按时间、按类别、按热度等进行排序。同时,客户端还可以提供搜索和过滤功能,帮助用户快速找到感兴趣的新闻。 此外,Android新闻客户端还可以提供多媒体支持,如图片、音频、视频等。用户可以通过客户端直接在应用内观看视频新闻或浏览图片报道,丰富和提升了用户的新闻阅读体验。 最后,Android新闻客户端通常还提供一些社交分享功能,用户可以将自己喜欢的新闻内容通过应用内的分享功能分享到社交媒体平台上,与朋友们一起讨论和互动。 综上所述,Android新闻客户端是一种便捷、多样化、个性化的应用程序,能够提供用户快速获取、浏览和分享新闻信息的功能,为用户带来更好的新闻阅读体验。 ### 回答3: Android新闻客户端是一款运行在安卓系统上的应用程序,主要用于实时获取和展示各类新闻信息。这种客户端通过与不同的新闻网站或新闻服务提供商进行数据交互,可以根据用户的兴趣和偏好,为用户推送最新、最相关的新闻内容。 Android新闻客户端通常拥有用户友好的界面设计,方便用户直观地浏览和阅读新闻信息。用户可以根据自己的喜好选择新闻的分类、频道或关键字进行订阅,也可以随时搜索自己感兴趣的新闻内容。此外,该客户端还会根据用户的历史浏览记录和喜好推送相似内容的新闻,以提供更加个性化的阅读体验。 Android新闻客户端具备多种功能与特点。首先,它可以支持多种媒体形式,如文字、图片、视频等,使用户得以全面多样地了解新闻事物。其次,它可以实现与其他应用程序的整合,比如分享新闻至社交媒体平台,或者将新闻保存至云端进行后续阅读。此外,该客户端还可以提供天气预报、股票行情、体育赛事等实用信息,以便用户一站式获取各种资讯。 综上所述,Android新闻客户端是一种功能强大、使用方便的应用程序,它通过与新闻提供方进行数据交互,为用户提供最新、最相关的新闻内容,并具备个性化推送、多媒体形式和与其他应用的整合等特点。无论是随时了解当前时事,还是关注自己感兴趣的领域,Android新闻客户端都是用户获取信息的好帮手。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值