CardView在API 21以下的圓角效果處理

CardView是Android5.0(API 21)加入的新控件,當(dāng)然,在API 21以下也能用,在build.gradle的依賴?yán)锛尤胂逻呉恍芯涂梢杂昧?/p>

compile 'com.android.support:cardview-v7:23.1.1'

項(xiàng)目中要做一個(gè)卡片瀏覽的程序,卡片需要有5dp的圓角,圓角效果CardView自帶屬性就可以支持,加上app:cardCornerRadius屬性就好了,如下:

<android.support.v7.widget.CardView
  xmlns:android="http://schemas.android.com/apk/res/android"  
  xmlns:app="http://schemas.android.com/apk/res-auto"    
  android:layout_width="match_parent"    
  android:layout_height="wrap_content"    
  app:cardUseCompatPadding="true"    
  app:cardCornerRadius="5dp">
  ...
</android.support.v7.widget.CardView>

在API 21以上(包括)的機(jī)器實(shí)現(xiàn)了很完美的圓角效果,效果如下:

但是在API 21以下的機(jī)器出現(xiàn)了問題,以下是API 19的實(shí)現(xiàn)效果:

初步一看,雖然加上了圓角屬性,但是圖片邊上是方的。將左下角和左上角放大仔細(xì)看下:

可以看到,CardView本身是圓角效果了,但是里邊的內(nèi)容卻還是方的,并且出現(xiàn)了多余的白邊。
再仔細(xì)查看CardView的文檔,發(fā)現(xiàn)其有一個(gè)屬性cardPreventCornerOverlap

<!-- Add padding to CardView on v20 and before to prevent intersections between the Card content and rounded corners. --> 
<!-- 在v20和之前的版本中添加內(nèi)邊距,這個(gè)屬性是為了防止卡片內(nèi)容和邊角的重疊 -->
 <attr name="cardPreventCornerOverlap" format="boolean" />

cardPreventCornerOverlap默認(rèn)為true,意思是阻止API 20或者之前的CardView的corner和內(nèi)部元素重疊。沒有重疊就產(chǎn)生了上邊的效果,多了一條白邊。于是在xml布局文件里增加CardView的屬性app:cardPreventCornerOverlap="false",左下角和左上角效果如下:

可以看到,CardView里的元素已經(jīng)和CardView重疊了,但是元素本身沒有圓角,所以頂點(diǎn)伸出去了。到這里思路就很簡單了,將里邊的元素單獨(dú)做圓角處理。

drawable下新建shape_radius.xml文件,代碼如下:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <corners android:radius="5dp" />
    <solid android:color="@color/f2f2f2"></solid>
</shape>

在CardView里的元素LinearLayout加上backgroud屬性

<LinearLayout android:layout_width="match_parent" 
    android:layout_height="match_parent"
    android:orientation="vertical" 
    android:background="@drawable/shape_radius" >
    <ImageView    
      android:id="@+id/iv_header"    
      android:layout_width="match_parent"    
      android:layout_height="wrap_content"    
      android:layout_gravity="center_horizontal"    
      android:adjustViewBounds="true"    
      android:scaleType="fitCenter"    
      android:src="@drawable/ic_person_default"/>
</LinearLayout>

左下角正常,左上角依然

圖片還需要單獨(dú)做圓角處理,這里需要的效果是,圖片的上邊兩個(gè)角需要圓角,下邊兩個(gè)角需要直角。
自定義UpRoundImageView類,繼承自ImageView,專門做圓角的繪制,代碼如下:

public class UpRoundImageView extends ImageView {

    private float mRadus = 5 * SystemUtils.getDensity(CampusApplication.getCampusApplicationContext());
    
    /*圓角的半徑,依次為左上角xy半徑,右上角,右下角,左下角*/
    private float[] rids = {mRadus, mRadus, mRadus, mRadus, 0.0f,0.0f,0.0f,0.0f};

    public UpRoundImageView(Context context) {
        super(context);
    }

    public UpRoundImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public UpRoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }


    /**
     * 畫圖
     * @param canvas
     */
    protected void onDraw(Canvas canvas) {
        Path path = new Path();
        int w = this.getWidth();
        int h = this.getHeight();
        /*向路徑中添加圓角矩形。radii數(shù)組定義圓角矩形的四個(gè)圓角的x,y半徑。radii長度必須為8*/
        path.addRoundRect(new RectF(0,0,w,h),rids,Path.Direction.CW);
        canvas.clipPath(path);
        super.onDraw(canvas);
    }
}

將ImageView替換成UpRoundImageView, 這樣就實(shí)現(xiàn)了全部圓角效果。
另外,可以在CardView加上app:cardElevation="3dp"屬性,這個(gè)屬性加上后可以在CardView后形成一個(gè)陰影,有卡片浮上來的感覺,更符合Material Design風(fēng)格。 xml中CardView的屬性設(shè)置為

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:cardUseCompatPadding="true"
    app:cardCornerRadius="5dp"
    app:cardPreventCornerOverlap="false"
    app:cardElevation="3dp">
    ...
</android.support.v7.widget.CardView>

最后實(shí)現(xiàn)效果在各個(gè)平臺(tái)一致:

api 19實(shí)現(xiàn)效果


api 19實(shí)現(xiàn)效果

api 22實(shí)現(xiàn)效果


api 22實(shí)現(xiàn)效果
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,351評(píng)論 25 708
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,688評(píng)論 4 61
  • 轉(zhuǎn)載注明出處:http://m.itdecent.cn/p/818e1284158d 1. 概述 Androi...
    王三的貓阿德閱讀 10,709評(píng)論 10 49
  • 伽藍(lán)寺,一位衣衫青素的僧人閉著眼睛虔誠的敲打著木魚。灰蒙蒙的天空飄著細(xì)細(xì)的小雨,老僧人緩緩的睜開眼睛,看著絲絲細(xì)雨...
    唐半仙閱讀 447評(píng)論 5 9
  • 一、NSDate 1.NSDate對(duì)象用來表示一個(gè)具體的時(shí)間點(diǎn)。 2.NSDate是一個(gè)類簇,我們所使用的NSDa...
    hAo_JS閱讀 1,165評(píng)論 0 1

友情鏈接更多精彩內(nèi)容