在Android应用程序开发中,我们经常用到ListView这个控件,可能大家会对方方正正的ListView控件感到厌烦,这里来实现圆角的ListView,并放在ScrollView控件中。实现类如下图这种效果,如图 这里我们沿用Android系统的MVC软件设计模式。首先,在res/drawable文件夹下新建一个listview_round_corner_bg.xml文件,作为ListView的背景,代码如下: <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!--圆角 -->
<corners
android:radius="8dp"
/>
<!-- 背景填充 -->
<solid
android:color="@color/white"
/>
<!-- 描边 -->
<stroke
android:width="1dp"
android:color="@color/gray"
/>
</shape>
我们点击ListView的Item时,需要设计四种情况: 1.只有一项,那么上下左右四个角都要是圆角,新建一个listview_round_corner_selector.xml <?xml version="1.0" encoding="UTF-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 按下时背景图片 -->
<item
android:state_pressed="true"
android:drawable="@drawable/listview_round_corner_shape_pressed"
/>
<!-- 默认是背景图片 -->
<item
android:drawable="@drawable/listview_round_corner_shape_normal"
/>
</selector>
其中用到的listview_round_corner_shape_pressed.xml: <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!--圆角 -->
<corners
android:radius="8dp"
/>
<!-- 背景填充 -->
<solid
android:color="@color/gray"
/>
<!-- 描边 -->
<stroke
android:width="1dp"
android:color="@color/gray"
/>
</shape>
另一个listview_round_corner_shape_normal.xml: <?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<!--圆角 -->
<corners
android:radius="8dp"
/>
<!-- 背景填充 -->
<solid
android:color="@color/white"
/>
<!-- 描边 -->
<stroke
android:width="1dp"
android:color="@color/gray"
/>
</shape>
2.不止一项的时候,当点击第一项时候,应该是左上角和右上角圆角 3.不止一项的时候,当点击中间某一项时候,应该是没有圆角 4.不止一项的时候,当点击最后一项时候,应该是左下角和右下角圆角 后面三种情况代码就不在这里贴出来了,详见附加文件 好了,到这里我们再继承一下Listview控件,创建一个自己的ListView控件,override一下onInterceptTouchEvent这个函数 public class RoundCornerListView extends ListView{
public RoundCornerListView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public RoundCornerListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
/**
* @param context
* @param attrs
*/
public RoundCornerListView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}
/****
* 拦截触摸事件
*/
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) ev.getX();
int y = (int) ev.getY();
int itemnum = pointToPosition(x, y);
if (itemnum == AdapterView.INVALID_POSITION)
break;
else{
if(itemnum==0){
if(itemnum==(getAdapter().getCount()-1)){
setSelector(R.drawable.listview_round_corner_selector);//上面的第一种情况
}else{
setSelector(R.drawable.listview_round_corner_top_selector);//第二种情况
}
}else if(itemnum==(getAdapter().getCount()-1))
setSelector(R.drawable.listview_round_corner_bottom_selector);//第四种情况
else{
setSelector(R.drawable.listview_round_corner_medium_selector);//第三种情况
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
return super.onInterceptTouchEvent(ev);
}
}
然后用这个RoundCornerListView控件创建属于自己的ListView,到此为止我们已经解决了ListView的圆角显示问题,现在来解决在ScrollView中显示ListView的问题,我们都知道这两个控件是“死敌”,解决的办法就是动态设置ListView的大小: /***
* 动态设置listview的高度
*
* @param listView
*/
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
// params.height += 5;// if without this statement,the listview will be
// a
// little short
// listView.getDividerHeight()获取子项间分隔符占用的高度
// params.height最后得到整个ListView完整显示需要的高度
listView.setLayoutParams(params);
}
在ListView设置setAdapter以后调用这个函数就ok了。 注意,在这里有个问题就是假如我们调用的ListView中Item是系统自带的话,例如:android.R.layout.simple_expandable_list_item_1这个Item,调用上面的函数时候会显示不正确,应该是检测Height时候不正确,所以这里我们自己写了一个listview_item.xml: <?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/text1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:gravity="center_vertical"
android:textColor="#000000"
android:paddingLeft="30dip"
android:minHeight="?android:attr/listPreferredItemHeight"
/>
|