【问题标题】:How to draw border on BottomNavigation MenuItem Icon?如何在底部导航菜单项图标上绘制边框?
【发布时间】:2022-01-13 08:38:34
【问题描述】:

我正在开发一个 android 应用程序:

  • Jetpack 生命周期 (ViewModel)
  • 喷气背包导航
  • 线圈(图像加载器)

我正在尝试自定义 BottomNavigationMenu。

但有一件事是很难的……

最后一个标签是带边框的用户个人资料图片。

如果用户的头像背景颜色是白色的,那么用户界面就很奇怪。 所以我应该显示边框。

class MainActivity {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        initBottomNav(binding.bottomNav)
        vm.initProfileBottomIcon()
    }

    private fun initBottomNav(bottomNav: BottomNavigationView) {
        val navHostFragment = supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
        bottomNav.setupWithNavController(navHostFragment.navController)
        bottomNav.itemIconTintList = null

        vm.profileImgUrl.observe(this) { url ->
            bottomNav.menu.findItem(R.id.profileFragment).load(this, url) {
                transformations(CircleCropTransformation())
            }
        }
    }
}

此代码在 BottomNavigationMenu 上绘制个人资料图像。 但不画边框。

当我在谷歌上搜索时,不支持带边框的 CircleCrop(甚至 Glide)。

所以我尝试了下面的代码,但是效果不佳..

vm.profileImg.observe(this) { imgBitmap ->
    val layerBorder = ResourcesCompat.getDrawable(resources, R.drawable.oval_trans_border1_red, null)
    val layerIcon = BitmapDrawable(Resources.getSystem(), imgBitmap)
    val layerDrawable = LayerDrawable(arrayOf(layerIcon, layerBorder))

    val bottomNavProfile = bottomNav.menu.findItem(R.id.profileFragment)
    val request = ImageRequest.Builder(this)
        .data(layerDrawable)
        .target {
            bottomNavProfile.icon = it
        }
        .apply {
            transformations(CircleCropTransformation())
        }
        .build()
    imageLoader.enqueue(request)
}

有人帮帮我吗?

【问题讨论】:

  • 当您加载profileImg 时,您可以使用转换来添加边框。它会给你一个 Drawable/Bitmap 。你试过这种方式吗?如果没有可用的转换,您可以创建一个 .在谈论 Glide 时,您只需修改 Circular Transformation 类应该不难。类似This.

标签: android navigation android-glide coil


【解决方案1】:

您可以像这样编写自己的带有边框的转换:

class BorderedCircleCropTransformation(
    private val borderSize: Float = 0f,
    @ColorInt private val borderColor: Int = Color.BLUE
) : Transformation {

    override fun key(): String = BorderedCircleCropTransformation::class.java.name

    override suspend fun transform(pool: BitmapPool, input: Bitmap, size: Size): Bitmap {
        val borderOffset = (borderSize * 2).toInt()
        val halfWidth = input.width / 2
        val halfHeight = input.height / 2
        val circleRadius = Math.min(halfWidth, halfHeight).toFloat()
        val newBitmap = Bitmap.createBitmap(
            input.width + borderOffset,
            input.height + borderOffset,
            Bitmap.Config.ARGB_8888
        )

        // Center coordinates of the image
        val centerX = halfWidth + borderSize
        val centerY = halfHeight + borderSize

        val paint = Paint()
        val canvas = Canvas(newBitmap).apply {
            // Set transparent initial area
            drawARGB(0, 0, 0, 0)
        }

        // Draw the transparent initial area
        paint.isAntiAlias = true
        paint.style = Paint.Style.FILL
        canvas.drawCircle(centerX, centerY, circleRadius, paint)

        // Draw the image
        paint.xfermode = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
        canvas.drawBitmap(input, borderSize, borderSize, paint)

        // Draw the createBitmapWithBorder
        paint.xfermode = null
        paint.style = Paint.Style.STROKE
        paint.color = borderColor
        paint.strokeWidth = borderSize
        canvas.drawCircle(centerX, centerY, circleRadius, paint)
        return newBitmap
    }

    override fun equals(other: Any?) = other is BorderedCircleCropTransformation

    override fun hashCode() = javaClass.hashCode()

    override fun toString() = "BorderedCircleCropTransformation()"

    private companion object {
        val XFERMODE = PorterDuffXfermode(PorterDuff.Mode.SRC_IN)
    }
}

internal val Bitmap.safeConfig: Bitmap.Config
    get() = config ?: Bitmap.Config.ARGB_8888

然后将它作为转换传递给线圈,它会画出你想要的东西。 我使用this code 绘制边框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-05-09
    • 1970-01-01
    • 2020-04-29
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 1970-01-01
    相关资源
    最近更新 更多