Android__ListView控件详解:http://jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1105/1906.html
ListView使用实例,需要更改的是选择的模式,是单选还是多选,还有默认样式以及一个自定义的样式。
lv = (ListView)findViewById(R.id.listView);
citys = getResources().getStringArray(R.array.str_citys);
citys = getResources().getStringArray(R.array.str_citys);
lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); //设定选择样式
arrayAdapter = new ArrayAdapter<CharSequence>(this,android.R.layout.simple_list_item_multiple_choice,citys); //相应这里也要对样式进行匹配选择
lv.setAdapter(
arrayAdapter);
关于
CHOICE_MODE_MULTIPLE 和
CHOICE_MODE_MULTIPLE_MODAL 的区别,官方的解释是这样的:
New CHOICE_MODE_MULTIPLE_MODAL
mode for setChoiceMode()
allows users to select multiple items from a ListView
or GridView
. When used in conjunction with the Action Bar, users can select multiple items and then select the action to perform from a list of options in the Action Bar (which has transformed into a Multi-choice Action Mode).
To enable multiple-choice selection, call
setChoiceMode(CHOICE_MODE_MULTIPLE_MODAL)
and register a
MultiChoiceModeListener
with
setMultiChoiceModeListener()
.
在网络上查到的是这样解释的:
CHOICE_MODE_MULTIPLE模式的特点在于他本身没有排斥性,在能选择item的情况下,也可以响应普通点击事件。为了解决这个问题 ,在android3.0之后增加了CHOICE_MODE_MULTIPLE_MODAL模式。
CHOICE_MODE_MULTIPLE_MODAL和CHOICE_MODE_MULTIPLE恰恰相反,他是对普通点击操作和多选操作是排斥的,一旦有一个item被选中,即进入到多选状态,item的onclick事件被屏蔽。这种排斥性也是他比CHOICE_MODE_MULTIPLE多了个MODAL的原因。此外CHOICE_MODE_MULTIPLE_MODAL还结合了android3.0的actionmode,当进入多选状态,actionbar的位置会显示新的菜单。
在我理解来就是modal状态下会对item的点击监听事件进行屏蔽,以满足不同条件下的需求。
说到ListView 就必须要介绍两种list的显示方式,一个是SimpleAdapter,一个是BaseAdapter。下面先介绍一下SimpleAdapter,
当我们在列表的每一项中需要显示不止一条信息,需要多条以及加个图片啥的,
1、就需要自己重新定义一下布局,
2、写一个SimpleAdapter对象,让SimpleAdapter对象和.xml布局文件绑定起来,
3、然后在MainActivity中把数据获取上,然后把数据给了adapter让他去封装,使用适配器将数据源和样式绑定在一起
4、之后用ListView对象和这个adapter绑定了就可以看到咯~。
而BaseAdapter的作用则是在为开发者提供了更多的实现可能方式,如果你要在每个item上增加一个按钮呢?如果是增加好多组件呢?这个时候就需要用到BaseAdapter了,想要实现这么特定的功能,当然就需要自主实现能多功能咯。
BaseAdapter的使用过程和SimpleAdapter的使用过程大致是相同的,不同的地方在于BaseAdapter的实现,
getCount()方法,返回的是要显示(或者说绘制)多大的item的个数,用数据的长度作为返回值。
View getView( int position , View convertView , ViewGroup parent){
//第一个参数是当前item的位置信息,第二个参数是不同item的显示View,在滑动过去后隐藏起来。第三个参数是父元素允许item的个数
ViewHolder holder = null;
if(convertView == null){
holder = new ViewHolder();
//这句一般会放在该类的构造方法里,就是为了要给convertView匹配一个外观样式,就可以匹配到自己写的样式了。
LayoutInflater inflater = LayoutInflater.from(context);
convertView = inflater.inflate(com.example.changyue.R.layout.contact_item, null);
//用holder来吧这些元素获取到,可以提高可复用性,当然也可以不用holder,那就得自己一个一个的敲类型对象然后从布局获取咯。
holder.img = (ImageView)convertView.findViewById(R.id.img);
holder.title = (TextView)convertView.findViewById(R.id.title);
holder.info = (TextView)convertView.findViewById(R.id.info);
holder.viewBtn = (Button)convertView.findViewById(R.id.view_btn);
//给该convertView绑定标签,算是一种优化。
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
//在这里要给holder里添加数据啦
holder.img.setBackgroundResource((Integer)mData.get(position).get(
"img"
));
holder.title.setText((String)mData.get(position).get(
"title"
));
holder.info.setText((String)mData.get(position).get(
"info"
));
//最后当然不能忘记返回
return convertView;
}
public
final
class
ViewHolder{
public
ImageView img;
public
TextView title;
public
TextView info;
public
Button viewBtn;
}
现在让我们回过头从新审视这个过程。系统要绘制ListView了,他首先获得要绘制的这个列表的长度,然后开始绘制第一行,怎么绘制呢?调用 getView()函数。在这个函数里面首先获得一个View(实际上是一个ViewGroup),然后再实例并设置各个组件,显示之。好了,绘制完这一 行了。那 再绘制下一行,直到绘完为止。在实际的运行过程中会发现listView的每一行没有焦点了,这是因为Button抢夺了listView的焦点,只要布局文件中将Button设置为没有焦点就OK了。