下面是《深入设计与应用 Android GridView》的系统教程,从原理讲解、样式自定义、到实际应用案例,帮助你全面掌握 GridView 的用法与扩展技巧。


📚 深入设计与应用 Android GridView 全面指南


🧱 一、什么是 GridView?

GridView 是 Android 中的一个视图控件,用于以网格(grid)的形式显示列表项。每个子项的尺寸一致,类似于图片墙、商品展示页等。

  • 继承自AbsListView
  • 布局形式:二维表格
  • 常用于:图标菜单、相册、商城产品陈列

🧭 二、GridView 基本使用流程

1. 在布局中添加 GridView

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

2. 编写 Adapter(通常继承自 BaseAdapter

public class MyGridAdapter extends BaseAdapter {
    private Context context;
    private String[] data;
    private int[] images;

    public MyGridAdapter(Context context, String[] data, int[] images) {
        this.context = context;
        this.data = data;
        this.images = images;
    }

    @Override
    public int getCount() {
        return data.length;
    }

    @Override
    public Object getItem(int position) {
        return data[position];
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = LayoutInflater.from(context).inflate(R.layout.item_grid, parent, false);
        TextView text = view.findViewById(R.id.text);
        ImageView img = view.findViewById(R.id.icon);

        text.setText(data[position]);
        img.setImageResource(images[position]);

        return view;
    }
}

3. 绑定数据到 GridView

GridView gridView = findViewById(R.id.grid_view);
MyGridAdapter adapter = new MyGridAdapter(this, titles, icons);
gridView.setAdapter(adapter);

🎨 三、GridView 子项样式设计(item_grid.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="100dp"
    android:layout_height="120dp"
    android:orientation="vertical"
    android:gravity="center"
    android:background="@drawable/grid_item_bg">

    <ImageView
        android:id="@+id/icon"
        android:layout_width="60dp"
        android:layout_height="60dp"
        android:src="@drawable/ic_launcher" />

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="标题"
        android:textSize="14sp"
        android:layout_marginTop="8dp" />
</LinearLayout>

🧩 四、常用属性与优化技巧

属性说明
android:numColumns="auto_fit"自动根据屏幕宽度调整列数
android:columnWidth="90dp"每列宽度
android:stretchMode="columnWidth"拉伸填满屏幕
android:verticalSpacing行间距
android:horizontalSpacing列间距

🔧 优化技巧

  • 使用 ViewHolder 模式:避免频繁 findViewById,提升滑动流畅度
  • 预加载图片:使用 Glide/Picasso 加载网络图片
  • 根据屏幕自动适配列数:动态计算列宽+列数

🧪 五、实际应用场景

📷 1. 图片墙(Photo Grid)

  • 使用网络图片列表,配合 Glide 自动加载
  • 支持点击查看大图(启动新 Activity)

🛍️ 2. 商品展示页

  • 加载商品缩略图 + 商品名
  • 可在 Adapter 中根据状态修改背景色(如促销/热销)

🧭 3. 九宫格菜单

  • 设置固定图标 + 功能名称
  • 点击项跳转到对应页面或功能模块

🔄 六、点击事件与交互

gridView.setOnItemClickListener((parent, view, position, id) -> {
    Toast.makeText(this, "点击了:" + titles[position], Toast.LENGTH_SHORT).show();
});

🚀 七、动态设置列数适配屏幕

DisplayMetrics metrics = getResources().getDisplayMetrics();
int screenWidth = metrics.widthPixels;
int itemWidth = (int) (100 * metrics.density); // 每项宽度约 100dp

int numColumns = screenWidth / itemWidth;
gridView.setNumColumns(numColumns);

🧱 八、GridView 与 RecyclerView 对比(推荐)

特性GridViewRecyclerView + GridLayoutManager
灵活性较低非常高
性能优化一般更好(支持 View 缓存池)
动画支持内置支持
推荐使用场景快速开发简单列表复杂布局、动态列表

✅ 若开发新项目,建议优先使用 RecyclerView + GridLayoutManager 实现网格布局。


📦 九、总结

  • GridView 是经典网格布局控件,适合快速实现图片墙、菜单等界面
  • 搭配自定义 Adapter 和样式能实现灵活效果
  • 对于复杂交互或动态布局,建议使用 RecyclerView 替代

🔗 参考链接


好的,我们继续深入讲解 Android GridView 的进阶设计与实际应用技巧,涵盖以下几个方面:


🔍 十、进阶设计:ViewHolder 优化模式

当 GridView 显示大量数据时,若不优化性能,将出现滑动卡顿等问题。ViewHolder 模式能极大提高性能。

✅ 优化后的 getView() 实现:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    ViewHolder holder;
    if (convertView == null) {
        convertView = LayoutInflater.from(context).inflate(R.layout.item_grid, parent, false);
        holder = new ViewHolder();
        holder.imageView = convertView.findViewById(R.id.icon);
        holder.textView = convertView.findViewById(R.id.text);
        convertView.setTag(holder); // 绑定 ViewHolder
    } else {
        holder = (ViewHolder) convertView.getTag(); // 复用 ViewHolder
    }

    holder.textView.setText(data[position]);
    holder.imageView.setImageResource(images[position]);
    return convertView;
}

static class ViewHolder {
    ImageView imageView;
    TextView textView;
}

🚀 优势:减少 findViewById 次数,提升性能。


🌈 十一、自定义选择效果(选中高亮)

GridView 没有默认选中项样式,需手动设置:

✅ 方法一:设置选择背景

<!-- item_grid.xml 的根布局添加背景 -->
android:background="@drawable/grid_item_selector"

✅ 方法二:使用 Selector 实现状态变化背景

<!-- res/drawable/grid_item_selector.xml -->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:drawable="@color/pressed_color"/>
    <item android:drawable="@color/normal_color"/>
</selector>

📁 十二、加载网络图片(Glide 示例)

如果你从网络加载图像,建议使用 Glide 代替 setImageResource()

// build.gradle
implementation 'com.github.bumptech.glide:glide:4.15.1'
annotationProcessor 'com.github.bumptech.glide:compiler:4.15.1'

✅ 修改 Adapter 中的图像加载逻辑:

Glide.with(context)
     .load(imageUrls[position])
     .placeholder(R.drawable.placeholder)
     .into(holder.imageView);

🧩 十三、自定义列数和响应式设计

为了让 GridView 自动适配各种屏幕尺寸,动态设置列数非常重要。

✅ 方法:根据屏幕宽度和预设列宽动态调整列数

DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

int screenWidth = metrics.widthPixels;
int itemWidth = (int) TypedValue.applyDimension(
    TypedValue.COMPLEX_UNIT_DIP, 100, getResources().getDisplayMetrics());

int numColumns = screenWidth / itemWidth;
gridView.setNumColumns(numColumns);

🎯 十四、添加头部和底部(GridView 限制)

GridView 不像 ListView 有 addHeaderView() 方法,因此如果需要在 GridView 上方加内容,可以使用以下方式:

✅ 方法一:在布局文件中外包一个 LinearLayout

<LinearLayout
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:text="我是头部"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <GridView
        android:id="@+id/grid_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:numColumns="3"/>
</LinearLayout>

🛠️ 十五、替代方案推荐:RecyclerView + GridLayoutManager

GridView 虽然方便,但它局限性大。推荐使用 RecyclerView 实现网格布局。

✅ 替代方案核心代码:

RecyclerView recyclerView = findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
recyclerView.setAdapter(new MyRecyclerAdapter(...));

👍 优点:支持头尾添加、动画、加载更多、分页、数据刷新等高级功能。


🧾 十六、完整项目结构建议

res/
├── layout/
│   ├── activity_main.xml
│   └── item_grid.xml
├── drawable/
│   └── grid_item_selector.xml
src/
├── MainActivity.java
├── MyGridAdapter.java
└── data/
    └── images/, icons/, json/

🔗 十七、延伸学习资源