26. 【Android教程】网格视图 GridView

简介: 26. 【Android教程】网格视图 GridView

和 ListView 一样,GridView 也是一个 ViewGroup,它用来将各种不同的控件整合到一起,按照一个二维可以滚动的网格视图展示出来。同时也遵循 MVC 模式,依靠 Adapter 自动帮我们完成 UI 和数据的绑定。

1. GridView 的特性

GridView 在 Android App 中运用非常广泛,比如我们手机的系统相册将我们的照片及照片名称按照网格的样式排列起来,并且可以上下滚动,这种效果非常适合用 GridView 实现。

为了实现 MVC 模式,更方便的管理数据与 UI,GridView 通过 Adapter 完成数据的填充,Adapter 的使用几乎和 ListView 一样,另外系统提供了几种简单的 Adapter,具体可以参考 23 节和 24 节的内容。

2. GridView 的基本用法

GridView 和 上一节所学的 ListView 极其相似,主要还是从属性、API 及事件监听器三个方面来介绍基本用法。

2.1 GridView 的常用属性

  • android:columnWidth:
  • 设置网格的列宽
  • android:gravity:
  • 网格内各个 item 的对齐方式
  • android:horizontalSpacing:
  • 网格的各个 item 在水平方向上的间距
  • android:verticalSpacing:
  • 网格的各个 item 在垂直方向上的间距
  • android:numColumns:
  • 设置列数,可以直接设置距离也可以设置成“auto_fit”让系统自适应
  • android:stretchMode:
  • 设置网格拉伸模式,可选值如下:
  • none: 不拉伸
  • spacingWidth: 将多余空间分摊给网格的间隔空隙
  • columnWidth: 将多余空间分摊给网格的各个列
  • spacingWidthUniform: 将多余空间分摊给网格的各个列及其间隔空隙


2.2 GridView 的常用 API

  • smoothScrollByOffset:
    平滑滚动一个相对距离
  • smoothScrollToPosition:
    平滑滚动到某个位置

2.3 GridView 的事件监听器

  • setOnItemClickListener:
    设置 GridView 的 item 点击事件回调,此接口与 ListView 完全一样。

3. GridView 的使用示例

为了和 ListView 以及 Adapter 两节的内容作对比,本节依旧实现“水果列表”的例子,只不过本节会把单维列表改成二维的网格样式,代码可基于上一节直接修改。

3.1 布局文件编写

首先修改布局文件,将 ListView 替换成 GridView 并添加一些 GridView 特有的属性,如下

3.2 GridView 适配器

以上属性都在 25.2.1 小节有描述,也比较好理解,接着修改 MyAdapter 类,它是继承自 BaseAdapter 实现的自定义适配器,因为二维列表更节省空间,上一节的水果数目已经没法占满一屏,这样会导致列表不能滑动,不利于体验 GridView 的效果。为此有两种解决方法:一个是我们可以手动扩展我们的列表数组,增加一些水果名称和图片;第二种方法是直接修改适配器,不断地循环从之前的列表中取水果数据。为了让大家更好的理解适配器的原理,我们采用第二种方法来扩展列表,我们需要修改两个回调方法:getCount和getView。

getCount 表示列表的总 item 数,我们直接将水果列表长度乘以10:

 @Override
  public int getCount() {
      return mName.length * 10;
  }
  • getView 中我们完成 View 和数据的绑定,我们需要循环取数,所以只需要将 item 的位置对数组大小取模即可

完整的 MyAdapter 代码如下:

package com.emercy.myapplication;
 
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
 
 
public class MyAdapter extends BaseAdapter {
 
    private Context mContext;
    private String[] mName;
    private int[] mResId;
 
    public MyAdapter(Context context) {
        mContext = context;
    }
 
    public void setData(String[] name, int[] resId) {
        mName = name;
        mResId = resId;
    }
 
 
    @Override
    public int getCount() {
        return mName.length * 10;
    }
 
    @Override
    public Object getItem(int position) {
        return null;
    }
 
    @Override
    public long getItemId(int position) {
        return position;
    }
 
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        convertView = LayoutInflater.from(mContext).inflate(R.layout.list_view, null);
        TextView name = convertView.findViewById(R.id.textView);
        ImageView image = convertView.findViewById(R.id.imageView);
        name.setText(mName[position % mName.length]);
        image.setImageResource(mResId[position % mResId.length]);
        return convertView;
    }
}

3.3 主 Activity 逻辑

Activity 的逻辑其实和 ListView 中的例子完全一样,只需要将所有的 ListView 类型改成 GridView 即可。这里体现了 MVC 设计思路的灵活性,我们想要替换一个样式其实只需要修改布局文件,主逻辑和数据层完全不需要修改,这就是前面所说的 UI 和数据解耦的强大优势。MainActivity 代码如下:


package com.emercy.myapplication;
 
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.Toast;
 
public class MainActivity extends Activity {
 
    GridView mGridView;
    String[] mDataName = {"苹果", "梨", "香蕉", "桃子", "西瓜", "荔枝", "橘子"};
    int[] mDataImage = {R.drawable.apple, R.drawable.pear, R.drawable.banana, R.drawable.peach,
            R.drawable.watermelon, R.drawable.lychee, R.drawable.orange, R.drawable.orange};
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mGridView = findViewById(R.id.gridview);
 
        MyAdapter adapter = new MyAdapter(this);
        adapter.setData(mDataName, mDataImage);
        mGridView.setAdapter(adapter);
        mGridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
                Toast.makeText(getApplicationContext(), mDataName[i % mDataName.length], Toast.LENGTH_LONG).show();
            }
        });
    }
}

编译之后,可以发现从一维列表变成了网格列表,水果的样式循环 10 次,效果如下:

4. 小结

本节介绍了 Adapter 常用的第二个控件,它与 ListView 的用法及其相似,作为网格样式,相比 ListView 有一些二维的属性,其余的 API 和事件回调都和 ListView 完全一样。最后我们完成了和 ListView 类似的一个“水果”列表样式,通过修改 Adapter 可以达到扩展列表的效果。


这里也希望大家能够注意到 Adapter 的几个回调接口具体的含义,因为很多人虽然经常用 Adpater,但其实都是墨守成规的去实现那几个回调,没有真正的理解其内涵,这样在今后的实际开发中往往会遇到很多不可控的问题,希望大家能够做到知其然并知其所以然。


相关文章
|
1月前
|
Android开发 开发者
安卓应用开发中的自定义视图
【9月更文挑战第37天】在安卓开发的海洋中,自定义视图犹如一座座小岛,等待着勇敢的探索者去发现其独特之处。本文将带领你踏上这段旅程,从浅滩走向深海,逐步揭开自定义视图的神秘面纱。
38 3
|
3月前
|
供应链 物联网 区块链
未来触手可及:探索新兴技术的趋势与应用安卓开发中的自定义视图:从基础到进阶
【8月更文挑战第30天】随着科技的飞速发展,新兴技术如区块链、物联网和虚拟现实正在重塑我们的世界。本文将深入探讨这些技术的发展趋势和应用场景,带你领略未来的可能性。
|
3月前
|
测试技术 Android开发 Python
探索软件测试的艺术:从基础到高级安卓应用开发中的自定义视图
【8月更文挑战第29天】在软件开发的世界中,测试是不可或缺的一环。它如同艺术一般,需要精细的技巧和深厚的知识。本文旨在通过浅显易懂的语言,引领读者从软件测试的基础出发,逐步深入到更复杂的测试策略和工具的使用,最终达到能够独立进行高效测试的水平。我们将一起探索如何通过不同的测试方法来确保软件的质量和性能,就像艺术家通过不同的色彩和笔触来完成一幅画作一样。
|
8天前
|
Android开发
布谷语音软件开发:android端语音软件搭建开发教程
语音软件搭建android端语音软件开发教程!
|
13天前
|
搜索推荐 前端开发 Android开发
安卓应用开发中的自定义视图实现
【10月更文挑战第30天】在安卓开发的海洋中,自定义视图是那抹不可或缺的亮色,它为应用界面的个性化和交互体验的提升提供了无限可能。本文将深入探讨如何在安卓平台创建自定义视图,并展示如何通过代码实现这一过程。我们将从基础出发,逐步引导你理解自定义视图的核心概念,然后通过一个实际的代码示例,详细讲解如何将理论应用于实践,最终实现一个美观且具有良好用户体验的自定义控件。无论你是想提高自己的开发技能,还是仅仅出于对安卓开发的兴趣,这篇文章都将为你提供价值。
|
2月前
|
Android开发 开发者
安卓开发中的自定义视图:从入门到精通
【9月更文挑战第19天】在安卓开发的广阔天地中,自定义视图是一块充满魔力的土地。它不仅仅是代码的堆砌,更是艺术与科技的完美结合。通过掌握自定义视图,开发者能够打破常规,创造出独一无二的用户界面。本文将带你走进自定义视图的世界,从基础概念到实战应用,一步步展示如何用代码绘出心中的蓝图。无论你是初学者还是有经验的开发者,这篇文章都将为你打开一扇通往创意和效率的大门。让我们一起探索自定义视图的秘密,将你的应用打造成一件艺术品吧!
61 10
|
2月前
|
XML 编解码 Android开发
安卓开发中的自定义视图控件
【9月更文挑战第14天】在安卓开发中,自定义视图控件是一种高级技巧,它可以让开发者根据项目需求创建出独特的用户界面元素。本文将通过一个简单示例,引导你了解如何在安卓项目中实现自定义视图控件,包括创建自定义控件类、处理绘制逻辑以及响应用户交互。无论你是初学者还是有经验的开发者,这篇文章都会为你提供有价值的见解和技巧。
44 3
|
2月前
|
前端开发 Android开发 开发者
安卓应用开发中的自定义视图基础
【9月更文挑战第13天】在安卓开发的广阔天地中,自定义视图是一块神奇的画布,它允许开发者将想象力转化为用户界面的创新元素。本文将带你一探究竟,了解如何从零开始构建自定义视图,包括绘图基础、触摸事件处理,以及性能优化的实用技巧。无论你是想提升应用的视觉吸引力,还是追求更流畅的交互体验,这里都有你需要的金钥匙。
|
2月前
|
前端开发 搜索推荐 Android开发
探索安卓开发中的自定义视图##
【9月更文挑战第6天】 在安卓应用开发的世界里,自定义视图如同绘画艺术中的色彩,它们为界面设计增添了无限可能。通过掌握自定义视图的绘制技巧,开发者能够创造出既符合品牌形象又提升用户体验的独特界面元素。本文将深入浅出地介绍如何从零开始构建一个自定义视图,包括基础框架搭建、关键绘图方法实现、事件处理机制以及性能优化策略。准备好让你的安卓应用与众不同了吗?让我们开始吧! ##
|
3月前
|
前端开发 Android开发 开发者
安卓开发中的自定义视图:构建你的第一个控件
【8月更文挑战第26天】在安卓开发的浩瀚海洋中,自定义视图是一块充满魔力的乐土。它不仅是开发者展示创造力的舞台,更是实现独特用户体验的关键。本文将带你步入自定义视图的世界,从基础概念到实战应用,一步步教你如何打造自己的第一个控件。无论你是初学者还是有经验的开发者,这篇文章都将为你的开发之旅增添新的风景。