Progreess Bar tracking multiple TextField states - java

I'd like to have a progress bar that tracks a user's form progress. For example:
TextFieldName: _______
TextFieldPhone: ________
With both fields empty, the progress bar should read 0%. If the user has filled out one of either their name or phone, the progress bar should update to 50%. If the user has filled out both name and phone, the progress bar should read 100%.
I have tried to approach the problem, but I can't deal with the fact that there should be some sort of global variable that's stored somewhere that can be grabbed at any time between edits (also not sure where that would be as I am new to this). Here is my code:
binding.progressBarNewRelease.setProgress(0);
float numInputs = 20;
float increment = (1 / numInputs) * 100;
binding.textInputEditTrackName.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
int currProgress = binding.progressBarNewRelease.getProgress();
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().length() > 0) {
binding.progressBarNewRelease.incrementProgressBy((int)increment);
}
else {
binding.progressBarNewRelease.incrementProgressBy((int)-increment);
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
binding.textInputEditArtist.addTextChangedListener(...); // similar code for artist name field
I have been playing around with the code a bit so it's missing most of what I have tried like setting the maxProgress to (currentProgress + increment) to prevent additional increments once the field is not empty.
Also, if there is a way, I would like to avoid having to have multiple bindings for each field, but if that is unavoidable then I understand.
EDIT
I have achieved the initial functionality I was looking for by using a combination of beforeTextChanged and onTextChanged, although I am a little skeptical about whether it covers all edge cases:
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().length() == 0) {
binding.progressBarNewRelease.incrementProgressBy((int)increment);
}
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (charSequence.toString().length() == 0) {
binding.progressBarNewRelease.incrementProgressBy((int)-increment);
}
}
I am also now setting the progress bar's max to the number of fields, and incrementing/subtracting by 1 for each field. Additionally, rather than new TextWatcher(), I am also now using a shared function where possible, which reduces amount of code.
Going to explore getting all the logic right, but still looking for how I could avoid having to repeat the same code for every field. For example, this is how I am handling multiple buttons:
MaterialButtonToggleGroup.OnButtonCheckedListener gridRowButtonListener = new MaterialButtonToggleGroup
.OnButtonCheckedListener() {
#Override
public void onButtonChecked(MaterialButtonToggleGroup group, int checkedId, boolean isChecked) {
if (isChecked) {
binding.progressBarNewRelease.incrementProgressBy(1);
}
else {
binding.progressBarNewRelease.incrementProgressBy(-1);
}
}
};
binding.buttonsGridRowOne.addOnButtonCheckedListener(gridRowButtonListener);
binding.buttonsGridRowTwo.addOnButtonCheckedListener(gridRowButtonListener);
binding.buttonsGridRowThree.addOnButtonCheckedListener(gridRowButtonListener);
binding.buttonsGridRowFour.addOnButtonCheckedListener(gridRowButtonListener);

Related

TextWatcher overrides not called when we backspace remove last character. How do I know if the last character is removed?

I'm trying to save what's being typed on an EditText. When the user types some text, text watcher works fine. When the user removes text, the text watcher works fine until the user removes the last character.
answerEditText.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) {
saveAnswer(editable.toString())
}
});
What is expect saveAnswer to get when the last character is removed is an empty string. But the actual result is that it is not triggered.
Use TextWatcher and onTextChange method to track user input, when user write something inside watcher first time, then yourself store the text and keep checking diff yourself. Since onTextChanged is fired everytime when user changes the character.
String userInputText=userText.getString().toString();
#Override
onTextChanged(CharSequence s, int start, int before, int count){
compareText(s, userInputText); //compare and do whatever you need to do
previousText = s;
}

user input run time android

I am trying to build a simple converter code(convert feet to mtr) in Android. I am able to do this but only when user clicks some button. Now I want to modify it such that it starts to convert as and when the user gives input(Something like google converter). Is there any way to do this in Android?
Thanks in advance.
Add the listener to your edittext:
yourEditText.addTextChangedListener(addTextWatcher);
Add the TextWatcher interface:
private TextWatcher addTextWatcher = new TextWatcher() {
#Override
public void onTextChanged(CharSequence sequence, int start, int before, int count) {
// here is where you could grab the contents of the edittext
// input each time a character is entered, and pass the value
// off to your unit conversion code. Careful to check for
// numerals/decimals only, or to set the proper inputType in
// your xml.
}
#Override
public void beforeTextChanged(CharSequence sequence, int start, int count, int after) {
}
#Override
public void afterTextChanged(Editable sequence) {
}
};

Android Studio : Converting numbers in real time

For AndroidStudio, I am creating a simple conversion app that allows you to convert kilometres to miles and vice versa. I am able to convert it by clicking a button, but how would you do it in real time? For example, as I am typing the number, it converts it right away in a different textbox.
This is the code for my onClick method that I created for my button:
public void onClick(View vw){
EditText value = (EditText)findViewById(R.id.editText);
double total = Double.parseDouble(value.getText().toString()) * 0.621371192;
TextView obj = (TextView)findViewById(R.id.milesDisplay);
obj.setText(Double.toString(total));
obj.setVisibility(View.VISIBLE);
}
You can do this if you're using an EditText:
mEditText.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) {
// Every time you hit a number, capture the number and convert it
}
#Override
public void afterTextChanged(Editable s) {
}
});
inside onTextChanged a listener is trigged every time you hit the keyboard. Force it to only accept numbers.

MultiAutocompleteTextView events

I'm trying to work with a MultiAutocompleteTextView in such way that whenever I type a character in the textview, an event will be fired OR after 2-3 elements have been typed, fire the event again.
The reason I work with multiautocomplete is because I also need the autocompletion feature .
Is there such an event that can be triggered after every character or 2-3 characters typed? Thanks!
Yes you can use add a TextWatcher and TextChangedListener to your edit Text like this:
myEditText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//check count or count in edit text and do something
}
#Override
public void afterTextChanged(Editable arg0) {
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
});
http://developer.android.com/reference/android/text/TextWatcher.html

KeyReleased equivalence in Android

On PC I can add a onKeyListener for a JTextField to listen keyReleased event. On Android I've used addTextChangedListener.
I have two EditText fields in my Android application. Editing one will affect the other. This will cause the program to fail in stack overflow error.
How can I listen for the phone's keyboard instead of changes in the EditText field? I don't want the program to invoke the listener because of the infinite loop caused by the listener.
Attach a onFocusChangedListener and add the TextChangedListener when a EditText has focus and remove it when it loses focus.
Something like this:
EditText1.setOnFocusChangeListener(new OnFocusChangeListener() {
public void onFocusChange(View v, boolean hasFocus) {
if(hasFocus){
((EditText) v).addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before, int count) {
//
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
//
}
public void afterTextChanged(Editable s) {
// affect EditText2
}
});
}
if(!hasFocus){
((EditText) v).removeTextChangedListener();
}
}
});
}
});
The same for EditText2
First of all, I would create one text change listener, something like SynchronizingWatcher and attach it to both EditTexts. Then, when you receive a text change event, before updating other text edits, just unregister old listeners, update text and enable listeners again:
class SynchronizingWatcher implements TextWatcher {
Set<EditText> synchronizedViews = new HashSet<EditText>();
public void watchView(EditText view) {
view.addTextChangedListener(this);
synchronizedViews.add(view);
}
public void afterTextChanged(Editable s) {
for (EditText editText : synchronizedViews) {
editText.removeTextChangeListener(this);
editText.setText(s); // Of course you can do something more complicated here.
editText.addTextChangeListener(this);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Don't care.
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Don't care.
}
}
...
// Somewhere in your activity:
SyncrhonizingWatcher synchronizingWatcher = new SynchronizingWatcher();
synchronizingWatcher.watchView(myEditText1);
synchronizingWatcher.watchView(myEditText1);
Another solution: provide your own KeyListener that decorates existing KeyListener (you can get existing key listener with editText.getKeyListener() and set your decorator with editText.setKeyListener(). Your decorator would also update other edit texts in onKeyUp(). But I would try to stay away from messing with that stuff.

Categories