在上一节中,已经搭建好了导航栏,现在开始完成首页内容的设计。
任务描述:实现从网络HTTP接口获取菜谱数据,并完成菜谱App主页面的布局设计。
设计思路:
1.数据层面,使用showapi的菜谱接口。
2.HTTP请求层面,使用OkHttp开源库。
3.数据解析层面,使用GSON解析库。
4.数据展示层面:使用RecyclerView。
5.图片展示,使用Glide库。
大致流程便是:
使用OkHttp从showapi拿到菜谱的数据,但这些数据是JSON格式的,我们需要使用数据的话,需要进行数据解析。
数据解析的方式有很多种:JSONObject(官方提供),GSON(谷歌开源库),还有一些第三方如:Jackson,FastJSON等等。
本次使用GSON进行解析,另外之前有写过一篇使用FastJSON进行数据解析的,指路
然后通过RecyclerView的布局方式将数据展示出来,图片的展示使用Glide库。
①前往“万维易源”网站获取到菜谱数据的接口。
网址:https://www.showapi.com/
1. 搜索菜谱,出现如图所示:
可以看到,对于普通会员每天有20次的免费调用,注册即可成为普通会员。
2.现在点进菜谱大全,可以看到如下接口信息:
这里的showapi_appid=&showapi_sign=都需要替换成自己的值,那这个值从哪里来呢?
3.注册好账号后,前往“控制台”创建新的应用,以此获取到相应的appid和appkey。
如下图:
现在我们就算是做好了准备工作,打开AS,开始敲代码了。
②导入依赖和页面布局设计
我们需要用到的依赖都添加进来:
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.squareup.okhttp3:okhttp:4.4.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.google.code.gson:gson:2.8.6'
布局效果如下:
首先:主页面是用RecyclerView的方式展示数据,上面还有菜谱类型的布局设计。
1.主界面布局:在fragment_homepage.xml中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical"
tools:context=".HomepageFragment">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_view_tags"
android:layout_width="match_parent"
android:layout_height="50dp"/>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recy_homepage"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
如上所示:第一个recyclerview是显示类型标签的,第二个是内容。
2.有关上述第二个RecyclerView(recy_homepage)的子界面布局如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/item_layout"
android:orientation="vertical"
android:layout_marginLeft="10dp"
android:layout_marginTop="10dp"
android:layout_marginRight="10dp"
android:layout_width="200dp"
android:layout_height="280dp">
<com.google.android.material.imageview.ShapeableImageView
android:layout_weight="1"
android:id="@+id/item_image"
android:src="@drawable/xixi_01"
android:background="@drawable/corners_shade"
android:layout_width="180dp"
android:layout_height="200dp"
android:scaleType="centerCrop"
app:shapeAppearanceOverlay="@style/eggStyle"/>
<TextView
android:layout_marginTop="10dp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:id="@+id/item_title"
android:textSize="16sp"
android:textStyle="bold"
android:ellipsize="end"
android:maxLines="1"
android:textColor="@color/black"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<TextView
android:layout_marginTop="5dp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:id="@+id/item_user"
android:textColor="#CCCCCC"
android:textSize="12sp"
android:ellipsize="end"
android:maxLines="1"
android:layout_width="wrap_content"
android:layout_height="30sp"/>
</LinearLayout>
效果图:
有关图片的圆角设置,可参考我前面的备忘录小项目
recy_view_tags),这里需要点击前后的变化,如下图,点击前为白色,点击后为蓝色:
在drawable新建点击前后的资源文件,如下图:
my_round_recentgle1.xml为点击前,内容如下:
我们在这里设置了颜色为白色,就没做任何设置了。如果有兴趣,还可以设置圆角,边框等等。
my_round_recentgle1.xml为点击后,内容如下:
recy_view_tags的子界面layouttagtext.xml。
内容如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent">
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:background="@drawable/my_round_recentgle1"
android:layout_margin="10dp"/>
</LinearLayout>
可以看到,只有一个TextView,文字初始背景为my_round_recentgle1
做完以上工作,主页面的界面布局才算完成,接下来我们需要往这些页面中填充数据,在填充数据之前,我们需要先拿到数据。
③逻辑代码设计
1.通过okhttp异步GET请求数据:
首先创建一个网络工具类NetUtil,用于处理网络HTTP请求,同时在NetUtil类中新建接口类OnRecipeQueriedCallback,该类用于菜谱查询结果(成功或是失败,如果成功则将拿到的数据传回去)的回调。
package com.kotlin.activitystudy.http;
import android.util.Log;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class NetUtil {
public interface OnRecipeQueriedCallback{
void onSuccess(String recipes);
void onFailure(Exception e);
}
public static void queryRecipe(String tag,final OnRecipeQueriedCallback callback){
OkHttpClient okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(String.format("http://route.showapi.com/1164-1?showapi_appid=&type=填自己的%s&showapi_sign=填自己的",tag))//该tag为类型
.build();
Call call = okHttpClient.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
callback.onFailure(e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
try {
String jsonStr = response.body().string();
callback.onSuccess(jsonStr);
}catch (Exception e){
callback.onFailure(e);
}
}
});
}
}
有关上述代码为什么这样写,
然后在HomepageFragment中创建initData()方法,用于数据的查询和展示,并重写onActivityCreated方法在其中调用initData。
private void initData() {
NetUtil.queryRecipe("蛋类", new NetUtil.OnRecipeQueriedCallback() {
@Override
public void onSuccess(String recipes) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("OKHttpActivity2",""+recipes);
responseText.setText(recipes);
}
});
}
@Override
public void onFailure(Exception e) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.d("OKHttpActivity2","网络错误");
}
});
}
});
}
调用后结果如下:
显示到屏幕上是这样的:(可以看看官网上返回的数据格式:https://www.showapi.com/apiGateway/view/1164)
已经成功请求到了数据,但是这些数据都不能直接使用,我们需要到这些数据进行解析。
再看看官网的信息:
返回的为JSON格式的数据,我们怎么解析JSON格式的数据呢?
之前有写过一篇百度AI人脸特征点检测的JSON数据解析(使用FastJSON解析),感兴趣的可以移步
总而言之,解析JSON数据有很多种方法,本次使用GSON解析库来解析。
具体解析步骤请移步
解析数据后,我们需要做的就是将数据展示出来。
前面说过,本次采用RecyclerView布局方式,图片显示使用Glide库。
具体的逻辑代码(如适配器,动态加载数据等)写在下一节。