Android 重复调用LineBackgroundSpan drackground()
编辑:我已经能够追踪到问题的根源是Android 重复调用LineBackgroundSpan drackground(),android,android-layout,android-edittext,Android,Android Layout,Android Edittext,编辑:我已经能够追踪到问题的根源是EditText的使用,而不是TextView。重复调用仅在字段为EditText时发生,并且当字段为TextView时系统会自行运行。我在文档或网上找不到任何东西表明LineBackgroundSpan不能与EditText一起使用 我已经更新了MCVE,以显示如何使用TextView(它可以)和EditText(它不能-至少不能很好地工作)。我最新的问题是如何获得LineBackgroundSpan使用EditText 我已经实现了一个简单的类,用它向Ed
EditText
的使用,而不是TextView
。重复调用仅在字段为EditText
时发生,并且当字段为TextView
时系统会自行运行。我在文档或网上找不到任何东西表明LineBackgroundSpan
不能与EditText
一起使用
我已经更新了MCVE,以显示如何使用TextView
(它可以)和EditText
(它不能-至少不能很好地工作)。我最新的问题是如何获得LineBackgroundSpan
使用EditText
我已经实现了一个简单的类,用它向
EditText
中的文本添加圆形背景。一切正常,但在调试过程中,我注意到类的traffackground
方法被反复调用,而且似乎字符串中的每个跨度都没有结束,即使没有进行任何更改。它在显示屏上不明显,但如果在牵引地面
方法中设置了断点,则很明显
在试图追踪问题的过程中,我将代码简化为MCVE。顶行是一个编辑文本
,底行是一个文本视图
。(这不是我真正想做的,但它达到了目的。)
这个MCVE向我展示了运行API 17和API 24的模拟器以及运行API 24的实际手机的问题。将roundedbackgroundspan()
的构造函数的disableDraw
参数设置为true
,将禁用drackground()中的背景绘图操作。即使在禁用背景绘图的情况下,EditText
上也出现了问题
这是怎么回事?我是否误解了如何使用跨度?span不能使用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;
}
package com.example.bgspanmcve;
导入android.graphics.Canvas;
导入android.graphics.Paint;
导入android.graphics.RectF;
导入android.os.Bundle;
导入android.support.v7.app.AppActivity;
导入android.text.SpannableString;
导入android.text.style.LineBackgroundSpan;
导入android.util.Log;
导入android.widget.EditText;
导入android.widget.TextView;
导入静态android.text.SPAN.SPAN_INCLUSIVE_INCLUSIVE;
公共类MainActivity扩展了AppCompatActivity{
最终字符串dispString=“XAB CD EF”;
private static int count=0;//调用trackground的次数
@凌驾
创建时受保护的void(Bundle savedInstanceState){
编辑文本编辑文本;
文本视图文本视图;
圆形背景跨度bg;
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//设置带有跨距的EditText字段。
//RoundedBackgroundSpan#此编辑文本将永远调用trackground。
editText=((editText)findViewById(R.id.editText));
SpannableString ssEditText=新的SpannableString(dispString);
bg=新的圆形背景跨度(禁止绘制,错误);
ssEditText.setSpan(bg,0,ssEditText.length(),包含SPAN_);
editText.setText(ssEditText);
//设置带有跨距的TextView字段。
//RoundedBackgroundSpan#将为此TextView调用一次牵引地面。
textView=((textView)findViewById(R.id.textView));
SpannableString ssTextView=新的SpannableString(dispString);
bg=新的圆形背景跨度(抑制图,真);
ssTextView.setSpan(bg,0,ssTextView.length(),包含SPAN_);
textView.setText(ssTextView,textView.BufferType.EDITABLE);
}
私有静态类RoundedBackgroundSpan实现LineBackgroundSpan{
私有布尔mDisableDraw;
私有布尔文本视图;
RoundedBackgroundSpan(布尔禁用绘制,布尔isTextView){
超级();
mDisableDraw=禁用绘制;
mIsTextView=isTextView;
}
@凌驾
公共空地(
帆布,油漆,左整数,右整数,顶部整数,
int基线、int底部、字符序列文本、int开始、int结束、int lnum){
计数++;
if(mIsTextView){
Log.d(TAG,“对牵引地面()
的调用按照@Suragch建议的大约500毫秒的闪烁光标的速率进行计时。我现在确信,对牵引地面()
的调用是作为光标实现的一部分进行的
作为一个快速但非决定性的测试,我已将EditText
字段设置为不显示光标,但仍可编辑(android:cursorVisible=“false”
)。当此属性设置为false时,重复调用trackground()
停止。你找到你的答案了吗?多久调用一次EditText
?这可能与光标闪烁率有关吗?@Suragh我没有找到这个问题的答案。我只是回去检查有多少次调用退税地
。当前计数是1426,并且增加了大约2倍/秒。我可以避免如果我在应用span之前清除了所有span,则会出现问题,因此似乎存在导致此问题的潜在span交互。这是一个无声的问题,在屏幕或性能上不明显。我碰巧发现了它,因为我在trackground
中设置了断点。至于光标闪烁率,光标隐藏在后面背景和我对速率没有任何影响。@Sugarch我认为你对光标闪烁速率的看法是正确的。通话是以光标闪烁的速率计时的。我认为
<?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>