title: Incorrect EditText line spacing behavior in target API 28, when dealing with non-English Unicode (Like Chinese, Japanese)
body: <p>We notice that, during targetSdkVersion 28, <code>EditText</code> will tend to "slightly push down" the line after input, when non-English unicode (Like Chinese, Japanese, ...) is being entered.</p>
  
  <p>Such behavior doesn't happen, when the code is targetSdkVersion 27 or below.</p>
  
  <hr>
  
  <h2>Use <code>targetSdkVersion</code> 27, run on emulator API 28</h2>
  
  <p><strong>(Before input non-English unicode)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/SvCL7.png" rel="noreferrer"><img src="https://i.stack.imgur.com/SvCL7.png" alt="enter image description here"></a></p>
  
  <p><strong>(After input non-English unicode)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/9FCPn.png" rel="noreferrer"><img src="https://i.stack.imgur.com/9FCPn.png" alt="enter image description here"></a></p>
  
  <p><strong>(Confirm spacing is OK)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/6STSf.png" rel="noreferrer"><img src="https://i.stack.imgur.com/6STSf.png" alt="enter image description here"></a></p>
  
  <hr>
  
  <h2>Use <code>targetSdkVersion</code> 28, run on emulator API 28</h2>
  
  <p><strong>(Before input non-English unicode)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/YFXvF.png" rel="noreferrer"><img src="https://i.stack.imgur.com/YFXvF.png" alt="enter image description here"></a></p>
  
  <p><strong>(After input non-English unicode)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/35dvp.png" rel="noreferrer"><img src="https://i.stack.imgur.com/35dvp.png" alt="enter image description here"></a></p>
  
  <p><strong>(Confirm spacing is problematic. Lines after input are being pushed down)</strong></p>
  
  <p><a href="https://i.stack.imgur.com/EFmuz.png" rel="noreferrer"><img src="https://i.stack.imgur.com/EFmuz.png" alt="enter image description here"></a></p>
  
  <hr>
  
  <p>This is the XML and code used by us. We inherit from <code>androidx.appcompat.widget.AppCompatEditText</code>, to paint the lines, to make the problem more obvious.</p>
  
  <pre><code>&lt;com.yocto.wenote.note.LinedEditText
      android:id="@+id/body_edit_text"
      android:gravity="top"
      android:paddingLeft="16dp"
      android:paddingRight="16dp"
      android:layout_marginBottom="12dp"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:background="@android:color/transparent"
      android:scrollbars="vertical"
      android:textSize="18sp"
      android:singleLine="false"
      android:lineSpacingMultiplier="1.4"
      android:inputType="textMultiLine|textCapSentences"
      android:textCursorDrawable="?attr/shorterCursor" /&gt;
  </code></pre>
  
  <p><strong>LinedEditText.java</strong></p>
  
  <pre><code>package com.yocto.wenote.note;
  
  import android.content.Context;
  import android.content.res.Resources;
  import android.graphics.Canvas;
  import android.graphics.Paint;
  import android.util.AttributeSet;
  import android.util.TypedValue;
  
  import com.yocto.wenote.R;
  
  /**
   * Created by yccheok on 24/3/2018.
   */
  
  public class LinedEditText extends androidx.appcompat.widget.AppCompatEditText {
      private final Paint mPaint = new Paint();
      private int noteLineColor;
      private static final float DEFAULT_LINE_SPACING_EXTRA = 0.0f;
      private static final float DEFAULT_LINE_SPACING_MULTIPLIER = 1.4f;
  
      private void initResource() {
          Context context = getContext();
          TypedValue typedValue = new TypedValue();
          Resources.Theme theme = context.getTheme();
          theme.resolveAttribute(R.attr.noteLineColor, typedValue, true);
          noteLineColor = typedValue.data;
      }
  
      public LinedEditText(Context context) {
          super(context);
          initResource();
          initPaint();
      }
  
      public void setNoteLineColor(int noteLineColor) {
          this.noteLineColor = noteLineColor;
      }
  
      public LinedEditText(Context context, AttributeSet attrs) {
          super(context, attrs);
          initResource();
          initPaint();
      }
  
      public LinedEditText(Context context, AttributeSet attrs, int defStyleAttr) {
          super(context, attrs, defStyleAttr);
          initResource();
          initPaint();
      }
  
      private void initPaint() {
          mPaint.setStyle(Paint.Style.STROKE);
          mPaint.setColor(noteLineColor);
          mPaint.setStrokeWidth(1);
      }
  
      @Override
      protected void onDraw(Canvas canvas) {
          int left = getLeft();
          int right = getRight();
          int paddingTop = getPaddingTop();
          int paddingBottom = getPaddingBottom();
          int paddingLeft = getPaddingLeft();
          int paddingRight = getPaddingRight();
          final int heightWithScrollY = getHeight() + getScrollY();
          int lineHeight = getLineHeight();
          int count = (heightWithScrollY-paddingTop-paddingBottom) / lineHeight;
  
          mPaint.setColor(noteLineColor);
          mPaint.setTypeface(this.getTypeface());
  
          final float originalLineHeight;
          if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.JELLY_BEAN) {
              originalLineHeight = lineHeight / getLineSpacingMultiplier();
          } else {
              originalLineHeight = lineHeight / DEFAULT_LINE_SPACING_MULTIPLIER;
          }
  
          for (int i = 0; i &lt; count; i++) {
              float baseline = lineHeight * (i + 1) + paddingTop - mPaint.descent() - (lineHeight - originalLineHeight);
              canvas.drawLine(
                      left + paddingLeft,
                      baseline,
                      right - paddingRight,
                      baseline,
                      mPaint
              );
          }
  
          super.onDraw(canvas);
      }
  
      // https://stackoverflow.com/questions/49467579/workaround-for-edittext-ignoring-linespacingmultiplier
      @Override
      protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
          super.onTextChanged(text, start, lengthBefore, lengthAfter);
  
          if (lengthBefore != lengthAfter) {
              float add;
              float mul;
  
              if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.JELLY_BEAN) {
                  add = getLineSpacingExtra();
                  mul = getLineSpacingMultiplier();
              } else {
                  add = DEFAULT_LINE_SPACING_EXTRA;
                  mul = DEFAULT_LINE_SPACING_MULTIPLIER;
              }
  
              setLineSpacing(0f, 1f);
              setLineSpacing(add, mul);
          }
      }
  
  }
  </code></pre>
  
  <p>Take note that, if you use <code>targetSdkVersion</code> 28, BUT run on emulator API 27, this problem will not occur too.</p>
  
  <p>Any suggestion on the workaround?</p>
  
  <p>p/s I filed an issue at <a href="https://issuetracker.google.com/issues/131284662" rel="noreferrer">https://issuetracker.google.com/issues/131284662</a></p>