如何自定义GridView的元素

这篇博客介绍如何在Android中自定义GridView的元素,以实现每项Item同时显示图片和文字介绍。通过创建自定义Adapter并继承BaseAdapter,可以灵活控制布局,将介绍文字置于图片上方或下方。示例代码包括MainActivity.java、gridview.xml和GridViewAdapter.java的实现。
摘要由CSDN通过智能技术生成

之前有写过一篇博客《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;
	}

}

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;
	}

希望本文对您有帮助,也算做个笔记。



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值