Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/195.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android textview文本使用自定义字体在侧面截断_Android_Fonts_Textview - Fatal编程技术网

Android textview文本使用自定义字体在侧面截断

Android textview文本使用自定义字体在侧面截断,android,fonts,textview,Android,Fonts,Textview,这是预览和设备上发生的情况: TextView没有什么特别之处,它只是加载自定义字体: public class TestTextView extends AppCompatTextView { public TestTextView(Context context) { super(context); init(context); } public TestTextView(Context context, AttributeSe

这是预览和设备上发生的情况:

TextView没有什么特别之处,它只是加载自定义字体:

public class TestTextView extends AppCompatTextView {

    public TestTextView(Context context) {
        super(context);

        init(context);
    }

    public TestTextView(Context context, AttributeSet attrs) {
        super(context, attrs);

        init(context);
    }

    public TestTextView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        init(context);
    }

    void init(Context context) {

        Typeface t = Typeface.createFromAsset(context.getAssets(), "fonts/daisy.ttf");

        setTypeface(t);
    }
}
布局也很基本,但以防万一:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/material_red200"
    android:orientation="vertical">    

    <*custompackage* .TestTextView
        android:gravity="left"
        android:padding="0dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="just some text for testing"
        android:textColor="@color/material_black"
        android:textSize="100dp" />

</LinearLayout>

如果您将其包装在另一个布局中并添加填充,会怎么样?例如,类似这样的事情:

<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="24dp">
        <*custompackage* .TestTextView
        android:gravity="left"
        android:padding="0dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="just some text for testing"
        android:textColor="@color/material_black"
        android:textSize="100dp" />
</RelativeLayout>

没有你的字体和其他主题等,我只是尝试了草书字体,例如,在我的机器上,它会像这样。

更新: 看起来你不是唯一一个有这个问题和其他答案的人,不幸的是,这两个问题都与增加额外的空间有关


我创建了一个bug通知单,因为它在我看来像个bug。

这个答案让我找到了正确的路径:

因此,解决方案是创建自定义Textview并重写onDraw方法:

    @Override
    protected void onDraw(Canvas canvas) {
        final Paint paint = getPaint();
        final int color = paint.getColor();
        // Draw what you have to in transparent
        // This has to be drawn, otherwise getting values from layout throws exceptions
        setTextColor(Color.TRANSPARENT);
        super.onDraw(canvas);
        // setTextColor invalidates the view and causes an endless cycle
        paint.setColor(color);

        System.out.println("Drawing text info:");

        Layout layout = getLayout();
        String text = getText().toString();

        for (int i = 0; i < layout.getLineCount(); i++) {
            final int start = layout.getLineStart(i);
            final int end = layout.getLineEnd(i);

            String line = text.substring(start, end);

            System.out.println("Line:\t" + line);

            final float left = layout.getLineLeft(i);
            final int baseLine = layout.getLineBaseline(i);

            canvas.drawText(line,
                    left + getTotalPaddingLeft(),
                    // The text will not be clipped anymore
                    // You can add a padding here too, faster than string string concatenation
                    baseLine + getTotalPaddingTop(),
                    getPaint());
        }
    }
@覆盖
受保护的void onDraw(画布){
最终油漆=getPaint();
final int color=paint.getColor();
//用透明纸画你必须画的东西
//必须绘制此图,否则从布局中获取值会引发异常
setTextColor(颜色:透明);
super.onDraw(帆布);
//setTextColor使视图无效并导致无休止的循环
油漆。设置颜色(颜色);
System.out.println(“图纸文本信息:”);
Layout=getLayout();
字符串text=getText().toString();
对于(int i=0;i
我在
EditText
中使用一些字体时遇到了同样的问题

我的第一次尝试是使用填充。视图大小增加,但文本仍被裁剪

然后我查看了源代码
TextView
。在方法
onDraw
中,调用方法
Canvas.clipRect
执行此裁剪

我在使用填充时绕过裁剪的解决方案:

1) С创建从
Canvas
继承的自定义类,并重写方法
clipRect

public class NonClippableCanvas extends Canvas {

    public NonClippableCanvas(@NonNull Bitmap bitmap) {
        super(bitmap);
    }

    @Override
    public boolean clipRect(float left, float top, float right, float bottom) {
        return true;
    }
}
2) 创建自定义
TextView
并覆盖方法
onSizeChanged
onDraw

在方法
onSizeChanged
中,创建位图和画布

在方法
onDraw
中,通过将自定义的
Canvas
传递给方法
super.onDraw
来绘制位图。接下来,在目标画布上绘制此位图

public class CustomTextView extends AppCompatTextView {
    private Bitmap _bitmap;
    private NonClippableCanvas _canvas;

    @Override
    protected void onSizeChanged(final int width, final int height,
                             final int oldwidth, final int oldheight) {
        if (width != oldwidth || height != oldheight) {
            _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            _canvas = new NonClippableCanvas(_bitmap);
        }

        super.onSizeChanged(width, height, oldwidth, oldheight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        _canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        super.onDraw(_canvas);

        canvas.drawBitmap(_bitmap, 0, 0, null);
    }
}

一种解决方法是在键入前添加空格。它将为您节省大量编码,但会导致左侧出现“填充”


android:text=“空格后的文本”
返工@Dmitry Kopytov解决方案:

  • 在科特林
  • 回收旧位图
  • 添加文档
  • 如果无法创建位图(内存不足),请使用默认的TextView渲染
代码:


我遇到了同样的问题,我使用
TextView.shadowLayer
为数千名的人找到了一个一行解决方案

这是基于[Dmitry Kopytov]带来的源代码:



就是这样,现在
TextView.onDraw()
中的
canvas.clipRect
不会切掉卷曲的字体边。

TextView.BufferType.SPANNABLE
替换为
TextView.BufferType.NORMAL
尝试删除
android:padding=“0dp”
@AlexanderTumanin这对结果没有任何影响。请尝试在最后一个字符后添加空格,或为TestTextView设置固定宽度。是否可以共享字体文件?是否应用了任何自定义的文本样式和边框?@AmitKumar这是我使用的字体:我想它仍然会被截断。看第一个字母“j”哦,我的错。一开始并没有注意到这一点。我只是假设这就是字体的风格。填充导致文本视图变小(正如预期的那样),对剪切没有任何影响。是的,在谷歌上搜索一下,人们对这个问题的唯一“修复”似乎是添加额外的空格。正如我在上面的回答中所提到的,我已经用谷歌创建了一个bug罚单(不确定他们是否会响应,但值得一试)。@Kai bug ticket是个好主意。我也很好奇他们是否会回应。这不是一个好主意。此解决方案可能仅适用于单行文本。如果有多行,您必须计算哪些文本进入哪行,并在前面添加空格(加上如果当前行的内容在空格后到达下一行,或者如果单词对于单行来说太长)。此外,一个空间可能不够。因此,这只适用于非常特殊的情况。另一种解决方案是将文本框的宽度增加几dps,并将文本放在中间。这可以在activityjava文件中完成。我需要输出1-3个符号,它们是从侧面剪下来的。我不想用重写类做任何复杂和通用的事情。添加空格解决了我的问题。当我使用它时,它可以工作,但如果我需要缩放文本视图,它会显示模糊。@lasnow确定它不会。这将覆盖整个绘图机制,然后仅使用数据提供新的渲染。您必须通过删除行
setTextColor(Color.TRANSPARENT),为自己渲染光标光标和
public class CustomTextView extends AppCompatTextView {
    private Bitmap _bitmap;
    private NonClippableCanvas _canvas;

    @Override
    protected void onSizeChanged(final int width, final int height,
                             final int oldwidth, final int oldheight) {
        if (width != oldwidth || height != oldheight) {
            _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            _canvas = new NonClippableCanvas(_bitmap);
        }

        super.onSizeChanged(width, height, oldwidth, oldheight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        _canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

        super.onDraw(_canvas);

        canvas.drawBitmap(_bitmap, 0, 0, null);
    }
}
/**
 * This TextView is able to draw text on the padding area.
 * It's mainly used to support italic texts in custom fonts that can go out of bounds.
 * In this case, you've to set an horizontal padding (or just end padding).
 *
 * This implementation is doing a render-to-texture procedure, as such it consumes more RAM than a standard TextView,
 * it uses an additional bitmap of the size of the view.
 */
class TextViewNoClipping(context: Context, attrs: AttributeSet?) : AppCompatTextView(context, attrs) {
    private class NonClippableCanvas(@NonNull val bitmap: Bitmap) : Canvas(bitmap) {
        override fun clipRect(left: Float, top: Float, right: Float, bottom: Float): Boolean {
            return true
        }
    }

    private var rttCanvas: NonClippableCanvas? = null

    override fun onSizeChanged(width: Int, height: Int,
                               oldwidth: Int, oldheight: Int) {
        if ((width != oldwidth || height != oldheight) && width > 0 && height > 0) {
            rttCanvas?.bitmap?.recycle()
            try {
                Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)?.let {
                    rttCanvas = NonClippableCanvas(it)
                }
            } catch (t: Throwable) {
                // If for some reasons the bitmap cannot be created, we fall back on default rendering (potentially cropping the text).
                rttCanvas?.bitmap?.recycle()
                rttCanvas = null
            }
        }

        super.onSizeChanged(width, height, oldwidth, oldheight)
    }

    override fun onDraw(canvas: Canvas) {
        rttCanvas?.let {
            // Clear the RTT canvas from the previous font.
            it.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR)

            // Draw on the RTT canvas (-> bitmap) that will use clipping on the NonClippableCanvas, resulting in no-clipping
            super.onDraw(it)

            // Finally draw the bitmap that contains the rendered text (no clipping used here, will display on top of padding)
            canvas.drawBitmap(it.bitmap, 0f, 0f, null)

        } ?: super.onDraw(canvas) // If rtt is not available, use default rendering process
    }
}
editTextOrTextView.setShadowLayer(editTextOrTextView.textSize, 0f, 0f, Color.TRANSPARENT)