在上一节中,已经搭建好了导航栏,现在开始完成首页内容的设计。

任务描述:实现从网络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. 搜索菜谱,出现如图所示:

android header布局 android首页布局_android

android header布局 android首页布局_数据_02

 

 

 可以看到,对于普通会员每天有20次的免费调用,注册即可成为普通会员。

2.现在点进菜谱大全,可以看到如下接口信息:

android header布局 android首页布局_数据_03

 

 这里的showapi_appid=&showapi_sign=都需要替换成自己的值,那这个值从哪里来呢?

3.注册好账号后,前往“控制台”创建新的应用,以此获取到相应的appid和appkey。

如下图:

android header布局 android首页布局_android header布局_04

 

 

 现在我们就算是做好了准备工作,打开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'

布局效果如下:

android header布局 android首页布局_数据_05

 

 首先:主页面是用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>

效果图:

android header布局 android首页布局_android header布局_06

 

有关图片的圆角设置,可参考我前面的备忘录小项目

recy_view_tags),这里需要点击前后的变化,如下图,点击前为白色,点击后为蓝色:

android header布局 android首页布局_android_07

 

在drawable新建点击前后的资源文件,如下图:

android header布局 android首页布局_xml_08

 

 my_round_recentgle1.xml为点击前,内容如下:

android header布局 android首页布局_android_09

 

我们在这里设置了颜色为白色,就没做任何设置了。如果有兴趣,还可以设置圆角,边框等等。

my_round_recentgle1.xml为点击后,内容如下:

android header布局 android首页布局_xml_10

 

 

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","网络错误");
                }
            });
        }
    });
}

调用后结果如下:

android header布局 android首页布局_数据_11

 

 显示到屏幕上是这样的:(可以看看官网上返回的数据格式:https://www.showapi.com/apiGateway/view/1164)

android header布局 android首页布局_数据_12

 

 已经成功请求到了数据,但是这些数据都不能直接使用,我们需要到这些数据进行解析。

再看看官网的信息:

android header布局 android首页布局_android_13

 

 返回的为JSON格式的数据,我们怎么解析JSON格式的数据呢?

之前有写过一篇百度AI人脸特征点检测的JSON数据解析(使用FastJSON解析),感兴趣的可以移步

总而言之,解析JSON数据有很多种方法,本次使用GSON解析库来解析。

具体解析步骤请移步

解析数据后,我们需要做的就是将数据展示出来。

前面说过,本次采用RecyclerView布局方式,图片显示使用Glide库。

具体的逻辑代码(如适配器,动态加载数据等)写在下一节。