添加不透明的“阴影”(轮廓)到Android TextView

2022-09-03 14:44:05

我的活动中有一个文本视图,我想向其添加阴影。它应该看起来像在OsmAnd中(100%不透明):

what I want

但它看起来像这样:

What I have

您可以看到当前阴影模糊并逐渐消失。我想要一个坚实的、不透明的阴影。但是如何做到呢?

我目前的代码是:

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/speedTextView"
    android:text="25 km/h"

    android:textSize="24sp"
    android:textStyle="bold"
    android:textColor="#000000"
    android:shadowColor="#ffffff"
    android:shadowDx="0"
    android:shadowDy="0"
    android:shadowRadius="6"
/>

答案 1

我尝试了其他帖子中的所有技巧,提示和技巧,例如这里这里这里

它们都没有那么好或看起来那么好。

现在,这就是您真正做到这一点的方式(在OsmAnd应用程序的源代码中找到):

您可以使用 FrameLayout(它具有将其组件相互放置的特征),并将 2 个 TextViews 放在同一位置。

主要活动.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="#445566">

    <FrameLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:layout_weight="1">

        <TextView
            android:id="@+id/textViewShadowId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:textSize="36sp"
            android:text="123 ABC" 
            android:textColor="#ffffff" />

        <TextView
            android:id="@+id/textViewId"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:textSize="36sp"
            android:text="123 ABC"
            android:textColor="#000000" />
    </FrameLayout>

</LinearLayout>

在活动方法中,您可以设置阴影TextView的描边宽度,并将其从FILL更改为STROKE:onCreate

import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
    
public class MainActivity extends AppCompatActivity {    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        //here comes the magic
        TextView textViewShadow = (TextView) findViewById(R.id.textViewShadowId);
        textViewShadow.getPaint().setStrokeWidth(5);
        textViewShadow.getPaint().setStyle(Paint.Style.STROKE);
    }
}

结果如下所示:

result screenshot


答案 2

我遇到了同样的问题,调用导致无限绘制循环。我想使我的自定义文本视图在呈现文本时具有与轮廓颜色不同的填充颜色。这就是为什么我在.setTextColoronDrawsetTextColoronDraw

使用 https://github.com/santaevpavel/OutlineSpan 找到了替代解决方案。这比使用多个 TextView 或使用反射使布局层次结构复杂化要好,并且需要的更改最少。有关更多详细信息,请参阅 github 页面。例OutlineSpan

val outlineSpan = OutlineSpan(
    strokeColor = Color.RED,
    strokeWidth = 4F
)
val text = "Outlined text"
val spannable = SpannableString(text)
spannable.setSpan(outlineSpan, 0, 8, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE)

// Set text of TextView
binding.outlinedText.text = spannable 

推荐