8.5 网格(Grid)视图组
本节介绍的网格(Grid)视图组可以将某种控件按照网格的形式组织起来,平铺在屏幕上。
参考示例程序:Icon Grid(ApiDemo=>Views=>Grid =>Icon Grid)
源代码: com/example/android/apis/view/Grid1.java
布局文件:grid_1.xml
Icon Grid 程序的运行结果如图所示:
本示例显示了当前系统中所包含的应用程序的图标。布局文件 grid_1.xml 的内容如下所示:
代码语言:javascript复制<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@ id/myGrid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:columnWidth="60dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
这里使用的是 GridView 标签,网格视图 GridView 的扩展关系如下所示:
代码语言:javascript复制 => android.view.View
=> android.view.ViewGroup
=> android.widget.AdapterView<T extends android. widget.Adapter>
=> android.widget.AbsListView
=> android.widget.GridView
本例中使用的 android:numColumns
、android:columnWidth
、android:horizontalSpacing
和 android:verticalSpacing
类是 GridView 的特定属性,分别表示了列的数目,列的宽度,水平间距和竖直间距,本例中的android:numColumns
设置为"auto_fit"表示根据宽度和间距等信息,自动适应。
AbsListView
是 ListView 和 GridView 的共同父类,它使用 ListAdapter 作为其中的数据。ListAdapter
作为列表的UI 和数据的桥梁,通过实现这个类来构建界面上的 AbsListView
。 android.widget.ListAdapter
实现了android.widget.Adapter
接口。
在本示例程序中,在布局文件中定义了 GridView,在 Java 代码中设置一个 BaseAdapter 作为 GridView 中的数据。
JAVA 源代码中实现的主要内容如下所示:
代码语言:javascript复制public class Grid1 extends Activity {
GridView mGrid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
loadApps();
setContentView(R.layout.grid_1);
mGrid = (GridView) findViewById(R.id.myGrid);
mGrid.setAdapter(new AppsAdapter()); // 设置 GridView 后面的数据
}
}
这里调用的 setAdapter()方法是 android.widget.AdapterView<T extends android. widget.Adapter>
中的方法,参数是所指定的一个模板类型 android.widget.Adapter
。
为了实现 GridView 的效果,需要构建一个 BaseAdapter,也就是 android.widget.BaseAdapter
。这个类表示了 Grid中的所包含的内容,GridView 的实现如下所示:
public class AppsAdapter extends BaseAdapter {
public AppsAdapter() { }
public View getView(int position, View convertView, ViewGroup parent) {
ImageView i;
if (convertView == null) {
i = new ImageView(Grid1.this);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
i.setLayoutParams(new GridView.LayoutParams(50, 50));
} else {
i = (ImageView) convertView;
}
ResolveInfo info = mApps.get(position);
i.setImageDrawable(info.activityInfo.loadIcon(getPackageManager()));
return i;
}
public final int getCount() {
return mApps.size();
}
public final Object getItem(int position) {
return mApps.get(position);
}
public final long getItemId(int position) {
return position;
}
}
AppsAdapter 主要需要实现 getView()函数,其中的 position 参数表示需要取得的 View 的位置。本例中的实现是获取系统中所有的应用程序的图标,也就是分类为 Intent.CATEGORY_LAUNCHER 的应用程序。
AbsListView 继承了 AdapterView,这是一个类的模板,如果需要让 GridView 实现对事件的影响,需要继承一个GridView ,并且实现AdapterView.OnItemClickListener
、 AdapterView.OnItemLongClickListener
和
AdapterView.OnItemSelectedListener
等几个接口。这几个接口如下所示:
AdapterView.OnItemClickListener {
abstract void onItemClick(AdapterView<?> parent, View view,
int position, long id) {}
}
AdapterView.OnItemLongClickListener {
abstract boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {}
}
AdapterView.OnItemSelectedListener {
abstract void onItemSelected(AdapterView<?> parent, View view,
int position, long id) {}
abstract void onNothingSelected(AdapterView<?> parent) {}
}
参考示例程序:Photo Grid(Views=>Grid =>Photo Grid)
源代码: com/example/android/apis/view/Grid2.java
布局文件:grid_2.xml
Photo Grid
程序的运行结果如图所示:
布局文件 grid_2.xml 如下所示:
代码语言:javascript复制<GridView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@ id/myGrid"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:numColumns="auto_fit"
android:columnWidth="60dp"
android:stretchMode="columnWidth"
android:gravity="center"
/>
Grid2.java 使用了:
代码语言:javascript复制public class Grid2 extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.grid_2);
GridView g = (GridView) findViewById(R.id.myGrid);
g.setAdapter(new ImageAdapter(this));
}
}
这里定义的 ImageAdapter 继承了 BaseAdapter,内容如下所示:
代码语言:javascript复制public class ImageAdapter extends BaseAdapter {
public ImageAdapter(Context c) {
mContext = c;
}
public int getCount() {
return mThumbIds.length;
}
public Object getItem(int position) {
return position;
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if (convertView == null) {
imageView = new ImageView(mContext);
imageView.setLayoutParams(new GridView.LayoutParams(45, 45));
imageView.setAdjustViewBounds(false);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
imageView.setPadding(8, 8, 8, 8);
} else {
imageView = (ImageView) convertView;
}
imageView.setImageResource(mThumbIds[position]);
return imageView;
}
private Context mContext;
private Integer[] mThumbIds = { // 图片的 id 数组
}
这里是使用一系列的图片,作为 GridView 中的内容。