編輯:我已經能夠跟蹤到使用EditText
而不是TextView
的問題。重複呼叫僅在字段爲EditText
時發生,並且當字段爲TextView
時系統會自行運行。我在文檔或在線中找不到任何內容,表明LineBackgroundSpan
不適用於EditText
。LineBackgroundSpan drawBackground()重複調用
我已更新MCVE以顯示事情如何與TextView
(它)和EditText
(它不 - 至少不是很好)一起工作。我更新的問題是如何獲得LineBackgroundSpan
與EditText
一起使用。
我實現了一個簡單的類添加一個圓形的背景使用LineBackgroundSpan
在EditText
爲文本。一切正常,但在調試過程中,我注意到我的類的方法被重複調用,看起來,即使沒有進行任何更改,字符串中的每個跨度都沒有結束。它在顯示屏上並不明顯,但如果在方法中設置了斷點,則顯而易見。
在試圖追蹤問題時,我能夠將代碼縮減爲MCVE。以下代碼將簡單地突出顯示整行文本。最上面一行是EditText
,最後一行是TextView
。 (這不是我真正想要做的,但它是有用的。)
此MCVE對運行API 17和API 24的仿真器以及運行API 24的實際電話展現了問題。設置disableDraw
參數爲true
,RoundedBackgroudSpan()
的構造函數將在drawBackground()
中禁用背景繪製操作。即使在禁用背景繪製的情況下,我也會在EditText
上看到問題。
這是怎麼回事?我誤解了如何使用跨度?將跨越EditText
不起作用?任何幫助將不勝感激。
MainActivity.java
package com.example.bgspanmcve;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.SpannableString;
import android.text.style.LineBackgroundSpan;
import android.util.Log;
import android.widget.EditText;
import android.widget.TextView;
import static android.text.Spanned.SPAN_INCLUSIVE_INCLUSIVE;
public class MainActivity extends AppCompatActivity {
final String dispString = "XAB CD EF";
private static int count = 0; // times drawBackground is called
@Override
protected void onCreate(Bundle savedInstanceState) {
EditText editText;
TextView textView;
RoundedBackgroundSpan bg;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Set up the EditText field with a span.
// RoundedBackgroundSpan#drawBackground will be called forever for this EditText.
editText = ((EditText) findViewById(R.id.editText));
SpannableString ssEditText = new SpannableString(dispString);
bg = new RoundedBackgroundSpan(INHIBIT_DRAWING, false);
ssEditText.setSpan(bg, 0, ssEditText.length(), SPAN_INCLUSIVE_INCLUSIVE);
editText.setText(ssEditText);
// Set up the TextView field with a span.
// RoundedBackgroundSpan#drawBackground will be called once for this TextView.
textView = ((TextView) findViewById(R.id.textView));
SpannableString ssTextView = new SpannableString(dispString);
bg = new RoundedBackgroundSpan(INHIBIT_DRAWING, true);
ssTextView.setSpan(bg, 0, ssTextView.length(), SPAN_INCLUSIVE_INCLUSIVE);
textView.setText(ssTextView, TextView.BufferType.EDITABLE);
}
private static class RoundedBackgroundSpan implements LineBackgroundSpan {
private boolean mDisableDraw;
private boolean mIsTextView;
RoundedBackgroundSpan(boolean disableDraw, boolean isTextView) {
super();
mDisableDraw = disableDraw;
mIsTextView = isTextView;
}
@Override
public void drawBackground(
Canvas canvas, Paint paint, int left, int right, int top,
int baseline, int bottom, CharSequence text, int start, int end, int lnum) {
count++;
if (mIsTextView) {
Log.d(TAG, "<<<<drawBackground (TextView) #" + count);
} else {
Log.d(TAG, "<<<<drawBackground (EditText) #" + count);
}
if (mDisableDraw) return;
Paint localPaint = new Paint();
RectF rect = new RectF(left, top, right, bottom);
localPaint.setColor(BG_COLOR);
canvas.drawRoundRect(rect, RADIUS_X, RADIUS_Y, localPaint);
}
private final String TAG = RoundedBackgroundSpan.class.getSimpleName();
private final int BG_COLOR = 0xfF00FF00;
private final int RADIUS_X = 20;
private final int RADIUS_Y = 20;
}
private final static String TAG = MainActivity.class.getSimpleName();
private final boolean INHIBIT_DRAWING = true;
}
activity_main.xml中
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.bgspanmcve.MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginStart="0dp"
android:inputType="text"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:text="EditText"
android:textSize="20sp" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignStart="@id/editText"
android:layout_below="@id/editText"
android:layout_marginStart="0dp"
android:layout_marginTop="16dp"
android:paddingEnd="0dp"
android:paddingStart="0dp"
android:text="TextView"
android:textSize="20sp"
android:textStyle="bold" />
</RelativeLayout>
您是否找到答案?多久它需要'EditText'?它可能與光標閃爍率有關嗎? – Suragch
@Suragch我還沒有找到這個問題的答案。我剛回去檢查有多少個「drawBackground」調用。目前的計數是1,426,每秒增加約2倍。如果我在應用跨度之前清除所有跨度,則可以避免此問題,因此似乎存在導致此問題的基礎跨度交互。這是一個沉默的問題,在屏幕上或性能上並不明顯。我偶然發現它是因爲我在'drawBackground'中設置了一個斷點。至於光標眨眼率,光標隱藏在背景之後,而且我也沒有對速率做任何事情。 – Cheticamp
@Sugarch我認爲你對光標閃爍率是正確的。這些呼叫是以閃爍的光標速率計時的。我認爲光標將與背景圖分開,但它看起來不是。如果您可以填寫答案,我會接受。謝謝! – Cheticamp