在 Android GridView 中下载和显示图像

一则或许对你有用的小广告

欢迎加入小哈的星球 ,你将获得:专属的项目实战 / Java 学习路线 / 一对一提问 / 学习打卡/ 赠书活动

目前, 星球 内第2个项目《仿小红书(微服务架构)》正在更新中。第1个项目:全栈前后端分离博客项目已经完结,演示地址:http://116.62.199.48/。采用技术栈 Spring Boot + Mybatis Plus + Vue 3.x + Vite 4手把手,前端 + 后端全栈开发,从 0 到 1 讲解每个功能点开发步骤,1v1 答疑,陪伴式直到项目上线,目前已更新了 255 小节,累计 39w+ 字,讲解图:1716 张,还在持续爆肝中,后续还会上新更多项目,目标是将 Java 领域典型的项目都整上,如秒杀系统、在线商城、IM 即时通讯、权限管理等等,已有 1300+ 小伙伴加入,欢迎点击围观

这个例子是我之前的例子 Android GridView Example 的改进版本。我们不使用静态图像来显示网格项,而是通过从服务器实时下载数据并呈现网格项来使此示例更加逼真。以下视频描述了此示例的输出。


不用浪费太多时间,让我们直接跳到构建这种 GridView 需要什么。您需要按照以下步骤完成此示例。

1.在Activity布局中添加GridView

首先,创建一个新的安卓项目。对于这个例子,我更喜欢使用 Android Studio 。在您的项目 res/layout 文件夹中创建一个新的布局文件,并将其命名为 activity_grid_view.xml 。并添加以下代码块。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

上面的布局非常简单。我们在活动布局中声明了一个 GridView 和一个 ProgressBar 。下载数据时会显示进度条。

2.声明GridView项目布局

现在让我们将另一个名为 grid_item_layout.xml 的文件添加到 res/layout 文件夹。此布局将由自定义网格适配器用于布置单个网格项目。为了简单起见,我们添加了一个 ImageView 和一个 TextView


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

3.增加上网权限

您可能知道,Android 应用程序必须声明应用程序所需的所有权限。由于我们需要下载数据表单服务器,因此我们需要添加 INTERNET 权限。将以下行添加到 AndroidManifest.xml 文件。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

请注意,我们还声明了应用程序中使用的所有活动。

4、添加毕加索图片下载库

Android 开源开发者社区带来了一些可以轻松集成到 Android 应用程序中的有趣库。它们有很多用途并节省了大量时间。在这个例子中,我说的是 Picasso 图像加载库。我们将添加用于下载和缓存图像的 Picasso 库。访问此处以了解有关如何在 Android 中使用 Picasso 库的更多信息。

您可以通过将以下依赖项添加到 build.gradle 文件来添加 Picasso 库。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

5. 创建一个 GridView 自定义适配器

网格视图是适配器视图。它需要一个适配器来呈现数据项的集合。将名为 GridViewAdapter.java 的新类添加到您的项目并添加以下代码片段。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

请注意上面代码片段中的以下内容,

  • setGridData() 方法更新 GridView 上的数据显示。
  • Picasso.with().load() 方法用于从 url 下载图像并显示在图像视图上。
  • GridViewAdapter 类构造函数需要网格项布局的 ID 和要操作的数据列表。
  • 您可能会感到惊讶, GridItem 类是从哪里来的。这不是魔术,我们需要将 GridItem.java 类添加到我们的项目中。 GridItem 类如下所示。

6. 下载数据并将其挂接到 Activity

现在我们将着手将适配器挂接到 GridView 并使其正常运行。创建一个新的 Java 类并将其命名为 GridViewActivity.java 并执行以下步骤。

  • 重写 onCreate() 方法,调用 setContentView() 方法设置布局
  • 使用声明的布局 ID 初始化 GridView 和 ProgressBar 组件。
  • 通过传递网格行布局 ID 和 GridItem 对象列表来初始化 CustomGridView 适配器。
  • 使用 AsyncTask 从服务器下载数据,下载成功后读取流 JSON 响应。
  • 将 JSON 字符串解析为 GridItem 对象列表。下载和解析完成后,在 onPostExecute() 回调中更新 UI 元素。

以下代码执行上述所有步骤。将以下代码添加到 GridViewActivity 类。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

此时您将能够运行该应用程序并注意到该应用程序将从服务器下载数据并显示在 GridView 上。

7.处理GridView的点击事件

现在 GridView 不响应用户点击。让我们通过添加以下代码使其更具功能性。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

当用户点击一个网格项目时,我们将启动另一个显示全屏图像的活动。您可以通过调用 startActivity() 方法从一个活动开始另一个活动。

我们需要传递项目的详细信息,例如标题和图像 url,以便在 DetailsActivity 上显示它。

8.创建细节活动布局

添加一个新的布局文件到 res/layout 目录,命名为 activity_details_view.xml 并添加以下代码片段。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

9. 完成详情活动

DetailsActivity 检索从 GridViewActivity 传递的详细信息并在屏幕上呈现详细信息。创建一个名为 DetailsActivity 的新类并添加以下代码片段。


 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">
&lt;GridView
    android:id="@+id/gridView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="5dp"
    android:columnWidth="100dp"
    android:drawSelectorOnTop="true"
    android:gravity="center"
    android:numColumns="auto_fit"
    android:stretchMode="columnWidth"
    android:verticalSpacing="5dp"
    android:focusable="true"
    android:clickable="true"/&gt;

&lt;ProgressBar
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/progressBar"
    android:layout_centerInParent="true"
    android:visibility="gone"/&gt;

</RelativeLayout>

10. 下载完整范例

从 GitHub 下载。

11. GridView 中的自定义活动转换

继续阅读我们的 下一个教程。