public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
init();
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
void init() {
this.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
// TODO Auto-generated method stub
return false;
}
});
this.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
Log.e("afterTextChanged", "" + s);
if (s.toString().length() > 0 && s.toString().charAt(0) != '$') {
StringBuilder b = new StringBuilder(s.toString());
b = b.reverse();
b.append('$');
b = b.reverse();
MyEditText.this.setText(b);
MyEditText.this.setSelection(MyEditText.this.getText()
.length());
} else {
int counter = 0;
for (int i = 0; i < s.toString().length(); i++) {
if (s.toString().charAt(i) == '$') {
counter++;
}
}
if (counter > 1) {
String str = s.toString().replace("$", "").trim();
str = str.replaceAll("\\s+", "");
StringBuilder b = new StringBuilder(str);
b = b.reverse();
b.append('$');
b = b.reverse();
MyEditText.this.setText(b);
MyEditText.this.setSelection(MyEditText.this.getText()
.length());
} else {
int spaceCount = 0;
for (int i = 0; i < s.toString().length(); i++) {
if (s.toString().charAt(i) == ' ') {
spaceCount++;
}
}
if (spaceCount > 0) {
String str = s.toString().replace("$", "").trim();
str = str.replaceAll("\\s+", "");
StringBuilder b = new StringBuilder(str);
MyEditText.this.setText(b);
MyEditText.this.setSelection(MyEditText.this
.getText().length());
}
}
}
}
});
}
}
Main_Activity布局是:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.example.mycustomizeedittextsample.MyEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal" />
</RelativeLayout>
MainActivity.java类是:
public class MainActivity extends Activity {
MyEditText myEditText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_layout);
myEditText = new MyEditText(this);
}
}
MainActivity
中缺少某些内容,但我不知道它是什么。当我运行应用程序时,会出现以下崩溃:
java.lang.StackOverflowError
at java.lang.StringBuilder.append(StringBuilder.java:202) at com.example.dialogfragmentexample.MyEditText$2.beforeTextChanged(MyEditText.java:55)
答案 0 :(得分:2)
您正在setText
内拨打beforeTextChanged
。这会触发对beforeTextChanged
的另一次调用,这会触发对setText
的另一次调用,...重复,直到您的堆栈帧用完为止。
在afterTextChanged
(或更高版本)之前不要更改editText的内容,并且要注意创建这样的无限循环。
答案 1 :(得分:1)
将您的代码放在onTextChanged()
中,而不是beforeTextchange()
,并且还可以将afterText()
更改方法设置为可以使用我测试它
答案 2 :(得分:0)
init();
大多数堆栈溢出错误与间接调用自身的方法有关。这也是这种情况。
您可以在MyEditText之外设置TextWather。
因此可能嵌套调用函数跟踪你的init它会创建TextWather回调函数的无限调用。
编辑:
<强> MyEditText.java 强>
public class MyEditText extends EditText {
public MyEditText(Context context) {
super(context);
// init();
}
public MyEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// init();
}
public MyEditText(Context context, AttributeSet attrs) {
super(context, attrs);
// init();
}
}
<强> MainActivity.java 强>
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyEditText myEditText = new MyEditText(this);
myEditText.addTextChangedListener(new CustomTextWatcher(myEditText));
}
//TextWathcer
private class CustomTextWatcher implements TextWatcher {
private MyEditText mEditText;
public CustomTextWatcher(MyEditText myEditText) {
mEditText = myEditText;
}
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
Log.e("afterTextChanged", "" + s);
if (s.toString().length() > 0 && s.toString().charAt(0) != '$') {
StringBuilder b = new StringBuilder(s.toString());
b = b.reverse();
b.append('$');
b = b.reverse();
mEditText.setText(b);
mEditText.setSelection(mEditText.getText()
.length());
} else {
int counter = 0;
for (int i = 0; i < s.toString().length(); i++) {
if (s.toString().charAt(i) == '$') {
counter++;
}
}
if (counter > 1) {
String str = s.toString().replace("$", "").trim();
str = str.replaceAll("\\s+", "");
StringBuilder b = new StringBuilder(str);
b = b.reverse();
b.append('$');
b = b.reverse();
mEditText.setText(b);
mEditText.setSelection(mEditText.getText()
.length());
} else {
int spaceCount = 0;
for (int i = 0; i < s.toString().length(); i++) {
if (s.toString().charAt(i) == ' ') {
spaceCount++;
}
}
if (spaceCount > 0) {
String str = s.toString().replace("$", "").trim();
str = str.replaceAll("\\s+", "");
StringBuilder b = new StringBuilder(str);
mEditText.setText(b);
mEditText.setSelection(mEditText
.getText().length());
}
}
}
}
}
}
布局文件与之前相同。