Android 控件GridView使用案例讲解

Android 控件GridView使用案例讲解

简介

GridView 是 Android 中常用的控件,用于显示多个相同类型的数据项。它类似于网格布局,将数据按行列方式排列,每个数据项都展示在一个格子里,用户可以通过滑动、缩放、选择来操作它们。在本篇文章中,我们将会讲解 GridView 的使用,包括创建、配置、自定义和优化等。

创建

在 Android Studio 中,我们可以使用 XML 布局文件创建 GridView,代码如下:

<GridView
    android:id="@+id/grid_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:verticalSpacing="10dp"
    android:horizontalSpacing="10dp"
    android:numColumns="3"
    android:gravity="center"
    android:stretchMode="columnWidth"/>

在上面的布局代码中,我们定义了一个 GridView,它有 id 为 grid_view,宽高都为 match_parent,每行展示三个数据项,每个数据项之间有 10dp 的垂直和水平间距,数据项的宽度会自动缩放以占据一整列的空间,如果一行上的数据项不足三个,它们会在水平方向居中显示。

然后,在代码中我们需要找到这个 GridView,并向它添加数据项:

GridView gridView = findViewById(R.id.grid_view);
gridView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, new String[]{"Item 1", "Item 2", "Item 3", "Item 4", ...}));

在这里,我们使用了 ArrayAdapter,将一个字符串数组中的每个元素都封装成了一个 TextView,然后把这些 TextView 作为数据项添加到了 GridView 中。

配置

为了让 GridView 更好的呈现我们的数据,我们可以通过设置相应的属性来决定它的显示方式。下面是一些常用的属性和作用:

  • android:numColumns:设置 GridView 每行展示的数据项个数。
  • android:verticalSpacing:设置每个数据项之间的垂直间距。
  • android:horizontalSpacing:设置每个数据项之间的水平间距。
  • android:gravity:设置数据项在整个 GridView 中的对齐方式。
  • android:stretchMode:设置数据项的宽度缩放模式,可以设置为 columnWidthspacingWidthnone

除了上述属性外,我们还可以通过代码来实现进一步的配置,如设置数据项的点击事件、长按事件等。示例代码如下:

gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        // 处理点击事件
    }
});

gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
        // 处理长按事件
        return true;
    }
});

在上述代码中,我们分别设置了 GridView 的点击事件和长按事件,根据事件的类型,我们可以在相应的回调方法中编写相应的逻辑代码。

自定义

使用 ArrayAdapter,每个数据项都会被封装成一个 TextView,而且每个数据项的显示样式都是一样的。如果我们需要自定义每个数据项的样式,可以通过自定义适配器来实现。示例代码如下:

public class MyAdapter extends BaseAdapter {

    private List<MyData> dataList;
    private LayoutInflater inflater;

    public MyAdapter(Context context, List<MyData> dataList) {
        this.dataList = dataList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return dataList.size();
    }

    @Override
    public Object getItem(int position) {
        return dataList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.my_item_layout, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.imageView = convertView.findViewById(R.id.item_image);
            viewHolder.textView = convertView.findViewById(R.id.item_text);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        MyData data = (MyData) getItem(position);
        viewHolder.imageView.setImageResource(data.getImageId());
        viewHolder.textView.setText(data.getName());
        return convertView;
    }

    private static class ViewHolder {
        ImageView imageView;
        TextView textView;
    }

}

在上述代码中,我们创建了一个 MyAdapter 类,继承自 BaseAdapter,并重写了其四个重要的方法,分别是 getCountgetItemgetItemIdgetView。其中 getView 方法是最为重要的方法,它决定了每个数据项的显示样式。我们在 getView 方法中使用了一个 ViewHolder 类来优化列表项的渲染,提高了 GridView 的显示效率。

然后,在代码中我们创建了一个 MyData 类,用于封装数据项的信息,它包含一个图片 ID 和一个名称字段。在 getView 方法中,我们将每个数据项对应的图片和名称分别设置到它们对应的 ImageViewTextView

最后,在代码中,我们找到 GridView,并将其适配器设置为 MyAdapter 的一个实例:

GridView gridView = findViewById(R.id.grid_view);
List<MyData> dataList = new ArrayList<>();
// 添加数据
gridView.setAdapter(new MyAdapter(this, dataList));

优化

GridView 中,每个数据项的布局随着列表项的增加会变得越来越昂贵,会导致应用程序变慢或崩溃。因此,在使用 GridView 时,我们需要采取一些优化措施,以保证它的流畅性。

  1. 使用 ViewHolder 模式:ViewHolder 模式可以减少每个列表项布局时创建视图对象的次数,能够极大地提高性能。通过使用 ViewHolder,我们可以将列表项的布局对象缓存在内存中,减少视图对象的创建次数。

  2. 使用 convertView 缓存视图对象:在绑定数据时,使用已经创建的视图资源能够加快列表项的创建速度。使用 convertView 来缓存视图可以重复使用之前加载的视图,将它们存储在内存中,以便下次使用。

  3. 异步加载图片资源:当我们在列表项中添加了图片资源时,应该采用异步加载的方式,以免阻塞主线程。可以使用 Glide、Picasso 等图片库来实现异步加载。

示例代码如下:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.my_item_layout, parent, false);
        viewHolder = new ViewHolder();
        viewHolder.imageView = convertView.findViewById(R.id.item_image);
        viewHolder.textView = convertView.findViewById(R.id.item_text);
        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }
    MyData data = (MyData) getItem(position);
    Glide.with(context)
            .load(data.getImageUrl())
            .into(viewHolder.imageView);
    viewHolder.textView.setText(data.getName());
    return convertView;
}

在上述代码中,我们使用了 Glide 异步加载图片,提高了列表项的渲染速度。

示例说明

示例 1:展示图片列表

首先,我们准备一些图片资源,将它们显示在 GridView 中。我们可以使用自定义适配器来实现列表项的自定义,也可以使用 ArrayAdapter 来快速创建视图。示例代码如下:

GridView gridView = findViewById(R.id.grid_view);
List<String> imageUrlList = new ArrayList<>();
// 添加图片资源
gridView.setAdapter(new ImageAdapter(this, imageUrlList));

在这里,我们创建了一个 ImageAdapter 类,用于封装图片的 URL,将图片异步加载并显示到 ImageView 中。示例代码如下:

public class ImageAdapter extends BaseAdapter {

    private List<String> imageUrlList;
    private LayoutInflater inflater;

    public ImageAdapter(Context context, List<String> imageUrlList) {
        this.imageUrlList = imageUrlList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return imageUrlList.size();
    }

    @Override
    public Object getItem(int position) {
        return imageUrlList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ImageView imageView;
        if (convertView == null) {
            imageView = new ImageView(parent.getContext());
        } else {
            imageView = (ImageView) convertView;
        }
        Glide.with(parent.getContext())
                .load(getItem(position))
                .into(imageView);
        return imageView;
    }

}

示例 2:展示应用程序列表

其次,我们使用 GridView 来展示应用程序图标和名称。这里,我们使用了系统应用程序图标和名称,通过解析应用程序的信息来进行展示。示例代码如下:

GridView gridView = findViewById(R.id.grid_view);
List<AppData> appList = new ArrayList<>();
// 获取应用程序信息
PackageManager packageManager = getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfoList = packageManager.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfoList) {
    AppData appData = new AppData();
    appData.setName(resolveInfo.loadLabel(packageManager).toString());
    appData.setIcon(resolveInfo.loadIcon(packageManager));
    appList.add(appData);
}
// 设置适配器
gridView.setAdapter(new AppAdapter(this, appList));

在这里,我们通过调用 PackageManagerqueryIntentActivities 方法来获取系统中所有的应用程序信息,然后将它们转换为列表项展示出来。示例代码如下:

public class AppData {
    private String name;
    private Drawable icon;

    // 省略 getter 和 setter 方法
}

public class AppAdapter extends BaseAdapter {

    private List<AppData> appList;
    private LayoutInflater inflater;

    public AppAdapter(Context context, List<AppData> appList) {
        this.appList = appList;
        inflater = LayoutInflater.from(context);
    }

    @Override
    public int getCount() {
        return appList.size();
    }

    @Override
    public Object getItem(int position) {
        return appList.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder viewHolder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.app_item_layout, parent, false);
            viewHolder = new ViewHolder();
            viewHolder.imageView = convertView.findViewById(R.id.app_icon);
            viewHolder.textView = convertView.findViewById(R.id.app_name);
            convertView.setTag(viewHolder);
        } else {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        AppData appData = (AppData) getItem(position);
        viewHolder.imageView.setImageDrawable(appData.getIcon());
        viewHolder.textView.setText(appData.getName());
        return convertView;
    }

    private static class ViewHolder {
        ImageView imageView;
        TextView textView;
    }

}

在这里,我们创建了一个 AppAdapter 类,用于封装应用程序的图标和名称,将它们展示到 ImageViewTextView 中。通过使用 ViewHolder 和 convertView 缓存视图,我们能够快速地创建和显示列表项,并减少视图对象的创建次数。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Android 控件GridView使用案例讲解 - Python技术站

(0)
上一篇 2023年6月26日
下一篇 2023年6月26日

相关文章

  • c#程序调用cmd执行命令

    以下是详细讲解“C#程序调用CMD执行命令的完整攻略”的标准Markdown格式文本: C#程序调用CMD执行命令的完整攻略 在C#程序中,有时需要调用CMD执行命令,以便于实现一些特定的功能。本文将介绍C#程序调用CMD执行命令的完整攻略,包括两个示例说明。 1. 使用Process类调用CMD 在C#程序中,可以使用Process类调用CMD执行命令。以…

    other 2023年5月9日
    00
  • Linux系列:进阶之jdk、X window安装与使用

    Linux系列:进阶之jdk、X window安装与使用 JDK安装 JDK是Java Development Kit(Java开发工具包)的缩写。用于开发Java程序的必备工具之一。 以下是在Linux系统上安装JDK的步骤: 1. 安装JDK 打开终端,并使用如下命令安装JDK: sudo apt install default-jdk 2. 检查JDK…

    其他 2023年3月28日
    00
  • 从零开始封装自己的自定义Vue组件

    下面是详细讲解“从零开始封装自己的自定义Vue组件”的完整攻略: 1. 确定组件需求及功能 在封装自定义Vue组件之前,需要先确定需要开发哪些组件,以及组件需要实现哪些功能。对于网站中需要复用的UI元素,可以考虑封装成组件,例如轮播图、瀑布流布局等。 在确定组件需求及功能后,需要根据组件类型及功能,采用不同的基础组件。例如,若需要实现一个表单组件,可以基于I…

    other 2023年6月25日
    00
  • vue多次打包后出现浏览器缓存的问题及解决

    针对“vue多次打包后出现浏览器缓存的问题及解决”这个问题,我们可以采取以下两种方案: 方案一:添加hash 每次打包时,为打包的静态资源文件添加hash,这样即使文件内容不变,文件名字也会发生变化,避免浏览器缓存问题。 在vue.config.js配置文件中设置filenameHashing: true。 module.exports = { filena…

    other 2023年6月27日
    00
  • mysql的interval函数用法

    MySQL的INTERVAL函数用法 MySQL是一种流行的关系型数据库管理系统,常用于网站和应用程序的数据存储和管理。其中一个非常有用的函数是INTERVAL函数,它使得我们可以对日期和时间进行各种运算和比较。在本文中,我们将讨论INTERVAL函数的用法和示例。 INTERVAL函数概述 INTERVAL函数是MySQL中用于对日期和时间进行运算的函数,…

    其他 2023年3月28日
    00
  • java实现基于UDP协议网络Socket编程(C/S通信)

    下面是“java实现基于UDP协议网络Socket编程(C/S通信)”的完整攻略。 一、UDP协议 UDP(User Datagram Protocol,用户数据报协议)是一种无状态的、轻量级的传输协议,与TCP相比,不保证可靠的传输(不提供丢包重传、状态协商等功能),但具有实时性好、开销小、网络负担小等优点。在网络游戏、实时音视频、实时监控等方面广泛应用。…

    other 2023年6月27日
    00
  • uniapp开发微信小程序自定义顶部导航栏功能实例

    下面我来为大家详细讲解一下“uniapp开发微信小程序自定义顶部导航栏功能实例”的完整攻略。 一、准备工作 首先,需要使用HBuilderX开发工具创建一个新项目,选择uni-app项目,在项目配置的时候需要选择添加微信小程序插件,此处添加“微信小程序自定义组件插件”。其次,需要在“App.vue”文件中定义NavigationBar组件,定义方法如下: &…

    other 2023年6月25日
    00
  • JavaScript axios安装与封装案例详解

    JavaScript axios安装与封装案例详解 简介 在 Web 开发过程中,我们经常需要进行异步网络请求。这时候,一个强大并且易于使用的工具就是 axios 库。axios 是一个基于 promise 的 HTTP 客户端,可以用于浏览器和 Node.js 中。 在本文中,我们将详细讲解如何安装 axios 库,并介绍如何封装 axios 进行网络请求…

    other 2023年6月25日
    00
合作推广
合作推广
分享本页
返回顶部