چگونه باید برای EditText روال delete ایجاد کرد؟
سلام
ابتدا خلاصه داستان را بگم (بخش آموزشی!) تا بعد برسیم به سوال خودم:
من یک EditText دارم با نام فرضی edtTest.
فرض کنید بخواهیم کاربر را مجبور کنیم که به جای استفاده از کلید حذف روی صفحه کلید از کلید Delete ما استفاده کند. خوب واضح است یک کلید ایجاد می کنیم و در رویداد کلیک آن کد زیر را قرار می دهیم:
EditText edtTest = (EditText) finedViewById(R.id.edtTest);
Editable editable = edtTest.getText();
int start = edittext.getSelectionStart();
editable.delete(start - 1, start);
خوب تا اینجا کار همه چیز خوبه و این کد کار یک دکمه حذف معمولی را برای ما انجام می ده.
سوال:
اگر بخواهیم در روال مربوط به حذف، هر زمان که کاربر به مثلا کلمه دلخواه "Deletable" رسید کل کلمه حذف شود و نه تک تک حروف آن چه باید کرد؟ توجه کنید که می خواهیم آن کلمه حذف شود و نه اینکه کل ادیت باکس ریست شود.
توجه داشته باشید که کاربر می تواند وسط کلمه مذکور سلکتور را قرار داده باشد.
لطفا هم ایده بهم بدید که بتونم کدی براش بنویسم و یا اینکه اگر راه خلاصه ای داره و دستور خاصی داره برام توضیح بدید.
با تشکر
ویرایش:
اگه بخواهم یکم دقیق تر توضیح بدهم اینه که ما یه فرمول ریاضی داریم مثلا: Xb + (Xa)Sin a و می خواهیم وقتی کاربر شروع به حذف یا ویرایش می کند: مثلا از آخر شروع به حذف می کند با هر بار فشردن کلید حذف اول حرف "a" حذف شود و بعد "Sin" و بعد "(" و بعد "Xa" و بعد + و بعد "Xb" و اگر مثلا در وسط کلمه "Sin" هم اگر کلیک کرد و دکمه حذف را زد کل "Sin" حذف شود.
میتونید متن ادیت تکست رو null کنید!
EditText editText =(EditText)findViewById(R.id.edit_text);
editText.setText("");
من می توانم هر عبارتی را که کاربر می خواهد وارد کند بین دو علامت دلخواه مثلا به صورت عبارت زیر ذخیره کنم. خط تیره و ستاره را برای این گذاشتم تا جهت مرکز و عبارت مشخص بشه وقتی که تعداد زیادی عبارت داریم که کنار هم هستند سیستم بتونه بفهمه که روی کدوم عبارت سلکت شده.
<*->عبارت<-*>
یعنی مثلا با متنی به صورت زیر مواجه خواهیم بود:
<*->1عبارت3<-*> <*->عبارت<-*> <*->عبارت<-*> <*->عبارت<-*>
حالا می توانیم محل سلکتور را در ادیت باکس از دستور زیر استخراج کنیم:
EditText edtTest = (EditText) finedViewById(R.id.edtTest);
Editable editable = edtTest.getText();
int start = edittext.getSelectionStart();
حالا می مونه اینکه چطور عبارت مورد سلکت را پیدا کنیم؟
خوب من هنوز منتظر جواب های دوستان هستم. با این وجود کد زیر را نوشتم و البته درست کار می کنه ولی هنوز به دل خودم نچسبیده چون به نظرم باید راه شسته رفته تری هم باشه. البته در این کد بر خلاف میلم کاراکتر اسپیس را به عنوان حد فاصل بین عباراتگذاشته ام که خوب بخش زیادی از برنامه ام را دچار مشکل می کنه و باید توی اون باز بینی کنم!
این هم کد:
EditText edttest = (EditText) findViewById(R.id.edttest);
Editable editable = edttest.getText();
int start = edttest.getSelectionStart();
char[] Str2 = new char[1];
int rightIndex = 0;
int leftIndex = 0;
Log.i("log", "clicked " + start);
if (start != 0 && start != editable.length()) {
while ((leftIndex == rightIndex)) {
String str = "-";
int i = 0;
while ( !str.equals(" ")) {
editable.getChars(start + i - 1, start + i , Str2, 0);
str = new String(Str2);
if (str.equals(" ")) {
rightIndex = start + i ;
}
i++;
}
i = 0;
str = "-";
while ( !str.equals(" ") && start - i - 1 >= 0) {
editable.getChars(start - i - 1, start - i , Str2, 0);
str = new String(Str2);
if (str.equals(" ")) {
leftIndex = start - i;
}
i++;
}
editable.delete(leftIndex, rightIndex);
start--;
}
edttest.setSelection(start - 1);
}
}
توضیح:
به صورت خلاصه این کد از محل کلیک کاربر به سمت دو طرف حرکت می کنه تا به اسپیس برسه و مختصات اسپیس ها را ذخیره می کنه.
بعد از اون ما می توانیم عبارت بین این دو اسپیس را به همراه یکی از اون ها (که به عنوان قرارداد سمت راستی را) حذف می کنیم.
حلقه بزرگتر که در برگیرنده این دو حلقه است نیز برای این ایجاد شده که اگر چند اسپیس پشت سر هم داشتیم برنامه متوقف نشه و یکی یکی اون ها را رد کنه تا به نزدیک ترین عبارت برسه.
اون عبارت شرط هم که در برگیرنده کل حلقه هاست برای اینه که اکر نشانگر ابتدای باکس یا انتهای باکس بود برنامه به دلیل منفی شدن متغیرها کرش نکنه.
من خیلی متوجه قسمت های جدید سوالتون یعنی این نشانه گذاری و اینها نشدم اما برای پاک کردن کلمه ای به این شکل عمل کنید
- کلیک روی دکمه => حذف یک کارکتر
- کلیک طولانی => حدف یک کلمه
- کلیک بیشتر از 2 ثانیه => حذف کل متن
میتونید به سلیقه ی خودتون زمانبدی رو تغییر بدید - حذف یک کارکتر که سادست ، حذف یک کلمه هم میتونید با توابعی مثل indexOf و lastIndexOf و ... برسی کنید و بگید از آخرین فاصله به بعد تو رویداد لانگ کلیک پاک بشه.
خوب دوستان بالاخره با این کد تمومش کردمو خوب جواب می ده هر چند شاید کد بهینه تری هم بشه نوشت. هر چند که آخرش مجبور شدم صورت وسئله را عوض کنم!)
برای آیندگان توضیح می دهم:
توسط این کد که در روال کلیک یک دکمه قرار می گیرد با فشرده شدن دکمه کلمات حذف خواهند شد و نه تک تک حروف. فرقی هم نداره کاربر کجای متن را انتخاب کرده باشه و یا کلیک کرده باشه. اگر وسط کلمه کلیک کرده باشه که حذف می شود و اگر اول اون باشه هم تبعا کلمه قبلی حذف می شه.
EditText edttest = (EditText) findViewById(R.id.edttest);
Editable editable = edttest.getText();
int start = edttest.getSelectionStart();
char[] Str2 = new char[1];
int rightIndex = 0;
int leftIndex = 0;
rightIndex = editable.toString().indexOf(" ", start);
leftIndex = editable.toString().lastIndexOf(" ", start);
if (start == leftIndex + 1) {
start = start - 2;
rightIndex = editable.toString().indexOf(" ", start);
leftIndex = editable.toString().lastIndexOf(" ", start);
}
if (leftIndex == rightIndex) {
start = start - 1;
rightIndex = editable.toString().indexOf(" ", start);
leftIndex = editable.toString().lastIndexOf(" ", start);
}
if (rightIndex == -1) {
rightIndex = editable.length();
}
if (leftIndex == -1) {
leftIndex = 0;
editable.delete(leftIndex, rightIndex); //for seriate space deleting
با تشکر از دوستانی که کمک کردن
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .