GridView的细节
在安卓开发中我们经常会用到GridView控件,它与ListView的最大区别就在与可以并列显示多行的集合型数据,可以理解为多个ListView的并列,下面从与ListView的分别入手分析
布局文件中的申明:
<!-- 与ListView多了 numColumns 属性,为显示的列数,另外增加有水平和垂直边距 -->
<GridView
android:id="@+id/GV_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:horizontalSpacing="2dip"
android:numColumns="2"
android:verticalSpacing="2dip" >
</GridView>
Activity中GridView的初始化
gv_list.setAdapter(new MyAdapter());
private class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return list.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if(convertView==null){
//Adapter的fast way
convertView = View.inflate(MainActivity.this, R.layout.item_gridview, null);
holder = new ViewHolder();
holder.iv_icon = (ImageView) convertView.findViewById(R.id.item_iv_icon);
holder.tv_title = (TextView) convertView.findViewById(R.id.item_tv_title);
holder.tv_desc = (TextView) convertView.findViewById(R.id.item_tv_desc);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
Bean bean = list.get(position);
holder.iv_icon.setImageResource(bean.getIcon());
holder.tv_title.setText(bean.getTitle());
holder.tv_desc.setText(bean.getDesc());
return convertView;
}
}
//持有者
static private class ViewHolder{
ImageView iv_icon;
TextView tv_title;
TextView tv_desc;
}
GridView的item布局
<?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:layout_centerVertical="true"
android:id="@+id/item_iv_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher" />
<LinearLayout
android:layout_centerVertical="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="@id/item_iv_icon"
android:gravity="center_vertical"
android:orientation="vertical" >
<TextView
android:id="@+id/item_tv_title"
android:textSize="16sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="标题" />
<TextView
android:id="@+id/item_tv_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="描述"
android:textColor="#88000000"/>
</LinearLayout>
</RelativeLayout>
添加条目的点击事件
gv_list.setOnItemClickListener(new MyListener());
private class MyListener implements OnItemClickListener{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
Toast.makeText(MainActivity.this, "您点击了条目"+position, 0).show();
}
}
效果图
这样的UI有点丑,为了提高用户的体验,我们经常会添加选择背景selector
下面是正确的代码
首先 新建selector
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/antispam_report_button_press" android:state_pressed="true"></item>
<item android:drawable="@drawable/antispam_report_button"></item>
</selector>
接下来,在GridView的条目中 添加background 属性中选择此 selector
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/item_selector">
详细解析过程中容易出现的细节错误
GridView中的item点击无效
错误代码
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:background="@drawable/item_selector">
效果图
分析
仅仅是因为在item的主布局中我们添加了 android:clickable=”true” 属性,本来在其他地方是没有问题,在单个布局中添加这个才会有 selector 的效果,但是现在这是GridView中的item布局,在GridView设置点击事件后,就会出现冲突,作为GridView的条目,设置点击事件之后就会有被点击的属性,这时添加可点击的属性,就不会响应GridView的点击事件了。ListView也有相关的特性
selector选择器的无效
错误代码
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/antispam_report_button"></item>
<item android:drawable="@drawable/antispam_report_button_press" android:state_pressed="true"></item>
</selector>
效果图————————我的模拟器很渣,toast的显示会持续很长的时间
分析
关于selector中item的位置是有要求的,只是因为你将pressed的状态放在了下面,这其实与xml的解析顺序有关,为从上而下的解析,原因很简单,你把所有的情况放在了上面,pressed状态只是其中的一种,不管什么时候,都不会执行到下面的代码