今天上午逛论坛时,发现了一位同学问起GridView的问题,他想实现多张图片被选中的效果。看得出这位同学刚学Android没多久,让我想起了两年前的自己。正好今天不太忙,索性就把这个简单的demo写了一下,希望能够帮助到刚学android没多久的同学,话不多说,开工!
下面是demo中用到的两个xml文件:
activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<GridView
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:horizontalSpacing="20dp"
android:numColumns="4"
android:scrollbars="none"
android:verticalSpacing="20dp" >
</GridView>
</RelativeLayout>
android:horizontalSpacing 和 android:verticalSpacing 这两个属性是指定gridview中的每一项之间的横向间距和纵向间距,避免拥挤在一起
android:numColumns 这个属性是指定每一行显示视图的个数
item.xml
<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<ImageView
android:id="@+id/image"
android:layout_width="130dp"
android:layout_height="100dp"
android:src="@drawable/ic_launcher"
android:scaleType="fitXY"></ImageView>"
<ImageView
android:id="@+id/isselected"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:src="@drawable/selected"/>
</RelativeLayout>
下面是两份java代码,因为一般项目中,从网络接口或者本地文件解析的数据源都会封装成一个个实体类,所以下面的Entity即是封装的实体类。
Entity.java:
package com.example.gridviewdemo;
public class Entity {
private int imageUri;//读取图片的地址
private boolean isSelected;//是否被选中状体的标示符
public Entity(int imageUri,boolean isSelected) {
this.imageUri = imageUri;
this.isSelected = isSelected;
}
public int getImageUri() {
return imageUri;
}
public void setImageUri(int imageUri) {
this.imageUri = imageUri;
}
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean isSelected) {
this.isSelected = isSelected;
}
}
MainActivity.java
package com.example.gridviewdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
public class MainActivity extends Activity {
ArrayList<Entity> dataList;//用来装载数据源的列表
GridView gridView;
GridAdapter adapter;//自定义的适配器
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
initView();
}
/**
* 初始化数据
*/
private void initData(){
/**
* 这里,我们假设已经从网络或者本地解析好了数据,所以直接在这里模拟了10个实体类,直接装进列表中
*/
dataList = new ArrayList<Entity>();
for(int i=-0;i<10;i++){
Entity entity = new Entity(R.drawable.picture, false);
dataList.add(entity);
}
}
/**
* 初始化view视图
*/
private void initView(){
gridView = (GridView)findViewById(R.id.gridview);
adapter = new GridAdapter();
gridView.setAdapter(adapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
/**
* 根据position参数,可以获得跟GridView的子View相绑定的实体类,然后根据它的isSelected状态,来判断是否显示选中效果。
* 至于选中效果的规则,下面适配器的代码中会有说明
*/
if(dataList.get(position).isSelected()){
dataList.get(position).setSelected(false);
}else{
dataList.get(position).setSelected(true);
}
/**
* 通知适配器,绑定的数据发生了改变,应当刷新视图
*/
adapter.notifyDataSetChanged();
}
});
}
/**
* 继承BaseAdapter,实现的一个适配器,用来绑定数据源和gridview
*/
class GridAdapter extends BaseAdapter{
@Override
public int getCount() {
int count = 0;
if(dataList!=null){
count = dataList.size();
}
return count;
}
@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) {
/**
* 这里解析Gridview的子view的布局,然后根据绑定实体类的属性,来显示图片和选中状态
* 其实这里写的不太规范,在真正的项目中,这里的视图解析应该用到ViewHolder来做视图缓存,达到性能优化的目的。
* 因为写的匆忙,就先不做ViewHolder的示范了,不过做项目时要注意。
*/
convertView = LayoutInflater.from(getApplicationContext()).inflate(R.layout.item, null);
ImageView image = (ImageView)convertView.findViewById(R.id.image);
ImageView selectImage = (ImageView)convertView.findViewById(R.id.isselected);
image.setImageResource(dataList.get(position).getImageUri());
if(dataList.get(position).isSelected()){
selectImage.setVisibility(View.VISIBLE);
}else{
selectImage.setVisibility(View.GONE);
}
return convertView;
}
}
}
至此一个简单的小demo就完成了,我把项目的源代码也传上来,大家可以下载源代码直接调试。
Demo下载地址:http://download.csdn.net/detail/pringlee2011/5895687