Как заменить определенное слово из текста
У меня есть один edittext: edittextmysite.
Теперь я хочу предоставить текст по умолчанию, например: " https://wwww.mysite.com/"
Я добился этого следующим образом:
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());
}
}
});
Поэтому, если кто-нибудь введет текст, он будет автоматически добавлен к значению по умолчанию, например так: https://wwww.mysite.com/<Mytext>
Теперь я хочу, чтобы кто-нибудь написал что-то вроде этого в edittext:
или же
или же
что он автоматически преобразует его в правильный формат, например так:
Как мне этого добиться?
10 ответов
@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());
}
}
Вот что я попробовал.
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());
}
}
}
Этот фрагмент кода не позволит вам ввести другой URL, а пользователь может вводить только строку после URL, как вы объяснили выше.
Спасибо
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());
}
});
Здесь я делюсь полным рабочим примером. Есть объяснение вместе с этим.
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());
}
}
Вы должны исправить текст префикса в EditText
который не может быть редактируемым и только пользователь может редактировать текст после base-url (как после https://wwww.mysite.com/
).
Таким образом, вы должны следовать этим шагам
- Префикс базового URL к EditText и сделать его недоступным для редактирования
- Разрешить пользователю вводить часть под URL
- Подтвердите ввод с помощью
Patterns.WEB_URL.matcher(inputUrl).matches()
для действительного URL. Вы можете добавить эту проверку в TextChange EditText или по нажатию кнопки.
Ниже приведен пользовательский код EditText, который вы можете использовать напрямую
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());
}
}
}
и в макете XML-файла это было бы как
<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" />
Вместо того, чтобы использовать android:tag
Вы можете определить пользовательский атрибут для этого текста редактирования.
И для проверки ввода вы можете проверить его как
String enteredUrl = textField.getText().toString();
if (Patterns.WEB_URL.matcher(enteredUrl).matches()) {
// Valid url
} else {
// Invalid url
}
Это работает для меня, я надеюсь, что это будет работать и для вас.
@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;
}
В этом коде я попробовал ваши входы, и это работает.
Вместо того, чтобы редактировать текст впоследствии, есть много более хороших способов сделать это:
Поместите " https://example.com/" слева от текста редактирования, а затем, если вам действительно нужно, вы можете найти в строке.com, www. И т. Д. И удалить ее, а также имя, которое они инкапсулируют, используя любой алгоритм. легко найти в Интернете. Затем объедините строки.
Используйте подсказку в тексте редактирования.
Ответ
Вы можете установить текст редактирования текста, чтобы не удалить пользователя. Таким образом, предопределенный текст останется с ediitext и автоматически добавит новый текст.
Попробуй это:
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) {
}
});
отредактированный
Если вы хотите исключить доменное имя после того, как пользователь ввел текст редактирования. Вы можете попробовать ниже код
@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());
}
}
}
Это не элегантное решение, и я предлагаю вам использовать альтернативный UX для того, что вы пытаетесь сделать полностью, но если вы действительно хотите следовать этим путем, попробуйте следующий код в вашем 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());
}
}
}
Как только пользователь начинает печатать, он устанавливает нашу базовую строку в тексте редактирования и заставляет пользователя не писать ничего, что может быть частью URI. Одна важная вещь, которую следует учитывать, когда пользователь пытается нажать клавишу Backspace, это связано с использованием специального условия, и пользователь не сможет удалить базовую строку, как только он начнет печатать.
Примечание: это решение также может быть оптимизировано
Вы можете просто сохранить его как строку, а затем простоString newReplacedString = stringtoReplace.replace("Phrase To Replace", "WHAT TO REPLACE WITH");