Android圆角ListView并完美解决和ScrollView共存问题

 在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"

/>







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值