跟代码相关的工作,大多唯手熟尔,所以这里花了点时间做了款简易版的新闻 APP,虽然都是些基础的内容,不过还是可以加深自己对部分代码的理解。至少,可以加深自己的记忆
步骤
- 依赖库
- 网络请求
- 网络解析
- 界面布局
- 最后
- 运行界面
- 运行GIF
- 完整代码下载地址(github)
依赖库
过程中需要用到一些开源依赖库文件,先在 build.grade 中声明:
compile 'com.google.code.gson:gson:2.8.0' //网络解析
compile 'com.squareup.okhttp3:okhttp:3.7.0' //网络请求
compile 'com.github.bumptech.glide:glide:3.8.0' //图片加载
compile 'com.android.support:design:24.2.1' //Material Design中用到的依赖库
compile 'de.hdodenhof:circleimageview:2.1.0' //显示圆形图片
网络请求
在包下创建一个文件夹 util 用来存放工具类,创建文件 HttpUtil.class 用来请求数据:
public class HttpUtil {
public static void sendOkHttpRequest(String address, okhttp3.Callback callback){
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(address).build();
client.newCall(request).enqueue(callback);
}
}
这里用到的是 okhttp3.Callback 的回调接口,结果会返回到 callback 的回调函数中,后面会进行处理
网络解析
我们先从数据解析开始,毕竟这才是这个小项目的重点。这次项目使用的数据来源是天行数据(http://www.tianapi.com/ )的新闻资讯 API ,先看 API 的说明:
可以看到返回数据为 JSON, 默认返回 10 条参数。请求地址为:
其中, APIKEY 需要用个人的 API KEY 代替,可以在个人中心中看到,其他的请求地址也是大同小异
JSON 返回示例:
还有错误返回码,用来判断返回数据的异常情况:
根据 gson 的返回示例,我们可以写出对应的实体类文件,通过 gson 将返回数据转化为对应的类型。先创建一个 gson 文件夹存放实体类文件。
在 gson 文件夹下创建 New.class 文件:
public class News {
@SerializedName("ctime")
public String time;
public String title;
public String description;
public String picUrl;
public String url;
}
创建 NewsList.class 文件:
public class NewsList {
public int code;
public String msg;
@SerializedName("newslist")
public List<News> newsList ;
}
至此,我们就已经创建好了与返回数据对应的实体类。
在 util 文件夹下创建文件 Utility.class 文件:
public class Utility {
public static NewsList parseJsonWithGson(final String requestText){
Gson gson = new Gson();
return gson.fromJson(requestText, NewsList.class);
}
}
将请求得到的数据解析为 NewList 实体类对象。现在网络请求和解析都准备好了,就开始界面文件了
界面布局
修改 values 目录下的 styles.xml 文件:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimary</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
修改通知栏颜色和标题栏颜色一样,是处于视觉统一的原因,也可以不修改(非必须)
主要采用的是 Material Design 的设计,整体布局采用的是滑动菜单,主界面内容为 ToolBar 和 ListView(这里为了方便,就直接使用),侧边栏内容为 NavigationView
主界面:
因为要用 ToolBar 替代 ActionBar, 我们先修改 values 下面的 styles 文件,修改主题为:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
在layout 下创建 nav_header 文件
<?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="180dp"
android:background="@color/colorPrimary"
android:padding="10dp">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon_image"
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_centerInParent="true"
android:src="@drawable/nav_icon" />
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="https://github.com/lentitude"
android:textColor="@color/color_White"
android:textSize="14sp" />
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/username"
android:text="lentitude"
android:textColor="@color/color_White"
android:textSize="14sp" />
</RelativeLayout>
这里在头部文件中放置了一个CircleImageView,两个 TextView,没有什么理解难度
在 res 目录下创建 menu 文件夹,新建 nav_menu.xml 文件:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_society"
android:title="社会新闻" />
<item
android:id="@+id/nav_county"
android:title="国内新闻" />
<item
android:id="@+id/nav_internation"
android:title="国际新闻" />
<item
android:id="@+id/nav_fun"
android:title="娱乐新闻" />
<item
android:id="@+id/nav_sport"
android:title="体育新闻" />
<item
android:id="@+id/nav_nba"
android:title="NBA新闻" />
<item
android:id="@+id/nav_football"
android:title="足球新闻" />
<item
android:id="@+id/nav_technology"
android:title="科技新闻" />
<item
android:id="@+id/nav_work"
android:title=