Android中的渐变文字

Cas*_*ash 56 user-interface android

如何扩展TextView以允许绘制具有渐变效果的文本?

小智 126

TextView secondTextView = new TextView(this);
Shader textShader=new LinearGradient(0, 0, 0, 20,
            new int[]{Color.GREEN,Color.BLUE},
            new float[]{0, 1}, TileMode.CLAMP);
secondTextView.getPaint().setShader(textShader);
Run Code Online (Sandbox Code Playgroud)

  • @Steve Prentice:可能是y1 = 20太短,所以你看不到任何渐变,请尝试:new LinearGradient(0,0,0,secondTextView.getPaint().getTextSize(),....) - 也许它会解决你的问题 (14认同)

han*_*wim 26

我使用了5种颜色的渐变顶部答案(@Taras),但是有一个问题:textView看起来像是我在上面放了一个白色的封面.这是我的代码和截图.

        textView = (TextView) findViewById(R.id.main_tv);
        textView.setText("Tianjin, China".toUpperCase());

        TextPaint paint = textView.getPaint();
        float width = paint.measureText("Tianjin, China");

        Shader textShader = new LinearGradient(0, 0, width, textView.getTextSize(),
                new int[]{
                        Color.parseColor("#F97C3C"),
                        Color.parseColor("#FDB54E"),
                        Color.parseColor("#64B678"),
                        Color.parseColor("#478AEA"),
                        Color.parseColor("#8446CC"),
                }, null, Shader.TileMode.CLAMP);
        textView.getPaint().setShader(textShader);
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

几个小时后,我发现我需要textView.setTextColor()使用渐变的第一种颜色来调用.然后截图:

在此输入图像描述

希望有人帮忙!


Cas*_*ash 20

似乎无法扩展TextView以使用渐变绘制文本.但是,可以通过创建画布并在其上绘图来实现此效果.首先,我们需要声明我们的自定义UI元素.在初始化中,我们需要创建Layout的子类.在这种情况下,我们将使用BoringLayout,它仅支持单行文本.

Shader textShader=new LinearGradient(0, 0, 0, 20,
    new int[]{bottom,top},
    new float[]{0, 1}, TileMode.CLAMP);//Assumes bottom and top are colors defined above
textPaint.setTextSize(textSize);
textPaint.setShader(textShader);
BoringLayout.Metrics boringMetrics=BoringLayout.isBoring(text, textPaint);
boringLayout=new BoringLayout(text, textPaint, 0, Layout.Alignment.ALIGN_CENTER,
            0.0f, 0.0f, boringMetrics, false);
Run Code Online (Sandbox Code Playgroud)

然后我们覆盖onMeasureonDraw:

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
    setMeasuredDimension((int) textPaint.measureText(text), (int) textPaint.getFontSpacing());
}

@Override
protected void onDraw(Canvas canvas){
    super.onDraw(canvas);
    boringLayout.draw(canvas);
}
Run Code Online (Sandbox Code Playgroud)

我们的实现onDraw在这一点上非常懒惰(它完全忽略了测量规范!)但只要你保证视图给出足够的空间,它应该可以正常工作.

或者,可以从a继承Canvas并覆盖该onPaint方法.如果这样做,那么不幸的是,正在绘制的文本的锚点将始终位于底部,因此我们必须添加-textPaint.getFontMetricsInt().ascent()到y坐标.


kou*_*ush 10

我已经推出了一个包含这两种方法的库.您可以使用XML创建GradientTextView,或者只使用GradientTextView.setGradient(TextView textView ...)在常规TextView对象上执行此操作.

https://github.com/koush/Widgets


Dus*_*tin 9

这里是多线支持作为一个班轮.这也适用于Buttons.

__CODE__

  • 可行,但对于高度,您可能需要考虑实际行下方的字母(如 y、g、j 等)并将行高乘以 1.10f,例如`textView.getLineHeight() * 1.10f`。 (2认同)