ImageView in circular through xml

前端 未结 27 1292
死守一世寂寞
死守一世寂寞 2020-11-22 10:35

I\'d Like to make any image from my ImageView to be circular with a border.

I searched but couldn\'t find any useful information (anything that I tried

27条回答
  •  耶瑟儿~
    2020-11-22 10:46

    Actually, you can use what Google provides via the support library RoundedBitmapDrawableFactory class (here and here), instead of using a third party library :

    Gradle:

    implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
    

    MainActivity.kt

    class MainActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
            val originalDrawable = ContextCompat.getDrawable(this, R.drawable.avatar_1)!!
            val bitmap = convertDrawableToBitmap(originalDrawable)
            val drawable = RoundedBitmapDrawableFactory.create(resources, bitmap)
            drawable.setAntiAlias(true)
            drawable.cornerRadius = Math.max(bitmap.width, bitmap.height) / 2.0f
            avatarImageView.setImageDrawable(drawable)
        }
    
        companion object {
            @JvmStatic
            fun convertDrawableToBitmap(drawable: Drawable): Bitmap {
                if (drawable is BitmapDrawable)
                    return drawable.bitmap
                // We ask for the bounds if they have been set as they would be most
                // correct, then we check we are  > 0
                val bounds = drawable.bounds
                val width = if (!bounds.isEmpty) bounds.width() else drawable.intrinsicWidth
                val height = if (!bounds.isEmpty) bounds.height() else drawable.intrinsicHeight
                // Now we check we are > 0
                val bitmap = Bitmap.createBitmap(if (width <= 0) 1 else width, if (height <= 0) 1 else height,
                        Bitmap.Config.ARGB_8888)
                val canvas = Canvas(bitmap)
                drawable.setBounds(0, 0, canvas.width, canvas.height)
                drawable.draw(canvas)
                return bitmap
            }
        }
    }
    

    res/layout/activity_main.xml

    
    
        
    
    
    

    res/drawable/avatar_1.xml

    
        
        
        
        
        
        
    
    

    The result:

    And, suppose you want to add a border on top of it, you can use this for example:

    stroke_drawable.xml

    
        
    
    

    And add android:foreground="@drawable/stroke_drawable" to the ImageView in the layout XML file, and you get this :

    I'm not sure how to add shadow (that will work on older Android versions), though. Using FloatingActionButton (from the "com.google.android.material:material" dependency), I failed to make the bitmap fill the FAB itself. Using it instead could be even better if it worked.


    EDIT: if you wish to add shadow of elevation (available from API 21), you can change a bit what I wrote:

    Inside the layout XML file:

    
    

    CircularShadowViewOutlineProvider.kt

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    class CircularShadowViewOutlineProvider : ViewOutlineProvider() {
        override fun getOutline(view: View, outline: Outline) {
            val size = Math.max(view.width, view.height)
            outline.setRoundRect(0, 0, size, size, size / 2f)
        }
    }
    

    In code:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
            avatarImageView.outlineProvider = CircularShadowViewOutlineProvider()
    

    Result:

提交回复
热议问题