2014-02-28 132 views
100

我想使我的ImageView中的任何圖像具有邊框的圓形。通過xml循環的ImageView

我搜索,但無法找到任何有用的信息(我嘗試過的任何東西都不起作用)。

如何通過xml實現此目標: 使用特定的src創建ImageView並使其具有邊框的圓形?

+0

如何在java代碼中更改ImageView的src? – chenzhongpu

+0

好簡單的解決方案在這裏http://stackoverflow.com/a/28096369/2162226 - 全部用Java,所以你可以在運行時動態地將這種格式應用於圖像 – gnB

回答

141

你可以用白色邊框和透明的形狀做一個簡單的圓形。

// res/drawable/circle.xml 

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:innerRadius="0dp" 
    android:shape="ring" 
    android:thicknessRatio="1.9" 
    android:useLevel="false" > 
    <solid android:color="@android:color/transparent" /> 

    <stroke 
     android:width="10dp" 
     android:color="@android:color/white" /> 
</shape> 

然後創建一個可繪製的圖層列表,並將其作爲背景添加到您的圖像視圖中。

// res/drawable/img.xml 

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:drawable="@drawable/ic_launcher"/> 
    <item android:drawable="@drawable/circle"/> 

</layer-list> 

並把它作爲背景到你的imageview。

<ImageView 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:background="@drawable/img"/> 

你會有這樣的事情。

enter image description here

+5

然後我將該形狀設置爲我的imageview背景?我試過了,但沒有奏效。我的圖像仍然是長方形的:( – user3050910

+0

你有一個矩形圖像,你想圍繞它像一個圓形? –

+1

是的,使用XML,因爲使用java代碼是非常昂貴的移動。圖像,而不是圖像本身是一個圓圈,我認爲是爲了邊框,我想讓圖像在這個圓圈內圓角倒圓 – user3050910

4

我使用形狀= 「橢圓形」,而不是下面的 「環」。它爲我工作。爲了保持圖像的範圍,我使用<padding>並在我的<ImageView>中將<adjustViewBounds>設置爲true。我已經嘗試過尺寸在50 x 50 px到200x200 px之間的圖像。

+5

更改你能舉一個你如何做的例子嗎? –

21

如果您使用src屬性,上述方法似乎不起作用。我所做的是把兩個影像觀點的幀結構裏面一個在另一個上是這樣的:

<FrameLayout android:id="@+id/frame" 
      android:layout_width="40dp" 
      android:layout_height="40dp"> 

    <ImageView android:id="@+id/pic" 
       android:layout_width="40dp" 
       android:layout_height="40dp" 
       android:src="@drawable/my_picture" /> 

    <ImageView android:id="@+id/circle_crop" 
       android:layout_width="40dp" 
       android:layout_height="40dp" 
       android:src="@drawable/circle_crop" /> 

</FrameLayout> 

簡單地講了circular_crop.png在繪製文件夾位於圖像尺寸的形狀(方形我案例),中間有一個白色的背景和一個透明的圓圈。如果你想要一個正方形的圖像視圖,你可以使用這個圖像。

Round image

只需下載上面的圖片。

+2

最佳解決方案!最棒的表演。改變位圖是內存問題 – itzhar

+3

這隻適用於白色背景? – Kishore

+0

這個樣本圖像是白色的,所以是的。但是你可以用任何顏色創建你自己的圖像,或者下載這個圖像並改變它的顏色。 –

2

這將這樣的伎倆:

rectangle.xml

<?xml version="1.0" encoding="UTF-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:shape="rectangle"> 
    <solid android:color="@android:color/transparent" /> 
    <padding android:bottom="-14dp" android:left="-14dp" android:right="-14dp" android:top="-14dp" /> 

</shape> 

circle.xml

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
    android:innerRadius="0dp" 
    android:shape="oval" 

    android:useLevel="false" > 
    <solid android:color="@android:color/transparent" /> 

    <stroke 
     android:width="15dp" 
     android:color="@color/verification_contact_background" /> 

</shape> 

profile_image.xml(該layerlist)

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" > 

    <item android:drawable="@drawable/rectangle" /> 
    <item android:drawable="@drawable/circle"/> 

</layer-list> 

您的佈局

<ImageView 
     android:id="@+id/profile_image" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@drawable/default_org" 
     android:src="@drawable/profile_image"/> 
+0

什麼是default_org? –

+0

這可以是任何佔位符圖像 – Nidhi

+0

在這種情況下,矩形尺寸圖像的邊緣將跨過圓的邊界。我如何精確定位每個圖像,每個維度和形式,在圓內? –

134

這是

我設計的最簡單的方法

。嘗試這個。

dependencies: compile 'com.android.support:appcompat-v7:23.1.1' 
       compile 'com.android.support:design:23.1.1' 
       compile 'com.android.support:cardview-v7:23.1.1' 

<android.support.v7.widget.CardView 
    android:layout_width="80dp" 
    android:layout_height="80dp" 
    android:elevation="12dp" 
    android:id="@+id/view2" 
    app:cardCornerRadius="40dp" 
    android:layout_centerHorizontal="true" 
    android:innerRadius="0dp" 
    android:shape="ring" 
    android:thicknessRatio="1.9"> 
    <ImageView 
     android:layout_height="80dp" 
     android:layout_width="match_parent" 
     android:id="@+id/imageView1" 
     android:src="@drawable/YOUR_IMAGE" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true"> 
    </ImageView> 
</android.support.v7.widget.CardView> 
+3

這裏不錯的創意。 –

+1

謝謝你。內存使用簡單,容易。到目前爲止,我嘗試過的庫在使用RecyclerView項目中的自定義視圖時都會給出OOMException。 – COBB

+1

最好的解決方案,只有在設計期間不要預覽它。 –

51

我希望這可能對您有所幫助。

enter image description here

<de.hdodenhof.circleimageview.CircleImageView 
     xmlns:app="http://schemas.android.com/apk/res-auto" 
     android:id="@+id/profile_image" 
     android:layout_width="120dp" 
     android:layout_height="120dp" 
     android:layout_centerHorizontal="true" 
     android:layout_centerVertical="true" 
     android:src="@drawable/your_picture" 
     app:border_color="@color/white" 
     app:border_width="3dp" /> 

注意:在你的項目中,打開your_app>搖籃腳本>的build.gradle(模塊:應用程序),並添加下面的執行語句的依賴關係{}

 compile 'de.hdodenhof:circleimageview:2.2.0' 

如需查看完整描述,請查看:The Source here.

+6

我不知道爲什麼人們討厭第三方 –

+1

如何將灰色部分更改爲白色? –

+2

自發布以來發生了更新。 border_colour和border_width已被重命名。檢查github頁面的更多信息:https://github.com/hdodenhof/CircleImageView – rharvey

4

glide庫和RoundedBitmapDrawableFactory類很容易實現。您可能需要創建循環的佔位符圖像。

Glide.with(context) 
     .load(imgUrl) 
     .asBitmap() 
     .placeholder(R.drawable.placeholder) 
     .error(R.drawable.placeholder) 
     .into(new BitmapImageViewTarget(imgProfilePicture) { 
      @Override 
      protected void setResource(Bitmap resource) { 
       RoundedBitmapDrawable drawable = RoundedBitmapDrawableFactory.create(context.getResources(), 
         Bitmap.createScaledBitmap(resource, 50, 50, false)); 
       drawable.setCircular(true); 
       imgProfilePicture.setImageDrawable(drawable); 
      } 
     }); 
+0

不知道你正在使用的這個例子是什麼版本的下滑,但與V4.0.0,你可以簡單地使用他們的RequestOptions代替RoundedBitmapDrawable的: '滑翔(context).load(imgUrl).apply(new RequestOptions()。centerCrop()) .into(imageView)' –

+0

新的RequestOptions()。circleCrop()).into(imageView)? – Androidz

11

下面是做到這一點,使用下面的代碼最簡單的方法之一:

依賴

dependencies { 
    ... 
    compile 'de.hdodenhof:circleimageview:2.1.0'  // use this or use the latest compile version. In case u get bug. 
} 

XML代碼

<de.hdodenhof.circleimageview.CircleImageView 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:id="@+id/profile_image" 
    android:layout_width="96dp"    // here u can adjust the width 
    android:layout_height="96dp"   // here u can adjust the height 
    android:src="@drawable/profile"   // here u can change the image 
    app:civ_border_width="2dp"    // here u can adjust the border of the circle. 
    app:civ_border_color="#FF000000"/>  // here u can adjust the border color 

截圖:

Screenshot

來源:Circular ImageView GitHub Repository

enter image description here

+1

不支持縮放類型。:( – Khan

0

使用下面的代碼,你可以修改它:

import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.Bitmap.Config; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PorterDuff.Mode; 
import android.graphics.PorterDuffXfermode; 
import android.graphics.Rect; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.util.AttributeSet; 
import android.widget.ImageView; 

public class RoundedImageView extends ImageView { 

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

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

    public RoundedImageView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 

     Drawable drawable = getDrawable(); 

     if (drawable == null) { 
      return; 
     } 

     if (getWidth() == 0 || getHeight() == 0) { 
      return; 
     } 
     Bitmap b = ((BitmapDrawable) drawable).getBitmap(); 
     Bitmap bitmap = b.copy(Bitmap.Config.ARGB_8888, true); 

     int w = getWidth(); 
     @SuppressWarnings("unused") 
     int h = getHeight(); 

     Bitmap roundBitmap = getCroppedBitmap(bitmap, w); 
     canvas.drawBitmap(roundBitmap, 0, 0, null); 

    } 

    public static Bitmap getCroppedBitmap(Bitmap bmp, int radius) { 
     Bitmap sbmp; 

     if (bmp.getWidth() != radius || bmp.getHeight() != radius) { 
      float smallest = Math.min(bmp.getWidth(), bmp.getHeight()); 
      float factor = smallest/radius; 
      sbmp = Bitmap.createScaledBitmap(bmp, 
        (int) (bmp.getWidth()/factor), 
        (int) (bmp.getHeight()/factor), false); 
     } else { 
      sbmp = bmp; 
     } 

     Bitmap output = Bitmap.createBitmap(radius, radius, Config.ARGB_8888); 
     Canvas canvas = new Canvas(output); 

     final String color = "#BAB399"; 
     final Paint paint = new Paint(); 
     final Rect rect = new Rect(0, 0, radius, radius); 

     paint.setAntiAlias(true); 
     paint.setFilterBitmap(true); 
     paint.setDither(true); 
     canvas.drawARGB(0, 0, 0, 0); 
     paint.setColor(Color.parseColor(color)); 
     canvas.drawCircle(radius/2 + 0.7f, radius/2 + 0.7f, 
       radius/2 + 0.1f, paint); 
     paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN)); 
     canvas.drawBitmap(sbmp, rect, rect, paint); 

     return output; 
    } 

} 
0

試試這個。

public class RoundedImageView extends android.support.v7.widget.AppCompatImageView { 

    private int borderWidth = 4; 
    private int viewWidth; 
    private int viewHeight; 
    private Bitmap image; 
    private Paint paint; 
    private Paint paintBorder; 
    private BitmapShader shader; 

    public RoundedImageView(Context context) 
    { 
     super(context); 
     setup(); 
    } 

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

    public RoundedImageView(Context context, AttributeSet attrs, int defStyle) 
    { 
     super(context, attrs, defStyle); 
     setup(); 
    } 

    private void setup() 
    { 
     paint = new Paint(); 
     paint.setAntiAlias(true); 

     paintBorder = new Paint(); 
     setBorderColor(Color.WHITE); 
     paintBorder.setAntiAlias(true); 
     this.setLayerType(LAYER_TYPE_SOFTWARE, paintBorder); 

     paintBorder.setShadowLayer(4.0f, 0.0f, 2.0f, Color.WHITE); 
    } 

    public void setBorderWidth(int borderWidth) 
    { 
     this.borderWidth = borderWidth; 
     this.invalidate(); 
    } 

    public void setBorderColor(int borderColor) 
    { 
     if (paintBorder != null) 
      paintBorder.setColor(borderColor); 

     this.invalidate(); 
    } 

    private void loadBitmap() 
    { 
     BitmapDrawable bitmapDrawable = (BitmapDrawable) this.getDrawable(); 

     if (bitmapDrawable != null) 
      image = bitmapDrawable.getBitmap(); 
    } 

    @SuppressLint("DrawAllocation") 
    @Override 
    public void onDraw(Canvas canvas) 
    { 
     loadBitmap(); 

     if (image != null) 
     { 
      shader = new BitmapShader(Bitmap.createScaledBitmap(image, canvas.getWidth(), canvas.getHeight(), false), Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); 
      paint.setShader(shader); 
      int circleCenter = viewWidth/2; 
      canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter + borderWidth - 4.0f, paintBorder); 
      canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, circleCenter - 4.0f, paint); 
     } 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) 
    { 
     int width = measureWidth(widthMeasureSpec); 
     int height = measureHeight(heightMeasureSpec, widthMeasureSpec); 

     viewWidth = width - (borderWidth * 2); 
     viewHeight = height - (borderWidth * 2); 

     setMeasuredDimension(width, height); 
    } 

    private int measureWidth(int measureSpec) 
    { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpec); 
     int specSize = MeasureSpec.getSize(measureSpec); 

     if (specMode == MeasureSpec.EXACTLY) 
     { 
      result = specSize; 
     } 
     else 
     { 
      // Measure the text 
      result = viewWidth; 
     } 

     return result; 
    } 

    private int measureHeight(int measureSpecHeight, int measureSpecWidth) 
    { 
     int result = 0; 
     int specMode = MeasureSpec.getMode(measureSpecHeight); 
     int specSize = MeasureSpec.getSize(measureSpecHeight); 

     if (specMode == MeasureSpec.EXACTLY) 
     { 
      result = specSize; 
     } 
     else 
     { 
      result = viewHeight; 
     } 

     return (result + 2); 
    } 
} 

,並在這樣的佈局使用的ImageView:

<com.app.Demo.RoundedImageView 
    android:id="@+id/iv_profileImage" 
    android:layout_width="70dp" 
    android:layout_height="70dp" 
    android:layout_centerHorizontal="true" 
    /> 
0

如奧爾罕Obut的答案,但與變化被描述:

<ImageView 
    android:layout_width="0dp" 
    android:layout_height="match_parent" 
    android:src="@drawable/img" 
    android:layout_weight="75" /> 

避免圖像的延伸。 而img.xml:

<?xml version="1.0" encoding="utf-8"?><layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
<item android:drawable="@drawable/profile" /> 
<item android:drawable="@drawable/circle" /></layer-list> 

(沒有改變),和circle.xml:

<shape xmlns:android="http://schemas.android.com/apk/res/android" 
android:innerRadiusRatio="2" 
android:shape="ring" 
android:thickness="300dp" 
android:useLevel="false"> 
<solid android:color="@android:color/white"/> 
<stroke 
    android:width="2dp" 
    android:color="@android:color/black"/> 
</shape> 

這裏的環的最大得到的厚度 - 1000dp
和radiusRatio是圖像寬度的一半(最大的戒指寬度,是嗎?) - 2
如果需要,筆畫是需要的邊框。
我用方形PNG圖像(profile.png),順便說一句。具有相同的寬度和高度。 這對任意ImageView尺寸都是正確的。 enter image description here