我想在Android中有一个双笔划的textview,这是不原生支持的(甚至不是一个单一的笔划)。遵循Android textview大纲文本就可以轻松实现.
public class StrokedTextView extends androidx.appcompat.widget.AppCompatTextView {
// fields
private int strokeColorW, strokeColorB;
private float strokeWidthW, strokeWidthB;
// 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);
strokeColorW = context.getColor(R.color.white);
strokeWidthW = dpToPx(context, 2);
strokeColorB = context.getColor(R.color.main_color_dark);
strokeWidthB = dpToPx(context, 3);
}
// overridden methods
@Override
protected void onDraw(Canvas canvas) {
//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 1 color and width
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(strokeWidthB);
setTextColor(strokeColorB);
//draw text stroke
super.onDraw(canvas);
//set paint to stroke mode and specify
//stroke 2 color and width
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(strokeWidthW);
setTextColor(strokeColorW);
//draw text stroke
super.onDraw(canvas);
//revert the color back to the one
//initially specified
setTextColor(currentTextColor);
}
public static int dpToPx(Context context, float dp)
{
final float scale= context.getResources().getDisplayMetrics().density;
return (int) (dp * scale + 0.5f);
}
}
问题是setTextColor
调用无效,因此这福尔斯无限次调用onDraw。正如一些人建议的那样,我尝试用一个标志来控制它,该标志指示无效是否由setTextColor引起。但它仍然无限地调用onDraw
private boolean isDrawing = false;
@Override
public void invalidate() {
if(isDrawing) return;
super.invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
isDrawing = true;
Paint p = getPaint();
p.setStyle(Paint.Style.FILL);
super.onDraw(canvas);
int currentTextColor = getCurrentTextColor();
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(strokeWidthB);
setTextColor(strokeColorB);
super.onDraw(canvas);
p.setStyle(Paint.Style.STROKE);
p.setStrokeWidth(strokeWidthW);
setTextColor(strokeColorW);
super.onDraw(canvas);
setTextColor(currentTextColor);
isDrawing = false;
}
正如其他用户在这个问题中所说的那样,我也尝试过使用Reflection来访问TextView的private字段并强行设置它:
private void setColor(int color){
Field field = TextView.class.getDeclaredField("mCurTextColor");
field.setAccessible(true);
field.set(this, color);
}
但是,它表示Reflective access to mCurTextColor will throw an Exception when targeting API 33 and above
所以我想问的是,是否有人看到了一种克服这个问题的方法,与我已经尝试过并失败的方法不同。
1条答案
按热度按时间gab6jxml1#
解决方案是从头开始创建自己的自定义视图。
在
attr.xml
中: