I have a form in an Android application used for setting up matches for a particular sport. I am able to successfully validate the inputs to exclude stuff (using TextWatcher), but not to enforce minimum input.
Although there is a means within XML to have minimum input in a certain field, I would prefer to do this programatically. Moreover, someone could still just ignore the fields altogether and just press the button to start the match (will result in application crashing).
If anyone has any suggestions I would really appreciate it - there doesn't seem to be a great deal of information about this available online (or I've been looking the wrong way).
I've excluded all but two fields in the form (teamA name and matchlength) for the sake of simplicity (Strings and ints are the only input "types").
public class MatchConfig extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_match_config);
// Show the Up button in the action bar.
setupActionBar();
final Context context = getApplicationContext();
final EditText teamA = (EditText) findViewById(R.id.teamA_editText); //Team A input
teamA.addTextChangedListener(new TextWatcher(){
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
#Override
public void beforeTextChanged(CharSequence s,int start,int count,int after)
{}
#Override
public void afterTextChanged(Editable s) //Team A validation
{
String filtered_str = s.toString();
if (filtered_str.matches(".*[^A-Za-z^0-9].*")) { //if not alphanumeric
filtered_str = filtered_str.replaceAll("[^A-Za-z^0-9]", "");
s.clear();
s.append(filtered_str);
// s.insert(0, filtered_str);
Toast.makeText(context, //warning Toast
"Only letters and numbers are allowed!",
Toast.LENGTH_SHORT).show();
}
}
});
final EditText matchlength = (EditText) findViewById(R.id.stones_editText); //matchlength input
matchlength.addTextChangedListener(new TextWatcher(){
#Override
public void onTextChanged(CharSequence s, int start, int before, int count)
{}
#Override
public void beforeTextChanged(CharSequence s,int start,int count,int after)
{}
#Override
public void afterTextChanged(Editable s) //matchlength validation
{
int no=Integer.parseInt(s.toString());
if(no>999)
{
s.replace(0,s.length(), "999");
Toast.makeText(context,
"999 minutes is max length!",
Toast.LENGTH_SHORT).show();
}
}
});
final EditText location = (EditText) findViewById(R.id.location_editText);
Button start = (Button) findViewById(R.id.start_button);
start.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent theIntent = new Intent(MatchConfig.this, MatchTimer.class);
theIntent.putExtra("teamAvar", teamA.getText().toString());
theIntent.putExtra("matchlengthVar", Integer.parseInt(matchlength.getText().toString()));
startActivity(theIntent);
//this finish() will close the MatchConfig Activity when start button will be pressed
finish();
}
});
Check the lengths when you click the start button:
if(teamA.getText().length() < 5){ //5 char min
//Show error
}
else{
//Do match
}
Related
I'm using editText in recyclerView, I want to display or edit the 2nd one only if the 1st is filled android java.
This is a quick solution of mine:
In your adapter, create a flag int currentFilled = -1;
and update this flag whenever your editText is filled
Like this:
EditText edt1 = new EditText(this);
edt1.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) { }
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() >0){
// this is when your edt1 is filled
// edt2.setEnabled(true); // You can enable your edt2 or whatever here
// edt2.setVisibility(View.VISIBLE);
currentFilled = itemPosition;
notifyItemChanged(itemPosition+1) // position you wan to display or edit the edt
} else {
// when edt1 is not filled
/// TODO do what ever you want
}
}
});
Then in your ViewHolder check if currentFilled == itemPosition-1
==>>
edt.setEnabled(true); // You can enable your edt2 or whatever here
// or
edt.setVisibility(View.VISIBLE)
it's may get some issues or not depending on your requirements.
Happy coding :))
Trying to get an integer from Edit Text entered by the user(such as Total Amount) and to display it by multiplying with value(such as 5%) and display it using TextView automatically.
For the 1st part i.e. simply displaying the integer from EditText to TextView got NumberFormatException Error.
'''
temp = (Integer.parseInt(editText.getText().toString()));
textView.setText(temp);
'''
And for the second part i.e. automatically displaying the value from EditText to TextView, no idea how to approach.
Just use textwatcher and put the logic in it. Just make sure change the id of edittext and textview
et.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) {
String value = s.toString();
double outputValue = Integer.parseInt(value) * 0.05;
textView.setText(String.valueOf(outputValue));
}
});
Make sure in edittext that it only capture the numerical value.
you could try this approach
editText.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void afterTextChanged(Editable s) {
String userInputText = s.toString();
try {
val userInputAsNumbger = userInputText.toInt();
}catch (e:NumberFormatException){
print(e.message)
}
}
});
to ensure it doesn't error
I have 2 buttons and 1 number field, if I press a button without something in the field, it crashes, so what I want to do is disable the buttons unless the number field has something in it, I have looked around for an answer but either they aren't relevant, or I'm not sure how it would fit into my code, here are the two onClick functions for each button. Thanks
public void toPounds(View view){
EditText amount = (EditText)findViewById(R.id.amount);
Double omrAmount = Double.parseDouble(amount.getText().toString());
Double gbrAmount = omrAmount * 1.79;
Toast.makeText(getApplicationContext(), "£" + gbrAmount.toString(), Toast.LENGTH_LONG).show();
}
public void toRiyals(View view){
EditText amount = (EditText)findViewById(R.id.amount);
Double gbrAmount = Double.parseDouble(amount.getText().toString());
Double omrAmount = gbrAmount / 1.79;
Toast.makeText(getApplicationContext(), omrAmount.toString() + " Riyals", Toast.LENGTH_LONG).show();
}
yourField.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)
button1.setEnabled(false)
else
button1.setEnabled(true)
}
});
link
If you want to disable buttons if edit text is empty then you can do the following :
EditText amount = (EditText)findViewById(R.id.amount);
Button button = (Button) findViewById(R.id.button1);
if(amount.getText().toString().isEmpty()){
button.setEnabled(false);
}
amount.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)
button1.setEnabled(false)
else
button1.setEnabled(true)
}
});
Not specifically an answer to your question, but generally speaking you would want to add some sort of check before you call your code which now crashes your application. It's not a good idea to to have code which crashes your app lingering around.
Maybe make a method like: isMyEditTextValid(...){..}
I am doing a chat app and got stocked on how to make textWatcher which will push on the firebase data structure under user-typing
. I want to push a data structure wherein on the data structure you will see if the user is typing. when the user is typing the data structure under user-typing is true. if the user is not typing then it will become false. i tried this code but it seems wrong because every time i run the program. When I click the ediText. it will automatically make a data structure key for a user
final Firebase test = firebase.child("room-typing").push();
test.setValue("true");
final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (s == editText) {
firebase.child("room-typing").child(test.getKey()).child("test").setValue("true");
} else {
firebase.child("room-typing").child(test.getKey()).child("test").setValue("false");
}
}
});
You're creating that new key yourself, by calling push(). From the documentation for push():
Generates a new child location using a unique key and returns a Firebase reference to it.
I added some comments to you code, to mark where things happen:
// This next line creates a new key
final Firebase test = firebase.child("room-typing").push();
test.setValue("true");
final EditText editText = (EditText) findViewById(R.id.editText);
editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (s == editText) {
// This next line uses the new key you created above
firebase.child("room-typing").child(test.getKey()).child("Onediver").setValue("true");
} else {
// As does the next line here
firebase.child("room-typing").child(test.getKey()).child("Onediver").setValue("false");
}
}
});
To prevent the creation of a new child, you should not call push, but depend on a known child, such as:
final Firebase test = firebase.child("room-typing").child("jaymee");
There are 2 ways you can do this. An easy way and there is an elegant way.
For elegant way look into: http://reactivex.io/documentation/operators/debounce.html
Here's the easy way:
Create somewhere a custom countdown timer:
public class MyCountDownTimmer extends CountDownTimer {
public MyCountDownTimmer(long millisInFuture, long countDownInterval) {
super(millisInFuture, countDownInterval);
}
#Override public void onTick(long l) {
}
#Override public void onFinish() {
databaseReference.child("room-typing").child(room_name).child(user_id_or_name).setValue("false");
isTyping = false;
}
}
Declare your countdown timer
private MyCountDownTimmer isTypingTimmer = new MyCountDownTimmer(1000, 1000);
private boolean isTyping = false;
editText_message.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
isTypingTimmer.cancel();
isTypingTimmer.start();
if (!isTyping) {
databaseReference.child("room-typing").child(room_name).child(user_id_or_name).setValue("true");
isTyping = true;
}
}
});
I'm trying to get what modification user has made to EditText, either insert or delete. I use TextWatcher but I don't get right result, moreover sometimes "getChar(start, end) has end before start" error.
editText = (EditText) findViewById(R.id.MyEditText);
editText.addTextChangedListener(new TextWatcher() {
#override
public void afterTextChanged(Editable s){}
#override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
showToast("text removed: " + s.subSequence(start, count));
}
#override
public void onTextChanged(CharSequence s, int start, int before, int count){
showToast("text added: " + s.subSequence(start, count));
}
}
As you can see I use beforeTextChanged to get any text that's removed by user, and onTextChanged for insertion. Please shed some light here. Thanks!
API is right here: http://developer.android.com/reference/android/text/TextWatcher.html#afterTextChanged(android.text.Editable)
EDIT:
I seem to figure it out...it's quite silly: s.subSequence(start, count)) should really be s.subSequence(start, start+count))
Just keep your functions inside the afterTextChanged and see what happens
Sample Code
seachbox.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
fillData(SEARCH_ORDER ,s.toString());
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
});
I hope it will work
Try this, I'm not sure whether you want the remaining word(after insert/update) or the letter(added/removed).
public class MainActivity extends Activity implements TextWatcher {
private EditText myEditText;
private String inputText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
myEditText = (EditText) findViewById(R.id.testEditText);
myEditText.addTextChangedListener(this);
}
#Override
public void afterTextChanged(Editable s) {
if (inputText.length() < s.toString().length()) {
Toast.makeText(
this,
("Text Added: " + s.toString().substring(inputText.length(),
s.toString().length())), Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(
this,
("Text Removed: " + inputText.substring(s.toString().length(),
inputText.length())), Toast.LENGTH_SHORT).show();
}
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
inputText = s.toString();
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
}