【问题标题】:Add opaque "shadow" (outline) to Android TextView将不透明的“阴影”(轮廓)添加到 Android TextView
【发布时间】:2016-08-23 16:31:29
【问题描述】:

我的Activity 中有一个TextView,我想在其中添加阴影。它应该看起来像OsmAnd(100% 不透明):

但它看起来像这样:

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

我当前的代码是:

<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"
/>

【问题讨论】:

  • 到目前为止,那里提供的解决方案都没有对我有用。我一直在努力……
  • 你想要的解决方案是这个:stackoverflow.com/a/23909516/4504191 你设置了一个笔画样式然后设置笔画宽度。图片中的白色轮廓是笔划。
  • 我有一个 MapsForge 活动,它有自己的 Paint 方法。我没有让它在那里工作。

标签: java android textview drawing mapsforge


【解决方案1】:

我尝试了hereherehere 等其他帖子中的所有技巧、提示和技巧。

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

现在这就是你真正的做法(在 OsmAnd 应用程序的源代码中找到):

您使用 FrameLayout(其特点是将其组件相互叠加)并在同一位置放置 2 个 TextView。

MainActivity.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>

在您的活动的onCreate 方法中,您设置阴影TextView 的笔画宽度并将其从填充更改为笔画:

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);
    }
}

结果如下:

【讨论】:

  • 两个文本视图,太糟糕的解决方案
  • @user924 我真的不认为这很糟糕,因为它还有两个视图。这是目前最可靠、最简单的解决方案。
  • 这实际上是一个可行的解决方案.. 但问题是很难定制这个......就像使用不同的 textview 属性进行不同的布局
  • 如果您不想只在一个地方实现它,这是一个非常简单的解决方案。我遇到了裁剪轮廓的问题。我通过添加空格来解决它。
【解决方案2】:

我遇到了同样的问题,在 onDraw 中调用 setTextColor 会导致无限循环。我想让我的自定义文本视图在渲染文本时具有与轮廓颜色不同的填充颜色。这就是我在onDraw 中多次调用setTextColor 的原因。

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

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 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-04
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 2021-10-25
    • 2019-06-14
    • 1970-01-01
    相关资源
    最近更新 更多