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日

相关文章

  • iOS开发之适配iOS10以及Xcode8

    iOS开发之适配iOS10以及Xcode8 简介 随着iOS 10的推出以及Xcode 8的正式发布,许多iOS开发者发现在新版本的开发环境中需要对项目进行一些适配工作才能确保应用程序在iOS 10上正常运行,本文将详细介绍如何适配iOS 10以及Xcode 8开发环境。 环境适配 在Xcode 8中,苹果引入了一些新特性以及变化,因此需要对开发环境进行一些…

    other 2023年6月26日
    00
  • Win11无限重启怎么办 Win11系统自动重启解决办法

    Win11无限重启怎么办 问题描述 在使用Win11系统时,有时可能会出现无限重启的情况,即计算机会在启动过程中不断地重启。这种情况会给用户带来极大的困扰,用户需要采取一些解决办法来解决。 解决办法 1.关闭自动重启 如果Win11系统在启动过程中循环重启,用户可以在计算机进入“安全模式”后,关闭自动重启功能。具体方法如下: 在计算机启动时按下 F8 按键,…

    other 2023年6月26日
    00
  • VUE实现分布式医疗挂号系统预约挂号首页步骤详情

    针对这个问题,我会给出以下详细的解答: 1. 背景与需求 在实现分布式医疗挂号系统时,预约挂号首页是至关重要的一步。用户通过首页进行预约挂号,需要浏览医院信息、选择科室、医生以及挂号时间等。因此,预约挂号首页需要实现如下功能: 显示医院信息,包括医院名称、地址、电话等。 显示可挂号的科室信息,包括科室名称、医生信息等。 支持根据时间、科室、医生等条件进行挂号…

    other 2023年6月26日
    00
  • 基于Java回顾之反射的使用分析

    下面是“基于Java回顾之反射的使用分析”的完整攻略: 简介 反射是Java编程语言的一种功能,它允许程序在运行时对本身进行检查,这其中包括了访问对象、调用方法等操作。反射技术在Java开发中经常使用,但是在使用时需要注意一些细节和规范,否则会影响程序的可读性、健壮性和安全性。本文将详细介绍Java反射的使用规范和细节,同时通过示例代码说明。 反射的基本使用…

    other 2023年6月27日
    00
  • 关于查询MySQL字段注释的5种方法总结

    标题:关于查询MySQL字段注释的5种方法总结 简介:本文总结了5种查询MySQL字段注释的方法,包括通过SQL语句查询、使用Navicat查询、使用Workbench查询、使用命令行查询和使用Mysql-Front查询。同时,本文将提供两种方法的示例说明。 方法一:通过SQL语句查询 SQL语句可以用于查询MySQL数据库中的字段注释信息。具体操作步骤如下…

    other 2023年6月25日
    00
  • linux环境安装、卸载docker

    Linux环境安装、卸载Docker Docker是一种开源的容器化平台,可以通过将应用程序打包到一个容器中来实现应用程序的依赖隔离、运行环境的一致性和跨平台性。Docker支持在多种操作系统下运行,本文将介绍在Linux环境下如何安装和卸载Docker。 安装Docker 条件要求 在安装Docker之前,需要满足以下条件: Linux系统版本需要为Ubu…

    其他 2023年3月28日
    00
  • win10无法新建文件夹该怎么办?win10右键没有新建文件夹的解决办法

    首先,我们需要明确一下为什么会出现win10无法新建文件夹的问题。通常情况下,这可能是因为Windows对“新建文件夹”项进行了禁用或删除。下面是解决这个问题的两种常用方法: 方法一:使用注册表修复 使用 Win+R 快捷键打开“运行”对话框,然后输入“regedit”并按下 Enter。 在注册表编辑器中,转到以下路径:HKEY_CLASSES_ROOT\…

    other 2023年6月27日
    00
  • 你应该知道的States字段使用规范

    关于“你应该知道的States字段使用规范”的完整攻略,主要包括几个方面的内容。 标题 你应该知道的States字段使用规范 什么是States字段 States字段是网页中的状态字段,是用来记录网页出现的状态变化的。在前端开发中,States字段通常被用来实现表单验证、页面切换和数据交换等功能。 States字段的命名规范 在命名States字段时,需要符…

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