getmeasuredheight возвращает 0 или то же самое при использовании ReplacementSpan

#java #android

#java #Android

Вопрос:

ShadowSpan.java

 public class ShadowSpan extends ReplacementSpan {
public ShadowSpan(int color, PointF offset){
}
@Override
public int getSize(@NonNull Paint paint, CharSequence text, int start, int end, @Nullable Paint.FontMetricsInt fm) {
    return (int)paint.measureText(text,start,end);
}

@Override
public void draw(@NonNull Canvas canvas, CharSequence text, int start, int end, float x, int top, int y, int bottom, @NonNull Paint paint) {
    canvas.drawText(text,start,end,x,y,paint);
}}
  

MainActivity.java

 public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    String tx = "sssss3333";
    SpannableString sp = new SpannableString(tx);
    ShadowSpan ss = new ShadowSpan(Color.GRAY,new PointF(8,8));
    AbsoluteSizeSpan as = new AbsoluteSizeSpan(100);
    sp.setSpan(ss,0,tx.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    sp.setSpan(as,0,tx.length(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
    TextView tv = new TextView(this);
    tv.setText(sp, TextView.BufferType.SPANNABLE);
    tv.measure(0,0);
    int h = tv.getMeasuredHeight();
    int w = tv.getMeasuredWidth();
    FrameLayout fl = (FrameLayout)getWindow().getDecorView().findViewById(android.R.id.content);
    fl.addView(tv);
}}
  

Выше приведен весь мой код, очень простой, но есть очень странная проблема.

если я использую ReplacementSpan, и если отладкой является реальная машина, то getMeasuredHeight вернет только 0 или то же значение, если отладкой является виртуальное устройство, то getMeasuredHeight вернет правильное значение.

Однако, независимо от того, является ли это реальной машиной или виртуальным устройством, значение, возвращаемое getMeasuredWidth, является правильным.

Это среда сборки: compileSdkVersion 27 minSdkVersion 15 targetSdkVersion 27

реальной машиной является sangsumg Galaxy Note 9

Обновление: у меня есть несколько новых открытий, даже на виртуальных устройствах, если вы используете API27, будут проблемы, API28 — это не проблема, реальный машинный API равен 28

Ответ №1:

Посмотрев на TextLine.java исходный код, поскольку ReplacementSpan наследуется от MetricAffectingSpan, и текст обрабатывается в процессе обработки MetricAffectingSpan, а затем обработки CharactorStyle, и когда MetricAffectingSpan является ReplacementSpan, затем непосредственно рисуется и продолжается, следующий CharactorStyle вообще не обрабатывается