【问题标题】:Is there a way to add glow effect to a view, for example button or image view?有没有办法为视图添加发光效果,例如按钮或图像视图?
【发布时间】:2021-08-04 11:04:34
【问题描述】:

例如这个按钮:

我想让他像这样发光:

如何在不使用外部库按钮的情况下执行此操作?
另外,我真的很想知道如何在 ImageView 上执行此操作。我所能找到的只是使用不适合我的情况的库中的外部按钮和图像视图。

提前致谢!

按钮 XML 代码:

<com.google.android.material.button.MaterialButton
    android:id="@+id/btAddMyCard"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/add_another_my_card"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="24dp"
    android:layout_below="@id/topAppBar"
    style="@style/Widget.App.Button.OutlinedButton" />

【问题讨论】:

    标签: android android-studio android-layout android-xml


    【解决方案1】:

    虽然新的 Material 小部件非常实用,但它们被锁定,因此以非规定的方式自定义它们并不容易。我可以告诉你一种方法来完成你所需要的。

    我使用前景来绘制一个由两个圆角矩形组合而成的圆角矩形:一个非模糊矩形和一个使用BlurMaskFilter 模糊的矩形。我让按钮绘制一个指定的透明圆角矩形,所以它什么都不显示,但我使用笔划宽度来绘制圆角矩形,尽管这个值确实应该在自定义视图的自定义属性中指定。

    您可能需要根据自己的情况进行一些调整。

    如果你真的看不到光芒,这里是放大镜:

    此图像是从基于 MaterialButton 的自定义视图生成的。

    class MyMaterialGlowButton @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null
    ) : MaterialButton(context, attrs) {
        private val mPaddedRect = RectF()
        private val mBlurRadius = strokeWidth.toFloat() * BLUR_RADIUS_FACTOR
    
        private val mLinePaint = Paint().apply {
            isAntiAlias = true
            strokeWidth = this@MyMaterialGlowButton.strokeWidth.toFloat()
            style = Paint.Style.STROKE
            color = ROUNDED_RECT_COLOR
        }
    
        private val mBlurPaint = Paint().apply {
            isAntiAlias = true
            strokeWidth = this@MyMaterialGlowButton.strokeWidth.toFloat()
            style = Paint.Style.STROKE
            color = ROUNDED_RECT_COLOR
            maskFilter = BlurMaskFilter(mBlurRadius, BlurMaskFilter.Blur.NORMAL)
        }
    
        override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
            super.onSizeChanged(w, h, oldw, oldh)
            val halfStrokeWidth = strokeWidth.toFloat() / 2f
            mPaddedRect.left = halfStrokeWidth + mBlurRadius
            mPaddedRect.top = halfStrokeWidth + mBlurRadius
            mPaddedRect.right = w.toFloat() - halfStrokeWidth - mBlurRadius
            mPaddedRect.bottom = h.toFloat() - halfStrokeWidth - mBlurRadius
        }
    
        override fun onDrawForeground(canvas: Canvas?) {
            super.onDrawForeground(canvas)
            val corners = cornerRadius.toFloat()
            canvas?.drawRoundRect(mPaddedRect, corners, corners, mBlurPaint)
            canvas?.drawRoundRect(mPaddedRect, corners, corners, mLinePaint)
        }
    
        private companion object {
            const val ROUNDED_RECT_COLOR = 0xFF2b86e6.toInt()
            const val BLUR_RADIUS_FACTOR = 1.0f
        }
    }
    

    使用的 XML:

    <androidx.constraintlayout.widget.ConstraintLayout 
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <com.example.blurredline.MyMaterialGlowButton
            android:id="@+id/btAddMyCard"
            style="@style/Widget.App.Button.OutlinedButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="24dp"
            android:textAllCaps="false"
            android:insetLeft="4dp"
            android:insetRight="4dp"
            android:text="@string/add_another_my_card"
            app:cornerRadius="16dp"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    插图防止波纹延伸到有界区域之外。您可能需要调整这些值。

    还有风格。我不确定你的价值观是什么,所以我使用了这些:

    <style name="Widget.App.Button.OutlinedButton" parent="Widget.MaterialComponents.Button.OutlinedButton">
        <item name="strokeColor">@android:color/transparent</item>
        <item name="strokeWidth">4dp</item>
        <item name="android:textColor">#FF2b86e6</item>
        <item name="cornerRadius">16dp</item>
        <item name="textAllCaps">false</item>
        <item name="fontFamily">sans-serif-light</item>
    </style>
    

    我可能更喜欢 RadialGradient 来实现发光,但这会更难实现。

    【讨论】:

    • 终于找到了合适的答案!看起来很完美,非常感谢您的时间和帮助!非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2011-06-20
    • 2015-06-26
    • 2014-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-05
    • 1970-01-01
    相关资源
    最近更新 更多