GreenCodes
GreenCodes

Reputation: 241

How to prevent deleting the first character of edit text in Android

This is one of my Edit text in the application

<EditText
        android:id="@+id/etFolder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="/pictures"
        android:ems="10" >

When it appear at first time it comes with "/pictures"

User can change the text and enter another word. but how to prevent deleting "/" of Edit text.

user can delete all other text but should not allow to delete first character.

How can I achieve this behavior ?

Upvotes: 14

Views: 13771

Answers (8)

Kartik
Kartik

Reputation: 171

#KOTLIN_EXAMPLE

    editText.addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                val prefix = "+91 "
                val count = s?.toString()?.length ?: 0
                if (count < prefix.length) {
                    if (s.toString() != prefix.trim()) {
                        editText.setText("$prefix$s")
                    } else {
                        editText.setText(prefix)
                    }
                    editText.setSelection(editText.length())
                }
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            }
        })

This way user won't be able to remove/delete the defined prefix. Moreover, the first entered character will also be appended in the EditBox.

#KOTLIN_EXAMPLE

#HappyCoding

Upvotes: 1

Kuvonchbek Yakubov
Kuvonchbek Yakubov

Reputation: 749

Kotlin example. You can do like this:

editText.addTextChangedListener(object: TextWatcher {
        override fun afterTextChanged(s: Editable?) {

        }

        override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

        }

        override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
            if (editText.length() < 5 || !editText.text.startsWith("+998 ")) {
                editText.setText("+998 ")
                editText.setSelection(editText.length());
            }
        }
    })

Upvotes: 4

Boycott A.I.
Boycott A.I.

Reputation: 18881

Based on ralphgabb's answer, this overcomes the problem of the caret ending up in the middle of the prefix when you do a rapid delete:

editText.addTextChangedListener(new TextWatcher() {

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
    }

    @Override
    public void afterTextChanged(Editable editable) {

        String prefix = "+63";

        int count = (editable == null) ? 0 : editable.toString().length();
        if (count < prefix.length()) {

            editText.setText(prefix);

            /*
             * This line ensure when you do a rapid delete (by holding down the
             * backspace button), the caret does not end up in the middle of the
             * prefix.
             */
            int selectionIndex = Math.max(count + 1, prefix.length());

            editText.setSelection(selectionIndex);
        }
    }
});

Upvotes: 3

ralphgabb
ralphgabb

Reputation: 10528

There may be an accepted answer here, but did not helped me at all, so for those looking for alternative way to do it heres the code.

My problem was, to prevent user to delete the first 3 characters in my EditText which is for area code of phone number (+63)

public class TextListener implements TextWatcher {

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }

    @Override
    public void afterTextChanged(Editable s) {
        if (count < 3) {
           etMobileNumber.setText("+63");
           etMobileNumber.setSelection(count + 1);
        }
    }
}

//
// use it like this
//
etMobileNumber.addTextChangedListener(new TextListener());

This way user wont be able to delete/remove the first 3 characters on my EditText and will always have a prefix at the start of the text.

Happy codings ! Cheers if you found this useful.

Upvotes: 4

PPartisan
PPartisan

Reputation: 8231

There are a few ways you can achieve this. First, you can simply have it so that if the EditText block is empty, it is immediately repopulated with a "/" char. Alternatively, make it so that if the previous char is /, then prevent the user from deleting back. The code below is untested, so you may need to tweak it a little.

editText = (EditText) findViewById(R.id.editText);
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (editText.getText().charAt(editText.length()-1) == '/') {
                editText.append(" ");
            }

            //OR...

            if (editText.length() == 0) {
                editText.setText("/")
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

Edit: FWIW, if I were in your position I would personally opt for a solution like Gabriella's and apk's combined. However, as your question was specific, I have tried to answer it directly.

Upvotes: 8

amodkanthe
amodkanthe

Reputation: 4530

rather than doing this let the user enter whatever text he wants and when you call getText() attach "/" at start as below

String text = "/"+editText.getText();

Upvotes: 1

Gabriella Angelova
Gabriella Angelova

Reputation: 2985

You could place your EditText in a separate RelativeLayout in the main Layout that you have and add one TextView with text / just before it on the same line and leave in the EditText text only the "pictures" part. Something like this:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content" >
    <TextView android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text = "/"/>
    <EditText
        android:id="@+id/etFolder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="pictures"
        android:ems="10"
        android:layout_marginLeft="10dp" >
</RelativeLayout>

Upvotes: 6

Don Chakkappan
Don Chakkappan

Reputation: 7560

You can't achieve such a behavior for EditText

But you can make some work-arounds

Use TextWatcher in Android . So you can listen to the changes in the EditText

Here is a complete Example code snippet

Upvotes: 1

Related Questions