Text watcher in edit text is making the edittext slow - android

In my tablet app I have used fragments and one fragment has multiple Edittexts, and I have a linear layout which will add a sublayout as many times the user wishes to add, in that fragment
This sublayout has two edittext, both this edittext is having
addtextchangelistener(Textwatcher) and
onfocuschangelistner
every time the text is changed 3 conditions are checked in both the edittext
every time the focus is changed 2 conditions are checked in both the edittext
After doing all this condition check, the problem I'm facing is, the edittext typing is too slow, its like i type an email and the whole email gets completely typed after 5 secs or more,
This is the code for 1 edit text in the sublayout:
receiverName.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View paramView, boolean hasFocus) {
receivernameFocus = hasFocus;
if(hasFocus)
{
if(receiverName.getText().toString().length()>0)
ReceiverName_btn_cancel.setVisibility(View.VISIBLE);
else
ReceiverName_btn_cancel.setVisibility(View.INVISIBLE);
}
else
ReceiverName_btn_cancel.setVisibility(View.INVISIBLE);
}
});
receiverName.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence paramCharSequence, int paramInt1,int paramInt2, int paramInt3) {
if(receivernameFocus)
{
if(receiverName.getText().toString().length()>0)
{
receiverNamePresent = true;
ReceiverName_btn_cancel.setVisibility(View.VISIBLE);
}
else
{
receiverNamePresent = false;
ReceiverName_btn_cancel.setVisibility(View.INVISIBLE);
}
}
else
ReceiverName_btn_cancel.setVisibility(View.INVISIBLE);
if(receiverEmailPresent && receiverNamePresent)
addReceiver.setBackgroundResource(R.drawable.plus_receiver);
else
addReceiver.setBackgroundResource(R.drawable.plus_deselect_receiver);
}
#Override
public void beforeTextChanged(CharSequence paramCharSequence,
int paramInt1, int paramInt2, int paramInt3) {
}
#Override
public void afterTextChanged(Editable paramEditable) {
}
});
same conditions are present for the other edittext, and everytime the user inflate another view, same set of edittext will be created for the new view too.
I can't remove the conditions, all of them are necessary, and you can see its just some button visibility or setting background resource
How to optimize this code, or how to speed up the edittext typing speed for android tablet?
EDIT: If I'm typing 10 letters persecond its showing only 1 letter per second in the edittext(so all the 10 letters will be visible in the edittext after 10 seconds), which I believe is happening because of multiple condition checking within onTextChanged method, the delay in showing the text is too much for user experience.
How to make the edittext show the text as fast as I'm typing it
Thanks

Here public void onTextChanged(CharSequence paramCharSequence, int paramInt1,int paramInt2, int paramInt3) it's generally in this format:
public void onTextChanged(CharSequence s, int start, int before, int count)
So here you will need to do some operation using paramInt3 . If you would like to show suggest text will come after you enter 3 letter then perform an operation here in this manner:
public void onTextChanged(CharSequence s, int start, int before, int count)
{
if (count%3 == 1)
{
adapter.clear();
GetPlaces task = new GetPlaces();
task.execute(dep_place.getText().toString());
}
}
here I haved updated text from server side in background. You just need to modify this portion from where your text will come use this code here.
Thanks.

Related

Failing to get the value of an EditText in ViewHolder of RecyclerView

In my app, I have a RecyclerView with editable EditText views as part of the ViewHolder, see picture:
The user can edit the values of the EditText views. To save the changed value back to the related adapter, set an OnFocusChangeListener to the EditText views, storing the (changed) value as soon as they loose focus, see following code snippet, taken from the onBindViewHolder method of my adapter:
// Add listener to views
holder.fpuView.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
// Focus has gone, so save value to adapter
mAbsorptionBlocks.get(position).setMaxFPU(Integer.valueOf(holder.fpuView.getText().toString()));
}
});
holder.absorptionTimeView.setOnFocusChangeListener((v, hasFocus) -> {
if (!hasFocus) {
// Focus has gone, so save value to adapter
mAbsorptionBlocks.get(position).setAbsorptionTime(Integer.valueOf(holder.absorptionTimeView.getText().toString()));
}
});
This works fine, as long as the user taps another EditText view.
It does NOT work if the user directly hits the "Save" button immediately after having changed the value of the EditText. The EditText seems not recognize that is has lost focus. This is probably due to the Save button does not belong to the RecyclerView, but to the parent activity.
I played around with other listener options, but I'm pretty lost now. Is there any chance to grasp the changed values when the user hits the Save button directly after editing the value?
You must these method of EditText
holder.fpuView.addTextChangedListener(new
TextWatcher() {
#Override
public void afterTextChanged(Editable s) {}
#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(s.length() != 0) {
mAbsorptionBlocks.get(position). setMaxFPU(Integer.valueOf(holder.fpuView.getText().toString()));
}else{
// add default value when EditText is empty.
}
}
});
Use OnTestChangeListener instead. Then catch the after text changed event or in real time if you prefer. That way you aren't relying on the focus change event to get the text.

How to focus on next edittext if there are a lot of them

I have several number of EditText's in my layout if I have to go to next EditText I have to use et1.addTextChangedListener with following code inside it:
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (et1.getText().toString().length() == 1) {
et2.requestFocus();
}
}
I know that very well, but the problem is I have from 17 up to 20 EditText's If I keep writing the code for every EditText my code will be the worst code of for the next 10 decades. How to handle this problem?
My case is very specific: when user presses a key on keyboard he need to focus on next EditText only. No ACTION_UP or ACTION_DOWN.
create a function that gets the first and second edittexts and check
public void goToAnotherEditext(final EditText et1, final EditText et2){
et1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
if(et1.getText().toString().trim().length()==1){
et2.requestFocus();
}
}
});
}
then put the edittexts inside the function
EditText et1 = new EditText(getApplicationContext());
EditText et2 = new EditText(getApplicationContext());
goToAnotherEditext(et1,et2);
In your XML file, what you can do is make your edittext,
android:singleLine="true"
and you can then add imeOptions to change your current focus to next edittext,
android:imeOptions="actionNext"
imeOptions are used to navigate to next action item focusable. to know in deep use other attribute values of imeOptions.
In this way, you don't need to make your hands dirty by performing programmatical part. you can easily do this by XML Part.

TextWatcher monitor only current input

I have EditText which is connected with TextWatcher I'm monitoring when user presses # letter. That will make a Listview appear with names of commentators on particular post. When user chooses one of the users from ListView, name is append to EditText and ListView is hidden.
But the problem is when user continues typing ListView will appear again because afterTextChanged(Editable s) monitors the whole inputted text which already contains letter #.
Is there a way to monitor only what user is actually typing not the whole inputed text? Or somehow escape last inputed word in TextWatcher? Or any other suggestions how to solve this.
I was researching but didn't find anything useful.
Thanks in advance
There can be many ways to achieve this. This is one of them. You can check weather your list is already filled or not.
final boolean isListSet = false;
public static final String textToFind = "#";
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 s) {
if (!isListSet && s.toString().contains(textToFind)) {
// set your list here
isListSet = true;
}
if (!s.toString().contains(textToFind)) {
// remove your list
isListSet = false;
}
}
});

Move focus to next EditText in an array

I have an activity in which I get from the user credit card's serial number.
It contains four editTexts - each one for 4 digits.
I've used an array for the editTexts -
EditText[] editSerial = new EditText[4];
and I've restricted the input's length in each editText with
android:maxLength="4"
I want the focus to move to the next editText once the user have entered 4 digits in the current one.
I've seen this answer - How to automatically move to the next edit text in android:
et1.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start,int before, int count)
{
// TODO Auto-generated method stub
if(et1.getText().toString().length()==size) //size as per your requirement
{
et2.requestFocus();
}
}
Is there any BETTER solution than repeat this code 3 times?
Kind of. You need a TextWatcher on each one but you can extract it as a proper class so that you can pass in parameters indicating the View to focus on next.
Then it'll be like
et1.addTextChangedListener(new FocusSwitchingTextWatcher(et2));
et2.addTextChangedListener(new FocusSwitchingTextWatcher(et3));
et3.addTextChangedListener(new FocusSwitchingTextWatcher(et4));
The class:
private static class FocusSwitchingTextWatcher implements TextWatcher {
private final View nextViewToFocus;
TextWatcher(View nextViewToFocus) {
this.nextViewToFocus = nextViewToFocus;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length > size) {
nextViewToFocus.requestFocus();
}
}
... // the other textwatcher methods
}

How do you gray out a "Submit" button when specific EditText boxes are empty?

Regarding an Android app I am creating:
I have three EditText boxes that need to be filled with numbers/strings. I have a submit button that will start a series of calculations.
IF any box is empty and submit is pressed, the app crashes. I have tried to do this with try-catch statement, but it is not working out. I simply want to disable the button until three boxes have numbers. I know there is a way to setEnabled(false) I think? Or is there a better way? Will this grey out the button? Or is that an unrelated function to setEnabled?
Try this solution.
EditText edit1;
EditText edit2;
EditText edit3;
View button;
#Override
protected void onCreate(Bundle savedInstanceState) {
// Your initialization code...
TextWatcher watcher = new LocalTextWatcher();
edit1.addTextChangedListener(watcher);
edit2.addTextChangedListener(watcher);
edit3.addTextChangedListener(watcher);
updateButtonState();
}
void updateButtonState() {
boolean enabled = checkEditText(edit1)
&& checkEditText(edit2)
&& checkEditText(edit3);
button.setEnabled(enabled);
}
private boolean checkEditText(EditText edit) {
return Integer.getInteger(edit.getText().toString()) != null;
}
private class LocalTextWatcher implements TextWatcher {
public void afterTextChanged(Editable s) {
updateButtonState();
}
void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
void onTextChanged(CharSequence s, int start, int before, int count) {
}
}
You should disable the button by default in the XML so that the user cannot hit the button by accident. After this you need to look at your fields and insure all of them have data before the submission.
You could do this, or you could just have submit run a quick check on all the fields and insure none of them are equal to "".
Basically look like this (If you want to ignore hiding the button and just handle processing after the check)
if (!((t1.getText().toString.compareTo("") == 0) && (t2.getText().toString.compareTo("")==0) ...))
{
Do stuff
}
else
{
Toast message here
}
Otherwise you can just have a "watcher" like the above poster mentioned.
You can also use this check
boolean checkEditText(EditText editText) {
return editText.getText().toString().trim().equals("");
}
Hi i have tried above code and changed the function to given below for it to work.
private boolean checkEditText(EditText edit) {
return ((edit.getText().toString()).length() >0 );
}

Categories

Resources