Android 实现圆角ListView 几种方法

本文探讨了在Android中创建圆角ListView的多种方法,包括处理选中项直角问题,自定义selector,以及结合不同策略实现理想效果。详细介绍了每个方法的优缺点和应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法一:定义
<?xml version ="1.0" encoding ="UTF-8" ?> 
<shape xmlns:android ="http://schemas.android.com/apk/res/android" android:shape ="rectangle" > 
       <gradient android:startColor ="#B0BCCD" android:endColor ="#6D84A2" android:angle ="270" /> 
       <corners android:bottomRightRadius ="8dp" android:bottomLeftRadius ="8dp" android:topLeftRadius ="8dp" 
              android:topRightRadius ="8dp" /> 

</shape> 


布局文件中的ListView属性android:listSelector="@drawable/shape"

存在问题是,ListView最上面或者最下面的item选中时,圆角背景变成直角的

方法二:修改选中item 

public class RoundedRectListView extends ListView {   
        private Context mContext; 
        public RoundedRectListView( Context context) { 
                super ( context) ;         
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs) { 
                super ( context, attrs) ; 
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs, int defStyle) { 
                super ( context, attrs, defStyle) ; 
                this .mContext = context; 
                init( ) ; 
        } 
        protected void init( ) { 
                setBackgroundDrawable( mContext.getResources ( ) .getDrawable ( R.drawable .background_rounded_white ) ) ; 
                setCacheColorHint( Color .WHITE ) ; 
                setFooterDividersEnabled( false ) ; 
        } 
        @Override
        public boolean onInterceptTouchEvent( MotionEvent ev) { 
 
                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_selection_shade_rounded ) ; 
                                        else 
                                                setSelector( R.drawable .listview_selection_shade_top_rounded ) ; 
                                } 
                                else if ( itemnum== ( getAdapter( ) .getCount ( ) - 1) ) 
                                        setSelector( R.drawable .listview_selection_shade_bottom_rounded ) ; 
                                else 
                                        setSelector( R.drawable .listview_selection_shade ) ;                       
                        } 
                        break ; 
                case MotionEvent.ACTION_UP : 
                        break ; 
                } 
                return true ;     
        }       
} 


 

方法三:定义selector

public class RoundedRectListView extends ListView {     
        private Context mContext; 
 
        public RoundedRectListView( Context context) { 
                super ( context) ;         
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs) { 
                super ( context, attrs) ; 
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs, int defStyle) { 
                super ( context, attrs, defStyle) ; 
                this .mContext = context; 
                init( ) ; 
        } 
        protected void init( ) { 
                setBackgroundDrawable( mContext.getResources ( ) .getDrawable ( R.drawable .background_rounded_white ) ) ; 
                setCacheColorHint( Color .WHITE ) ; 
                setFooterDividersEnabled( false ) ; 
        } 
        @Override
        public boolean onInterceptTouchEvent( MotionEvent ev) { 
 
                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_selection_shade_rounded ) ; 
                                        else 
                                                setSelector( R.drawable .listview_selection_shade_top_rounded ) ; 
                                } 
                                else if ( itemnum== ( getAdapter( ) .getCount ( ) - 1) ) 
                                        setSelector( R.drawable .listview_selection_shade_bottom_rounded ) ; 
                                else 
                                        setSelector( R.drawable .listview_selection_shade ) ;                       
                        } 
                        break ; 
                case MotionEvent.ACTION_UP : 
                        break ; 
                } 
                return true ;     
        }       
}


 

方法四:方法二和方法三的结合

public class RoundedRectListView extends ListView {   

        private Context mContext; 
 
        public RoundedRectListView( Context context) { 
                super ( context) ;         
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs) { 
                super ( context, attrs) ; 
                this .mContext = context; 
                init( ) ; 
        } 
        public RoundedRectListView( Context context, AttributeSet attrs, int defStyle) { 
                super ( context, attrs, defStyle) ; 
                this .mContext = context; 
                init( ) ; 
        } 
       protected void init( ) { 
                setBackgroundDrawable( mContext.getResources ( ) .getDrawable ( R.drawable .background_rounded_white ) ) ; 
                setCacheColorHint( Color .WHITE ) ; 
                setFooterDividersEnabled( false ) ;         
                setSelector( new Selector( RoundedRectListView.this ,- 1) ) ; 
        } 
   @Override
        public boolean onInterceptTouchEvent( MotionEvent ev) { 
                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 
                        {               
                           setSelector( new Selector( RoundedRectListView.this ,itemnum) ) ;                 
                        } 
                        break ; 
                case MotionEvent.ACTION_UP : 
                        break ; 
                } 
                return true ;     
        } 
    class Selector extends Drawable { 
        private static final String TAG = "Selector" ; 
        private Paint mPaint; 
        private AdapterView mList; 
        private RectF mRectF; 
        private int position; 
        
        public Selector( AdapterView list,int position) { 
            mList = list; 
            mPaint = new Paint ( ) ; 
            mRectF = new RectF( ) ; 
            this .position = position 

            LinearGradient g= new LinearGradient( mRectF.top ,mRectF.left ,mRectF.right ,mRectF.bottom ,Color .parseColor ( "#058cf5" ) ,Color .parseColor ( "#015fe6" ) ,TileMode.REPEAT ) ;   

    mPaint.setShader ( g) ; 
        } 
        @Override
        public void draw( Canvas canvas) { 
            Rect b = getBounds( ) ; 
            int mPosition = mList.getSelectedItemPosition ( ) ; 
            if ( mPosition==- 1) { 
                mPosition= position; 
            } 
            Log.d ( TAG, "Position :" + mPosition) ; 
            canvas.save ( ) ; 
            canvas.clipRect ( b.left , b.top , b.right , ( b.bottom + b.top ) / 2) ; 
            drawHalf( canvas, b, mPosition == 0) ; 
            canvas.restore ( ) ; 
            canvas.save ( ) ; 
            canvas.clipRect ( b.left , ( b.bottom + b.top ) / 2, b.right , b.bottom ) ; 
            drawHalf( canvas, b, mPosition == mList.getAdapter ( ) .getCount ( ) - 1 && b.bottom == mList.getHeight ( ) ) ; 
            canvas.restore ( ) ; 
            Log.d ( TAG, "draw " + b) ; 
        } 
        private void drawHalf( Canvas canvas, Rect b ,boolean round) {           
                
            if ( round) { 
                mRectF.set ( b) ; 
                canvas.drawRoundRect ( mRectF, 10, 10, mPaint) ;               
            } else { 
                canvas.drawRect ( b, mPaint) ;               
            } 
        } 
        @Override
        public int getOpacity( ) { 
            return 0 ; 
        } 
        @Override
        public void setAlpha( int alpha) { 
        } 
        @Override
        public void setColorFilter( ColorFilter cf) { 
        } 
    } 
}


 

方法五:

public class RoundedRectListView extends ListView { 
    private static final float RADIUS = 16 ; 
    private Path mClip; 
    public RoundedRectListView( Context context, AttributeSet attrs) { 
        super ( context, attrs) ; 
        init( ) ; 
    } 
    private void init( ) { 
        GradientDrawable gd = new GradientDrawable( ) ; 
        gd.setCornerRadius ( RADIUS) ; 
        gd.setColor ( 0xff208020) ; 
        setBackgroundDrawable( gd) ; 
        setCacheColorHint( 0) ; 
        setVerticalFadingEdgeEnabled( false ) ; 
        StateListDrawable sld = new StateListDrawable( ) ; 
        sld.addState ( 
                PRESSED_ENABLED_STATE_SET, 
                new GradientDrawable( Orientation.LEFT_RIGHT , new int [ ] { 0xffa58cf5, 0xffa13f99} ) ) ; 
        sld.addState ( 
                EMPTY_STATE_SET,
                new GradientDrawable( Orientation.LEFT_RIGHT , new int [ ] { 0xff058cf5, 0xff013f99} ) ) ; 
        setSelector( sld) ; 
    } 
    @Override
    protected void onSizeChanged( int w, int h, int oldw, int oldh) { 
        super .onSizeChanged ( w, h, oldw, oldh) ; 
        mClip = new Path( ) ; 
        RectF rect = new RectF( 0, 0, w, h) ; 
        mClip.addRoundRect ( rect, RADIUS, RADIUS, Direction.CW ) ; 
    } 
   @Override
    protected void dispatchDraw( Canvas canvas) { 
        canvas.save ( ) ; 
        canvas.clipPath ( mClip) ; 
        super .dispatchDraw ( canvas) ; 
        canvas.restore ( ) ; 
    } 
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值