如何在Activity中使用自定义EditText类?

时间:2014-05-30 05:31:39

标签: android android-edittext

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)

3 个答案:

答案 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());
                    } 
                } 

            } 
        } 
    } 
}

布局文件与之前相同。