Android学习笔记(十)——实现新闻列表

【第一部分】历史文章:
Android学习笔记(一)——创建第一个Android项目
Android学习笔记(二)android studio基本控件及布局(实现图片查看器)
Android学习笔记(三)android studio中CheckBox自定义样式(更换复选框左侧的勾选图像)
Android学习笔记(四)Android 中Activity页面的跳转及传值
Android学习笔记(五)——Toast提示、Dialog对话框、Menu菜单
Android学习笔记(六)——自定义ListView布局+AsyncTask异步任务
Android学习笔记(七)——数据存储(共享参数SharedPreferences)
Android学习笔记(八)——数据存储(SD卡文件操作)
Android学习笔记(九)——网络技术
【第二部分】主要问题解决:
Android Studio(存)读取不了SD卡上的文件——【已解决】

在上一篇的网络技术的文章中,主要介绍了数据的获取,没有对数据进行解析。那么这篇文章,用一个综合的案例,介绍数据的解析及以前知识的应用。

首先我们拿到头条新闻的API接口地址:http://v.juhe.cn/toutiao/index?type=top&key=a1a755458cc22f129942b34904feb820
在这里插入图片描述
下面就来开始我们的案例:

1、在activity_main.xml中添加ListView控件和自定义列表布局。

这里我们下只需要显示每一个列表项中的内容有:新闻图片、新闻标题、新闻的来源、时间等内容。

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"
    tools:context="cn.edu.hznu.ex10_news.MainActivity">
    <ListView
        android:id="@+id/listview"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

new_item_layout.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="wrap_content"
    android:orientation="vertical">
    <ImageView
        android:id="@+id/imgsrc"
        android:layout_width="100dp"
        android:layout_height="75dp"
        android:layout_centerVertical="true"
        android:padding="3dp"
        android:src="@mipmap/ic_launcher" />
    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_toRightOf="@id/imgsrc"
        android:paddingTop="4dp"
        android:text="显示新闻的标题"
        android:textColor="@android:color/darker_gray"
        android:textSize="20sp" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/title"
        android:layout_toRightOf="@id/imgsrc"
        android:orientation="horizontal"
        android:layout_alignParentBottom="true"
        android:paddingBottom="2dp"
        android:paddingTop="4dp">
        <TextView
            android:id="@+id/author_name"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:layout_weight="1"
            android:text="新闻的来源"
            android:textColor="@android:color/darker_gray"
            android:textSize="15sp" />
        <TextView
            android:id="@+id/date"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginRight="8dp"
            android:text="2019.5.13 16:35"
            android:textColor="@android:color/darker_gray"
            android:textSize="15sp" />
    </LinearLayout>
</RelativeLayout>

2、创建JAVABean,保存新闻数据。

news.java

package cn.edu.hznu.ex10_news.bean;
public class News {
    private String title;  //标题
    private String date;   //时间
    private String author_name;   //来源——作者名字
    private String thumbnail_pic_s;   //头像
    private String url;     //具体的内容
    public String getTitle() {
        return title;
    }

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

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getAuthor_name() {
        return author_name;
    }

    public void setAuthor_name(String author_name) {
        this.author_name = author_name;
    }

    public String getThumbnail_pic_s() {
        return thumbnail_pic_s;
    }

    public void setThumbnail_pic_s(String thumbnail_pic_s) {
        this.thumbnail_pic_s = thumbnail_pic_s;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

3、在创建访问网络异步类前,首先自己定义一个解析网络返回的JSON数据的类。

JSONUtils.java

package cn.edu.hznu.ex10_news.utils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import cn.edu.hznu.ex10_news.bean.News;
public class JSONUtils {
    public static ArrayList<News> parseJson(String jsonData) {
        ArrayList<News> result = new ArrayList<>();
        JSONObject jo = null;
        News news;
        try {
            jo = new JSONObject(jsonData);
            if (jo.getString("reason").equals("成功的返回")) {
                JSONObject jo1 = jo.getJSONObject("result");
                JSONArray ja = jo1.getJSONArray("data");
                for (int i = 0; i < ja.length(); i++) {
                    news = new News();
                    JSONObject obj = ja.getJSONObject(i);
                    news.setTitle(obj.getString("title"));
                    news.setDate(obj.getString("date"));
                    news.setAuthor_name(obj.getString("author_name"));
                    news.setThumbnail_pic_s(obj.getString("thumbnail_pic_s"));
                    news.setUrl(obj.getString("url"));
                    result.add(news);
                }
            }
            return  result;
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return null;
    }
}

4、创建访问网络异步类。

NewsTask.java

package cn.edu.hznu.ex10_news.task;
import android.os.AsyncTask;
import java.io.IOException;
import java.util.ArrayList;
import cn.edu.hznu.ex10_news.bean.News;
import cn.edu.hznu.ex10_news.utils.JSONUtils;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class NewsTask  extends AsyncTask<String,Void,ArrayList<News>> {
    private NewsCallBack  newsCallBack;
    public NewsTask(NewsCallBack newsCallBack) {
        this.newsCallBack = newsCallBack;
    }
    @Override
    protected ArrayList<News> doInBackground(String... strings) {
        //************************访问网络获取数据,得到列表项的数据*****************
        ArrayList<News> result=null;  //创建arraylist ,接收数据

        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder().url(strings[0]).build();
        try {
            Response response=client.newCall(request).execute();
            String jsonData=response.body().string();
            result=  JSONUtils.parseJson(jsonData);   //调用,返回Arraylist

        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    @Override
    protected void onPostExecute(ArrayList<News> result) {
        //在主线程中执行
        if(newsCallBack!=null)
            newsCallBack.getResults(result);
        super.onPostExecute(result);
    }


    @Override
    protected void onPreExecute() {
        //在主线程执行
        super.onPreExecute();
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        //做进度显示的操作
        super.onProgressUpdate(values);
    }
    //定义接口
    public interface NewsCallBack{
        void getResults(ArrayList<News> result);
    }
}

5、创建访问网络异步类,来获取具体的图片数据。

ImageTask.java

package cn.edu.hznu.ex10_news.task;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import java.io.IOException;
import cn.edu.hznu.ex10_news.utils.Thumbnail;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class ImageTask extends AsyncTask<String,Void,Bitmap> {
    private CallBack back;
    public ImageTask(CallBack back) {
        this.back = back;
    }
    @Override
    protected Bitmap doInBackground(String... strings) {
        Bitmap result=null;
        OkHttpClient client=new OkHttpClient();
        Request request=new Request.Builder().url(strings[0]).build();
        try {
            Response response=client.newCall(request).execute();
            byte[]imageData= response.body().bytes() ;
            result= Thumbnail.getThumbnail(imageData,400,500);  //调用工具类

        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        if(back!=null){
            back.getResults(bitmap);
        }
    }
    public interface  CallBack{
        void getResults(Bitmap result);
    }
}

6、创建工具类,用于转化图片。

Thumbnail.java

package cn.edu.hznu.ex10_news.utils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.ThumbnailUtils;
public class Thumbnail {
    public static Bitmap getThumbnail(byte[] imageData,int width,int height){
        Bitmap img_bitmap = null;
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.ARGB_4444;/*设置让解码器以最佳方式解码*/
        options.inJustDecodeBounds = true;
        img_bitmap = BitmapFactory.decodeByteArray(imageData,0,imageData.length, options);
        options.inJustDecodeBounds = false;//设为 false
        //计算缩放比
        int h = options.outHeight;
        int w = options.outWidth;
        int beWidth = w / width;
        int beHeight = h / height;
        int be = 1;
        if (beWidth < beHeight) {
            be = beWidth;
        } else {
            be = beHeight;
        }
        if (be <= 0) {
            be = 1;
        }
        options.inSampleSize = be;
        img_bitmap = BitmapFactory.decodeByteArray(imageData,0,imageData.length, options);
        img_bitmap = ThumbnailUtils.extractThumbnail(img_bitmap, width, height,
                ThumbnailUtils.OPTIONS_RECYCLE_INPUT);
        return img_bitmap;
    }
}

7、自定义数据适配器。

NewsAdapter .java

package cn.edu.hznu.ex10_news.adapter;
import android.content.Context;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import cn.edu.hznu.ex10_news.R;
import cn.edu.hznu.ex10_news.bean.News;
import cn.edu.hznu.ex10_news.task.ImageTask;
public class NewsAdapter extends ArrayAdapter<News> {
    private int item_layout_id;
    public NewsAdapter(Context context, int resource, List objects) {
        super(context, resource,objects);
        item_layout_id=resource;
    }
    @NonNull
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view=null;
        final  ViewHolder holder;
        if(convertView==null){//回收站为空\
            /**
             * LayoutInflater.from()得到布局填充器对象
             * getContext()获取当前上下文
             * inflate() 加载填充布局
             */
            view= LayoutInflater.from(getContext())
                    .inflate(item_layout_id,parent,false);
            holder=new ViewHolder(view);
            view.setTag(holder);

        }else {//显示后续的列表项
            view=convertView;
            holder= (ViewHolder) view.getTag();
        }
        News itemData=getItem(position);
        holder.title.setText(itemData.getTitle());
        holder.date.setText(itemData.getDate());
        holder.author_name.setText(itemData.getAuthor_name());
        if(!TextUtils.isEmpty(itemData.getThumbnail_pic_s())){
            new ImageTask(new ImageTask.CallBack() {
                @Override
                public void getResults(Bitmap result) {
                    holder.thumbnail_pic_s.setImageBitmap(result);


                }
            }).execute(itemData.getThumbnail_pic_s()) ;  //执行异步任务
        }else{
            holder.thumbnail_pic_s.setVisibility(View.GONE);
        }
        return view;
    }
    class  ViewHolder{
        TextView title;
        TextView date;
        TextView author_name;
        ImageView thumbnail_pic_s;

        public ViewHolder(View view) {
            title=(TextView) view.findViewById(R.id.title);
            date=(TextView)view.findViewById(R.id.date);
            author_name=(TextView)view.findViewById(R.id.author_name);
            thumbnail_pic_s=(ImageView)view.findViewById(R.id.imgsrc);
        }
    }
}

8、编写底部布局文件。

异步任务结合进度显示,,可以很好的给予用户焦急等待的体验。

footer_layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">
    <ProgressBar
        style="?android:attr/progressBarStyleSmall"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/progressBar"
        android:layout_weight="1" />

    <TextView
        android:text="正在加载数据........"
        android:textSize="24sp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/textView"
        android:layout_weight="1" />
</LinearLayout>

具体的效果是这样的:
在这里插入图片描述

9、MainActivity.java

package cn.edu.hznu.ex10_news;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import cn.edu.hznu.ex10_news.adapter.NewsAdapter;
import cn.edu.hznu.ex10_news.bean.News;
import cn.edu.hznu.ex10_news.task.NewsTask;
public class MainActivity extends AppCompatActivity  {
    private ListView listView;  //定义listview
    private ArrayList<News> data=new ArrayList<>();
    private NewsAdapter adapter;
    private boolean isLoading=true,isDown=false;
    //**************************************
    private static String URL = "http://v.juhe.cn/toutiao/index?type=top&key=6928eda123d4aef596b726b4addadf48";
    private String citySubing;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView= (ListView) findViewById(R.id.listview);  //绑定
        //**********************添加带有底部视图**************************************
        View view= LayoutInflater.from(this).inflate(R.layout.footer_layout,null);
        listView.addFooterView(view);

        loadData(URL);   //将列表项的数据加载到数据源(顺序表)中
        adapter=new NewsAdapter(MainActivity.this, R.layout.new_item_layout,data);
        listView.setAdapter(adapter);
        
        //添加列表的滚动事件
        listView.setOnScrollListener(new AbsListView.OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView absListView, int scrollState) {
                if(isDown==true&&scrollState==SCROLL_STATE_IDLE){
                    loadData(URL);
                }
            }

            @Override
            public void onScroll(AbsListView absListView, int i, int i1, int i2) {
                if(i+i1==i2){
                    isDown=true;
                }else{
                    isDown=false;
                }
            }
        });
    }
     private void loadData(String URL) {
        if(isLoading){
            isLoading=false;
            new NewsTask(new NewsTask.NewsCallBack() {
                @Override
                public void getResults(ArrayList<News> result) {//重写接接口方法
                    data.clear();
                    data.addAll(result);
                    adapter.notifyDataSetChanged();
                }
            }).execute(URL);
            isLoading=true;
        }
    }

10、运行效果。

在这里插入图片描述

注意点:

(1)由于我们使用的是Okhttp访问网络,在使用之前,我们需要在项目中添加Okhttp库的依赖。在app/build.gradle文件中,dependencies闭包中添加以下内容:

compile 'com.squareup.okhttp3:okhttp:3.4.1'

(2)在AndroidManifest.xml中添加网络访问权限:

    <uses-permission android:name="android.permission.INTERNET" />
  • 10
    点赞
  • 133
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 30
    评论
你好!感谢提问。下面是有关 K210 学习笔记五中串口通信的一些内容: 在 K210 开发板上,串口是一种常见的通信接口,用于将数据从一个设备传输到另一个设备。串口通信通常使用 UART (Universal Asynchronous Receiver/Transmitter) 协议。 要在 K210 上进行串口通信,首先需要使用两个引脚:一个用于接收数据(RX),一个用于发送数据(TX)。这些引脚可以通过 GPIO 端口与外部设备连接。 在 K210 的开发环境中,可以使用 MaixPy 或者 Kendryte Standalone SDK 进行串口编程。 在 MaixPy 中,可以使用 `uart` 模块来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```python from machine import UART uart = UART(UART.UART1, 115200) ``` 然后,可以使用 `uart.write()` 函数发送数据,使用 `uart.read()` 函数接收数据。例如: ```python uart.write("Hello, world!\n") data = uart.read(10) ``` 在 Kendryte Standalone SDK 中,可以使用 `uart.h` 头文件中的函数来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```c #include "uart.h" uart_init(UART_DEVICE_1, 115200); ``` 然后,可以使用 `uart_send_data()` 函数发送数据,使用 `uart_receive_data()` 函数接收数据。例如: ```c uart_send_data(UART_DEVICE_1, "Hello, world!\n", 14); char buffer[10]; uart_receive_data(UART_DEVICE_1, buffer, 10); ``` 以上是关于 K210 学习笔记五中串口通信的简要介绍。如果你有更具体的问题,请随时提问!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小Java开发者

“是一种鼓励,你懂的”

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值