Fal*_*rri 74 android colors textview
有没有一种简单的方法让文字能够有黑色轮廓?我的文字视图会有不同的颜色,但是有些颜色不能很好地显示在我的背景上,所以我想知道是否有一种简单的方法来获得黑色轮廓或其他可以完成工作的东西?我宁愿不必创建自定义视图并制作画布等.
小智 60
在TextView中使用阴影可以实现轮廓效果:
android:shadowColor="#000000"
android:shadowDx="1.5"
android:shadowDy="1.3"
android:shadowRadius="1.6"
android:text="CCC"
android:textAllCaps="true"
android:textColor="@android:color/white"
Run Code Online (Sandbox Code Playgroud)
Ste*_*roy 52
您可以在文本后面添加阴影,这通常有助于提高可读性.尝试在绿色文本上尝试50%半透明黑色阴影.有关如何执行此操作的详细信息在此处:Android - 文本上的阴影?
要真正在文本周围添加笔划,您需要做一些更复杂的事情,例如: 在Android中如何在MapView上绘制带边框的文本?
ABe*_*oon 52
所以,很晚,但MagicTextView将做文本概述,等等.
<com.qwerjk.better_text.MagicTextView
xmlns:qwerjk="http://schemas.android.com/apk/res/com.qwerjk.better_text"
android:textSize="78dp"
android:textColor="#ff333333"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
qwerjk:strokeColor="#FFff0000"
qwerjk:strokeJoinStyle="miter"
qwerjk:strokeWidth="5"
android:text="Magic" />
Run Code Online (Sandbox Code Playgroud)
注意:我做了这个,并且为了未来的旅行者而不是OP发布更多.它是临界垃圾邮件,但是在主题上,也许可以接受?
Zso*_*any 23
该框架支持text-shadow但不支持text-outline.但有一个诀窍:阴影是半透明的,并且会褪色.重绘阴影几次,所有alpha将得到总和,结果是大纲.
一个非常简单的实现扩展了TextView并覆盖了draw方法.每次请求绘制时,我们的子类都会绘制5-10个绘图.
public class OutlineTextView extends TextView {
// Constructors
@Override
public void draw(Canvas canvas) {
for (int i = 0; i < 5; i++) {
super.draw(canvas);
}
}
}
<OutlineTextView
android:shadowColor="#000"
android:shadowRadius="3.0" />
Run Code Online (Sandbox Code Playgroud)
Nou*_*nif 20
这是一个相当古老的问题,但我仍然没有看到任何完整的答案.所以我发布这个解决方案,希望有人在努力解决这个问题可能会觉得它很有用.最简单和最有效的解决方案是覆盖TextView类的onDraw方法.我见过的大多数实现都使用drawText方法来绘制笔划,但是这种方法并没有考虑到所有的格式对齐和文本换行.结果,笔画和文本通常会在不同的地方结束.以下方法使用super.onDraw来绘制文本的笔划和填充部分,这样您就不必费心了.这是步骤
并再次调用父类onDraw以在先前呈现的文本上绘制笔划.
package com.example.widgets;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.AttributeSet;
import android.widget.Button;
public class StrokedTextView extends Button {
private static final int DEFAULT_STROKE_WIDTH = 0;
// fields
private int _strokeColor;
private float _strokeWidth;
// constructors
public StrokedTextView(Context context) {
this(context, null, 0);
}
public StrokedTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public StrokedTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if(attrs != null) {
TypedArray a = context.obtainStyledAttributes(attrs,R.styleable.StrokedTextAttrs);
_strokeColor = a.getColor(R.styleable.StrokedTextAttrs_textStrokeColor,
getCurrentTextColor());
_strokeWidth = a.getFloat(R.styleable.StrokedTextAttrs_textStrokeWidth,
DEFAULT_STROKE_WIDTH);
a.recycle();
}
else {
_strokeColor = getCurrentTextColor();
_strokeWidth = DEFAULT_STROKE_WIDTH;
}
//convert values specified in dp in XML layout to
//px, otherwise stroke width would appear different
//on different screens
_strokeWidth = dpToPx(context, _strokeWidth);
}
// getters + setters
public void setStrokeColor(int color) {
_strokeColor = color;
}
public void setStrokeWidth(int width) {
_strokeWidth = width;
}
// overridden methods
@Override
protected void onDraw(Canvas canvas) {
if(_strokeWidth > 0) {
//set paint to fill mode
Paint p = getPaint();
p.setStyle(Paint.Style.FILL);
//draw the fill part of text
super.onDraw(canvas);
//save the text color
int currentTextColor = getCurrentTextColor();
//set paint to stroke mode and specify
//stroke color and width
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(_strokeWidth);
setTextColor(_strokeColor);
//draw text stroke
super.onDraw(canvas);
//revert the color back to the one
//initially specified
setTextColor(currentTextColor);
} else {
super.onDraw(canvas);
}
}
/**
* Convenience method to convert density independent pixel(dp) value
* into device display specific pixel value.
* @param context Context to access device specific display metrics
* @param dp density independent pixel value
* @return device specific pixel value.
*/
public static int dpToPx(Context context, float dp)
{
final float scale= context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}
Run Code Online (Sandbox Code Playgroud)就这些.此类使用自定义XML属性来启用从XML布局文件指定笔触颜色和宽度.因此,您需要在文件夹'res'下的子文件夹'values'中的attr.xml文件中添加这些属性.将以下内容复制并粘贴到attr.xml文件中.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="StrokedTextAttrs">
<attr name="textStrokeColor" format="color"/>
<attr name="textStrokeWidth" format="float"/>
</declare-styleable>
</resources>
Run Code Online (Sandbox Code Playgroud)
完成后,您可以在XML布局文件中使用自定义StrokedTextView类,并指定笔触颜色和宽度.这是一个例子
<com.example.widgets.StrokedTextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Stroked text sample"
android:textColor="@android:color/white"
android:textSize="25sp"
strokeAttrs:textStrokeColor="@android:color/black"
strokeAttrs:textStrokeWidth="1.7" />
Run Code Online (Sandbox Code Playgroud)
请记住使用项目的包名替换包名.还要在布局文件中添加xmlns命名空间,以便使用自定义XML属性.您可以在布局文件的根节点中添加以下行.
xmlns:strokeAttrs="http://schemas.android.com/apk/res-auto"
Run Code Online (Sandbox Code Playgroud)
sve*_*sch 15
我一直试图弄清楚如何做到这一点,并无法在网上找到一个好的指南,但最终想出来了.正如Steve Pomeroy建议的那样,你必须做更多的事情.为了获得轮廓文本效果,您可以将文本绘制两次:一次使用粗轮廓,然后第二次在轮廓上绘制主文本.但是,任务变得更容易,因为您可以非常轻松地调整SDK提供的代码示例之一,即SDK目录中名称下的代码示例:"/ samples/android-/ApiDemos/src/com/example/android /apis/view/LabelView.java".这也可以在Android开发者网站上找到.
根据您正在做的事情,很容易看到您只需对该代码进行少量修改,例如将其更改为从TextView扩展等.在我发现此示例之前,我忘记覆盖onMeasure()(其中你必须做的除了重写onDraw(),如Android Developer网站上的"构建自定义组件"指南中所述,这是我遇到麻烦的部分原因.
一旦你完成了,你可以做我做的事情:
public class TextViewOutline extends TextView {
private Paint mTextPaint;
private Paint mTextPaintOutline; //add another paint attribute for your outline
...
//modify initTextViewOutline to setup the outline style
private void initTextViewOutline() {
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(16);
mTextPaint.setColor(0xFF000000);
mTextPaint.setStyle(Paint.Style.FILL);
mTextPaintOutline = new Paint();
mTextPaintOutline.setAntiAlias(true);
mTextPaintOutline.setTextSize(16);
mTextPaintOutline.setColor(0xFF000000);
mTextPaintOutline.setStyle(Paint.Style.STROKE);
mTextPaintOutline.setStrokeWidth(4);
setPadding(3, 3, 3, 3);
}
...
//make sure to update other methods you've overridden to handle your new paint object
...
//and finally draw the text, mAscent refers to a member attribute which had
//a value assigned to it in the measureHeight and Width methods
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent,
mTextPaintOutline);
canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
}
Run Code Online (Sandbox Code Playgroud)
因此,为了获得轮廓文本效果,您可以绘制两次文本:一次使用粗轮廓,然后第二次在轮廓上绘制主文本.
Art*_*hur 11
package com.megvii.demo;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
public class TextViewOutline extends android.support.v7.widget.AppCompatTextView {
// constants
private static final int DEFAULT_OUTLINE_SIZE = 0;
private static final int DEFAULT_OUTLINE_COLOR = Color.TRANSPARENT;
// data
private int mOutlineSize;
private int mOutlineColor;
private int mTextColor;
private float mShadowRadius;
private float mShadowDx;
private float mShadowDy;
private int mShadowColor;
public TextViewOutline(Context context) {
this(context, null);
}
public TextViewOutline(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
private void setAttributes(AttributeSet attrs) {
// set defaults
mOutlineSize = DEFAULT_OUTLINE_SIZE;
mOutlineColor = DEFAULT_OUTLINE_COLOR;
// text color
mTextColor = getCurrentTextColor();
if (attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.TextViewOutline);
// outline size
if (a.hasValue(R.styleable.TextViewOutline_outlineSize)) {
mOutlineSize = (int) a.getDimension(R.styleable.TextViewOutline_outlineSize, DEFAULT_OUTLINE_SIZE);
}
// outline color
if (a.hasValue(R.styleable.TextViewOutline_outlineColor)) {
mOutlineColor = a.getColor(R.styleable.TextViewOutline_outlineColor, DEFAULT_OUTLINE_COLOR);
}
// shadow (the reason we take shadow from attributes is because we use API level 15 and only from 16 we have the get methods for the shadow attributes)
if (a.hasValue(R.styleable.TextViewOutline_android_shadowRadius)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDx)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDy)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowColor)) {
mShadowRadius = a.getFloat(R.styleable.TextViewOutline_android_shadowRadius, 0);
mShadowDx = a.getFloat(R.styleable.TextViewOutline_android_shadowDx, 0);
mShadowDy = a.getFloat(R.styleable.TextViewOutline_android_shadowDy, 0);
mShadowColor = a.getColor(R.styleable.TextViewOutline_android_shadowColor, Color.TRANSPARENT);
}
a.recycle();
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setPaintToOutline();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private void setPaintToOutline() {
Paint paint = getPaint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mOutlineSize);
super.setTextColor(mOutlineColor);
super.setShadowLayer(0, 0, 0, Color.TRANSPARENT);
}
private void setPaintToRegular() {
Paint paint = getPaint();
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(0);
super.setTextColor(mTextColor);
super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
}
@Override
public void setTextColor(int color) {
super.setTextColor(color);
mTextColor = color;
}
public void setOutlineSize(int size) {
mOutlineSize = size;
}
public void setOutlineColor(int color) {
mOutlineColor = color;
}
@Override
protected void onDraw(Canvas canvas) {
setPaintToOutline();
super.onDraw(canvas);
setPaintToRegular();
super.onDraw(canvas);
}
}
Run Code Online (Sandbox Code Playgroud)
属性定义
<declare-styleable name="TextViewOutline">
<attr name="outlineSize" format="dimension"/>
<attr name="outlineColor" format="color|reference"/>
<attr name="android:shadowRadius"/>
<attr name="android:shadowDx"/>
<attr name="android:shadowDy"/>
<attr name="android:shadowColor"/>
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
xml代码如下
<com.megvii.demo.TextViewOutline
android:id="@+id/product_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="110dp"
android:background="#f4b222"
android:fontFamily="@font/kidsmagazine"
android:padding="10dp"
android:shadowColor="#d7713200"
android:shadowDx="0"
android:shadowDy="8"
android:shadowRadius="1"
android:text="LIPSTICK SET"
android:textColor="@android:color/white"
android:textSize="30sp"
app:outlineColor="#cb7800"
app:outlineSize="3dp" />
Run Code Online (Sandbox Code Playgroud)
我想添加一个解决方案来解决性能问题。例如,@YGHM 和其他一些人的答案可以完成这项工作,但它会导致无限调用onDraw
becausesetTextColor
调用invalidate()
。因此,为了解决这个问题,您还需要覆盖invalidate()
并添加一个变量,isDrawing
您将在进行中并用笔画绘制true
时将其设置为 。onDraw()
如果变量是 则 invalidate 将返回true
。
override fun invalidate() {
if (isDrawing) return
super.invalidate()
}
Run Code Online (Sandbox Code Playgroud)
你的 onDraw 将如下所示:
override fun onDraw(canvas: Canvas) {
if (strokeWidth > 0) {
isDrawing = true
val textColor = textColors.defaultColor
setTextColor(strokeColor)
paint.strokeWidth = strokeWidth
paint.style = Paint.Style.STROKE
super.onDraw(canvas)
setTextColor(textColor)
paint.strokeWidth = 0f
paint.style = Paint.Style.FILL
isDrawing = false
super.onDraw(canvas)
} else {
super.onDraw(canvas)
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下代码段以编程方式执行此操作。这提供了黑色背景的白色字母:
textView.setTextColor(Color.WHITE);
textView.setShadowLayer(1.6f,1.5f,1.3f,Color.BLACK);
Run Code Online (Sandbox Code Playgroud)
该方法的参数是radius,dx,dy,color。您可以根据自己的特定需求更改它们。
我希望我能帮助那些以编程方式创建 TextView 而不是在 xml 中的人。
为 stackOverflow 社区干杯!
这是我发现的技巧比MagicTextView的中风IMO更好
@Override
protected void onDraw(Canvas pCanvas) {
int textColor = getTextColors().getDefaultColor();
setTextColor(mOutlineColor); // your stroke's color
getPaint().setStrokeWidth(10);
getPaint().setStyle(Paint.Style.STROKE);
super.onDraw(pCanvas);
setTextColor(textColor);
getPaint().setStrokeWidth(0);
getPaint().setStyle(Paint.Style.FILL);
super.onDraw(pCanvas);
}
Run Code Online (Sandbox Code Playgroud)
我写了一个类来执行带有大纲的文本,并且仍然支持所有其他属性和绘制普通文本视图.
它基本上使用了super.onDraw(Canves canvas)
on,TextView
但是用不同的样式绘制了两次.
希望这可以帮助.
public class TextViewOutline extends TextView {
// constants
private static final int DEFAULT_OUTLINE_SIZE = 0;
private static final int DEFAULT_OUTLINE_COLOR = Color.TRANSPARENT;
// data
private int mOutlineSize;
private int mOutlineColor;
private int mTextColor;
private float mShadowRadius;
private float mShadowDx;
private float mShadowDy;
private int mShadowColor;
public TextViewOutline(Context context) {
this(context, null);
}
public TextViewOutline(Context context, AttributeSet attrs) {
super(context, attrs);
setAttributes(attrs);
}
private void setAttributes(AttributeSet attrs){
// set defaults
mOutlineSize = DEFAULT_OUTLINE_SIZE;
mOutlineColor = DEFAULT_OUTLINE_COLOR;
// text color
mTextColor = getCurrentTextColor();
if(attrs != null) {
TypedArray a = getContext().obtainStyledAttributes(attrs,R.styleable.TextViewOutline);
// outline size
if (a.hasValue(R.styleable.TextViewOutline_outlineSize)) {
mOutlineSize = (int) a.getDimension(R.styleable.TextViewOutline_outlineSize, DEFAULT_OUTLINE_SIZE);
}
// outline color
if (a.hasValue(R.styleable.TextViewOutline_outlineColor)) {
mOutlineColor = a.getColor(R.styleable.TextViewOutline_outlineColor, DEFAULT_OUTLINE_COLOR);
}
// shadow (the reason we take shadow from attributes is because we use API level 15 and only from 16 we have the get methods for the shadow attributes)
if (a.hasValue(R.styleable.TextViewOutline_android_shadowRadius)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDx)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowDy)
|| a.hasValue(R.styleable.TextViewOutline_android_shadowColor)) {
mShadowRadius = a.getFloat(R.styleable.TextViewOutline_android_shadowRadius, 0);
mShadowDx = a.getFloat(R.styleable.TextViewOutline_android_shadowDx, 0);
mShadowDy = a.getFloat(R.styleable.TextViewOutline_android_shadowDy, 0);
mShadowColor = a.getColor(R.styleable.TextViewOutline_android_shadowColor, Color.TRANSPARENT);
}
a.recycle();
}
PFLog.d("mOutlineSize = " + mOutlineSize);
PFLog.d("mOutlineColor = " + mOutlineColor);
}
private void setPaintToOutline(){
Paint paint = getPaint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(mOutlineSize);
super.setTextColor(mOutlineColor);
super.setShadowLayer(mShadowRadius, mShadowDx, mShadowDy, mShadowColor);
}
private void setPaintToRegular() {
Paint paint = getPaint();
paint.setStyle(Paint.Style.FILL);
paint.setStrokeWidth(0);
super.setTextColor(mTextColor);
super.setShadowLayer(0, 0, 0, Color.TRANSPARENT);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setPaintToOutline();
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
@Override
public void setTextColor(int color) {
super.setTextColor(color);
mTextColor = color;
}
@Override
public void setShadowLayer(float radius, float dx, float dy, int color) {
super.setShadowLayer(radius, dx, dy, color);
mShadowRadius = radius;
mShadowDx = dx;
mShadowDy = dy;
mShadowColor = color;
}
public void setOutlineSize(int size){
mOutlineSize = size;
}
public void setOutlineColor(int color){
mOutlineColor = color;
}
@Override
protected void onDraw(Canvas canvas) {
setPaintToOutline();
super.onDraw(canvas);
setPaintToRegular();
super.onDraw(canvas);
}
}
Run Code Online (Sandbox Code Playgroud)
attr.xml
<declare-styleable name="TextViewOutline">
<attr name="outlineSize" format="dimension"/>
<attr name="outlineColor" format="color|reference"/>
<attr name="android:shadowRadius"/>
<attr name="android:shadowDx"/>
<attr name="android:shadowDy"/>
<attr name="android:shadowColor"/>
</declare-styleable>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
116203 次 |
最近记录: |