5

I have one edittext: edittextmysite.

Now I want to provide default text, for example: "https://wwww.mysite.com/"

I have achieved it this as follows:

edittextmysite.setText("https://wwww.mysite.com/");
Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());


edittextmysite.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 s) {
                if (!s.toString().contains("https://wwww.mysite.com/")) {
                    edittextmysite.setText("https://wwww.mysite.com/");
                    Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
                }

            }
        });

So if anyone enters text it will automatically be appended to the default, like this: https://wwww.mysite.com/<Mytext>

Now what I want is if anyone writes something like this in edittext:

https://wwww.mysite.com/https://wwww.mysite.com/helloworld

or

https://wwww.mysite.com/wwww.mysite.com/helloworld

or

https://wwww.mysite.com/wwww.anyothersite.com/helloworld

that it will automatically convert it to the correct format, like this:

https://wwww.mysite.com/helloworld

How can I achieve this?

Cindy Meister
  • 25,071
  • 21
  • 34
  • 43
  • 1
    As far as in get you.. get last index of `.com` string and concat it to your url i.e `https://wwww.mysite.com/` – Iamat8 Jul 04 '18 at 07:29
  • Why don't you replace the single EditText with a TextView containing your url side by side with an EditText where the user can append what he wants and then concatenate the 2 strings? –  Jul 07 '18 at 18:53
  • Did you checked my answer https://stackoverflow.com/questions/51167952/how-to-replace-particular-word-from-edidtext/51319515#51319515 ? – Gunaseelan Jul 14 '18 at 14:27

10 Answers10

5
@Override
public void afterTextChanged(Editable s) {
    if (!s.toString().contains("https://wwww.mysite.com/")) {
        String text = s.toString.subString(0, s.lastIndexOf("/"));
        edittextmysite.setText(s.toString().replace(text, "https://wwww.mysite.com/");
        Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
    }
}
Vinay Rathod
  • 1,262
  • 1
  • 10
  • 19
1

Here is what i have tried.

private String str = "https://wwww.mysite.com/";

 @Override
        public void afterTextChanged(Editable s) {
            if (!s.toString().contains("https://wwww.mysite.com/")) {
                edittextmysite.setText("https://wwww.mysite.com/");
                Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
            }

            String s1 = s.toString();
            String s2 = s1.substring(str.length());

            if(s2.contains("/")) {
                String s3 = s1.substring(str.length());
                if (Patterns.WEB_URL.matcher(s3).matches()) {
                    // Valid url
                    edittextmysite.setText(s.toString().replace(s3, ""));
                    Selection.setSelection(edittextmysite.getText(), edittextmysite.getText().length());
                }
            }

        }

This piece of code won't allow you to enter another URL and user can only enter string after URL as you explained above.

Thanks

suprita
  • 211
  • 1
  • 9
1
edittextmysite.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 s) {
                if(edittextmysite.getText().toString().length() == 0)
                    edittextmysite.setText("https://wwww.mysite.com/" + s.toString());
                else
                    edittextmysite.append(s.toString());

            }
        });
Dhara Jani
  • 461
  • 3
  • 10
0

Rather that editing the text afterwards, there are many nicer ways to accomplish this:

  • Place "https://example.com/" on the left of the edittext, then if you really have to, you can search the string for .com, www., etc. and remove it and the name they encapsulate using any algorithm found easily on the web. Then concatenate the strings.

  • Use a hint in the edittext.

TheChubbyPanda
  • 1,721
  • 2
  • 16
  • 37
0

here I have sharing complete working example. There is explanation along with it.

public class MainActivity extends AppCompatActivity implements TextWatcher {

    String BASE_URL = "https://wwww.mysite.com";
    EditText editText;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /*paste this editText --> https://wwww.mysite.com/https://wwww.mysite.com/helloworld  <--*/

        editText = findViewById(R.id.et);
        editText.addTextChangedListener(this);

    }

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

    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        String text = s.toString().trim();
        editText.removeTextChangedListener(this);
        if (text.length() > 0) {
            if (!text.contains(BASE_URL)) {
                String tempText = BASE_URL +"/"+ text;
                editText.setText(tempText);        //setting text here
                proceed(tempText);    //sending here for further test, if pasted the link
            } else {
                proceed(text);
            }
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }

    private void proceed(String text) {
        String newText="";
        String firstHalf = text.substring(0,text.lastIndexOf('/'));
        String secondHalf = text.substring(text.lastIndexOf('/',(text.length()-1)));

        String[] words = firstHalf.split("/");    //Split the word from String
        for (int i = 0; i < words.length; i++){        //Outer loop for Comparison
            if (words[i] != null) {
                for (int j = i + 1; j < words.length; j++){    //Inner loop for Comparison
                    if (words[i].equals(words[j]))    //Checking for both strings are equal
                        words[j] = null;            //Delete the duplicate words
                }
            }
        }

        //Displaying the String without duplicate words{
        for (int k = 0; k < words.length; k++){
            if (words[k] != null)
                newText=newText+words[k];
        }


        StringBuffer formattedText = new StringBuffer((newText+secondHalf));
        formattedText.insert(6,"//");       //length of https;//

        editText.setText(formattedText);


        //attaching textwatcher again
        editText.addTextChangedListener(this);

        //moving cusor pointer to the end point
        editText.setSelection(editText.getText().toString().length());
    }
}
Ranjan
  • 1,326
  • 18
  • 38
0

You should fix the prefix text into EditText which can not be editable and user only can edit the text after base-url (like after https://wwww.mysite.com/ ).

So you should follow these steps

  1. Prefix the base url to EditText and make it un-editable
  2. Let user enter sub part of the url
  3. Validate input with Patterns.WEB_URL.matcher(inputUrl).matches() for valid url. You can add this validation on TextChange of EditText or on click of a button.

Below is a custom EditText code which you can use directly


public class UrlEditText extends AppCompatEditText {
    float mLeftPadding = -1;

    public UrlEditText(Context context) {
        super(context);
    }

    public UrlEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public UrlEditText(Context context, AttributeSet attrs,
                       int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec,
                             int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        initPrefix();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        String prefix = (String) getTag();
        canvas.drawText(prefix, mLeftPadding,
                getLineBounds(0, null), getPaint());
    }

    private void initPrefix() {
        if (mLeftPadding == -1) {
            String prefix = (String) getTag();
            float[] widths = new float[prefix.length()];
            getPaint().getTextWidths(prefix, widths);
            float textWidth = 0;
            for (float w : widths) {
                textWidth += w;
            }
            mLeftPadding = getCompoundPaddingLeft();
            setPadding((int) (textWidth + mLeftPadding),
                    getPaddingRight(), getPaddingTop(),
                    getPaddingBottom());
        }
    }
}

and in layout xml file, it would be like

<com.path_of_custom_view.UrlEditText
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:tag="https://wwww.mysite.com/"
    android:text="helloworld" />

Instead of using android:tag you can define custom attribute for this edittext.

And for input validation you can validate it like

String enteredUrl = textField.getText().toString();
if (Patterns.WEB_URL.matcher(enteredUrl).matches()) {
    // Valid url
} else {
    // Invalid url
}
Pankaj Kumar
  • 81,967
  • 29
  • 167
  • 186
  • This is works but its shows white color if i will write again https//www.mysite.com –  Jul 12 '18 at 18:34
  • @deepak remove all of your validation for sort time if you implemented and then check. Reason is, no code added into custom edittext to validate if same text has been entered again. So please check and confirm. – Pankaj Kumar Jul 13 '18 at 04:58
  • Yes I have removed all my validation while checking your code. –  Jul 13 '18 at 06:05
  • @deepak share your current code at somewhere on code repo. Will check – Pankaj Kumar Jul 13 '18 at 06:53
0

You can Just store it as String and than simply
String newReplacedString = stringtoReplace.replace("Phrase To Replace", "WHAT TO REPLACE WITH");

skryshtafovych
  • 572
  • 4
  • 16
0

This one works for me, I hope this will work for you too.

@Override
public void afterTextChanged(Editable s) {
    String text = edittextmysite.getText().toString();
    String URL = "https://www.example.com/";
    if (text.contains(URL)) {
        String url = getUrl(URL, text);
        if (!text.equals(url)) {
            edittextmysite.setText(url);
            edittextmysite.setSelection(url.length());
        }
    } else {
        String tempUrl = URL + text;
        String url = getUrl(URL, tempUrl);
        if (!tempUrl.equals(url)) {
            edittextmysite.setText(url);
            edittextmysite.setSelection(url.length());
        } else if (!text.contains(URL)) {
            edittextmysite.setText(URL);
            edittextmysite.setSelection(URL.length());
        }
    }
}

private String getUrl(String URL, String text) {
    String urls[] = text.split("(?<!/)/(?!/)");
    Log.v(TAG, Arrays.toString(urls));
    String lastWord = urls[urls.length - 1];
    String lastChar = text.substring(text.length() - 1);
    if (lastChar.equals("/"))
        lastWord = lastWord.concat(lastChar);
    for (String url : urls) {
        url = url.concat("/");
        if (Patterns.WEB_URL.matcher(url).matches()) {
            if (url.equals(URL)) {
                if (!lastWord.contains("/"))
                    return url + lastWord;
                else return text;
            }
        }
    }
    return URL;
}

In this code I tried your inputs, and its working.

Gunaseelan
  • 14,415
  • 11
  • 80
  • 128
0

It's not an elegant solution and I suggest you to use alternative UX for what you are trying to do entirely but if you really want to pursue this way then try the following code in your TextWatcher,

final String baseString="https://wwww.mysite.com/";
 @Override
 public void afterTextChanged(Editable s) {
             if(!s.toString().contains(baseString)){
                editText.setText(baseString+s.toString());
                editText.setSelection(editText.length());
            }else {
                String regex = "\\b(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

                Pattern pattern=Pattern.compile(regex);

                String subStr=s.toString().substring(baseString.length());
                Matcher matcher= pattern.matcher(subStr);

                if(matcher.matches()){
                    editText.setText(baseString+subStr.replaceAll(regex,""));
                    editText.setSelection(editText.length());
                }else if(subStr.contains("https:")){
                    editText.setText(baseString+subStr.replace("https:",""));
                    editText.setSelection(editText.length());
                }else if(subStr.contains("www.")){
                    editText.setText(baseString+subStr.replace("www.",""));
                    editText.setSelection(editText.length());
                }else if(subStr.contains(".")){
                    editText.setText(baseString+subStr.replaceAll("\\.",""));
                    editText.setSelection(editText.length());
                }else if(subStr.contains("//")){
                    editText.setText(baseString+subStr.replaceAll("//",""));
                    editText.setSelection(editText.length());
                }else if(subStr.contains(":")){
                    editText.setText(baseString+subStr.replaceAll(":",""));
                    editText.setSelection(editText.length());
                }

            }

}

Once user starts typing, it sets our base string in the edittext and forces user not to write anything that can be a part of uri. One important thing to consider when user is trying to hit backspace, this is taken care of using the special condition and user won't be able to remove base string once he/she starts typing.

Note: This solution can be optimized as well

MRah
  • 940
  • 6
  • 15
0

Answer

You can set edittext text to not remove by user. So the predefined text will stay with ediitext and automatically append the new text.

Try this:

private EditText et;
private String str_value = "http://example.com/";
private String added_str;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    et = findViewById(R.id.edittext);

    et.setText(str_value);
    et.setSelection(str_value.length());
    et.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(start == str_value.length() - 1)
            {
                et.setText(str_value);
                et.setSelection(str_value.length());
            }
        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });

Edited

If you want elimnate the domain name after user entered in the edittext. You can try below code

 @Override
        public void afterTextChanged(Editable s) {

            if(s.length() > str_value.length()) {
                added_str = s.toString().substring(str_value.length(), s.length()); //this will get text after predefined text.

                if(Patterns.DOMAIN_NAME.matcher(added_str).matches() || added_str.contains("http:"))
                {
                    et.setText(str_value);
                    et.setSelection(str_value.length());
                }

            }
        }
Mohamed Mohaideen AH
  • 2,527
  • 1
  • 16
  • 24