之前有写过一篇博客《GridView应用》,简单的介绍了使用GridView的方法,由于使用的是SimpleAdapter,因此,无法自定义每个GridView元素的内容,例如:每项GridView Item都显示图片以及图片介绍,介绍文字显示在图片下方,上方等位置,当然也可以做到显示在图片底部,其实关键还是在Adapter的使用上,只需要自定义一个Adapter继承自BaseAdapter即可。本例的效果图如下:
先看MainActivity.java
public class MainActivity extends Activity { private Context mContext; private GridView mGridView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.gridview); mContext = getApplicationContext(); final int reqSize = getResources().getDimensionPixelSize(R.dimen.image_thumbnail_size); GridViewAdapter adapter = new GridViewAdapter(mContext, reqSize); mGridView = (GridView)findViewById(R.id.gridview); mGridView.setAdapter(adapter); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
gridview.xml如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" > <GridView android:id="@+id/gridview" android:layout_width="fill_parent" android:layout_height="wrap_content" android:columnWidth="@dimen/image_thumbnail_size" android:numColumns="auto_fit" android:horizontalSpacing="@dimen/image_thumbnail_spacing" android:verticalSpacing="@dimen/image_thumbnail_spacing" android:stretchMode="columnWidth" android:gravity="center_horizontal" > </GridView> <Button android:id="@+id/update_btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:layout_centerHorizontal="true" android:text="@string/update" /> </RelativeLayout>
GridViewAdapter.java代码如下:
public class GridViewAdapter extends BaseAdapter { private String mType = "landscape"; private Context mContext; private LayoutInflater mInflater; private ImageResizer mLoader; private int mNumColumns = 0; private int mItemHeight = 0; private GridView.LayoutParams mImageViewLayoutParams; public GridViewAdapter(Context context, int reqSize) { mContext = context; mLoader = new ImageResizer(mContext, reqSize); mLoader.setLoadingImage(R.drawable.empty_photo); mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } public GridViewAdapter(Context context, int reqWidth, int reqHeight) { mContext = context; mLoader = new ImageResizer(mContext, reqWidth, reqHeight); mLoader.setLoadingImage(R.drawable.empty_photo); mInflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { // TODO Auto-generated method stub return GridViewConstData.getItemCount(mType); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return 0; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub int resId = 0; ViewHolder holder = null; Log.d(TAG, "getView: position = " + position); if (convertView == null || convertView.getTag() == null) { convertView = mInflater.inflate(R.layout.gridviewitem, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } resId = GridViewConstData.getImageItemId(getFragmentType(), position); mLoader.loadImage(resId, holder.mImageItem); holder.mTextItem.setText(GridViewConstData.getItemTextId(getFragmentType(), position)); return convertView; } public void setFragmentType(String type) { mType = type; } public String getFragmentType() { return mType; } public void setNumColumns(int numColumns) { mNumColumns = numColumns; } public int getNumColumns() { return mNumColumns; } public void setItemHeight(int height) { if (height == mItemHeight) { return; } mItemHeight = height; mImageViewLayoutParams = new GridView.LayoutParams(LayoutParams.MATCH_PARENT, mItemHeight); mLoader.setImageSize(height); notifyDataSetChanged(); } private class ViewHolder { ImageView mImageItem; TextView mTextItem; public ViewHolder(View layoutView) { mImageItem = (ImageView)layoutView.findViewById(R.id.image_item); mTextItem = (TextView)layoutView.findViewById(R.id.text_item); } } }重点内容还是看View getView(int position, View convertView, ViewGroup parent)。其中,增加了convertView和ViewHolder的代码,主要是用来对显示性能做的优化,详情请参考本博客另一篇文章《 ListView的Adapter性能优化》。那本文提到的如何自定义的问题呢?在getView函数中,下面这段很重要:
@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub int resId = 0; ViewHolder holder = null; if (convertView == null || convertView.getTag() == null) { convertView = mInflater.inflate(R.layout.gridviewitem, null); holder = new ViewHolder(convertView); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } ...... return convertView; }convertView是加载了一个布局gridviewitem得来的View,在gridviewitem.xml中我们就可自定义每个GridView的Item项了,本例布局如下:
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/image_table" android:layout_width="fill_parent" android:layout_height="@dimen/image_thumbnail_size"> <ImageView android:id="@+id/image_item" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:contentDescription="@string/image_item" /> </LinearLayout> <LinearLayout android:id="@+id/text_table" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_below="@+id/image_table"> <TextView android:id="@+id/text_item" android:layout_width="fill_parent" android:layout_height="wrap_content" android:gravity="center" android:textIsSelectable="false" /> </LinearLayout> </RelativeLayout>
@Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub ...... resId = GridViewConstData.getImageItemId(getFragmentType(), position); mLoader.loadImage(resId, holder.mImageItem); holder.mTextItem.setText(GridViewConstData.getItemTextId(getFragmentType(), position)); return convertView; }