如何自定义GridView的元素
2015-02-08 · 知道合伙人数码行家
知道合伙人数码行家
向TA提问 私信TA
简单的介绍了使用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;
}
}
onCreate()中加载布局gridview.xml,创建一个GridViewAdapter对象adapter,将mGridView设置适配器为adapter。
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>
布局文件很简单,只有一个GridView控件和Button控件,其中GridView控件的gravity属性设置为center_horizontal,即将GridView整体内容居中显示在parent view上,这里可以简单理解为居中显示在页面上。
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>
比较简单,一张图片,底下一个文字说明。然后对每项Item的数据加载,就是在getView函数中对ViewHolder对象holder的处理。
@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;
}