I use the FormEditText widget for a form (obviously). Thing is: After being tested not valid once, the warning red exclamation mark won't disappear even after entering a correct input and the field.testValidity() returning true. I also haven't found a method of FormEditText to manually clear it.
Anyone else experienced this?
This is the method I use when the send button is tapped from the action bar:
public boolean checkFields() {
FormEditText[] allFields = { firstname, lastname, street, zip, city,
email, phone };
boolean allValid = true;
FormEditText firstFailedField = null;
for (FormEditText field : allFields) {
if (!field.testValidity()) {
Log.d("FOR", "failed field: " + field.getHint());
allValid = false;
if (firstFailedField == null) {
firstFailedField = field;
}
}
}
if (allValid) {
} else {
firstFailedField.requestFocus();
}
return allValid;
}
And this is part of my layout:
<com.andreabaccega.widget.FormEditText
android:id="#+id/firstname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Vorname"
android:inputType="textPersonName"
android:singleLine="true"
whatever:customRegexp="[a-zA-Z]{2,}"
whatever:emptyErrorString="Bitte Vornamen angeben"
whatever:testErrorString="Bitte Vornamen angeben"
whatever:testType="regexp" >
</com.andreabaccega.widget.FormEditText>
<com.andreabaccega.widget.FormEditText
android:id="#+id/lastname"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:ems="10"
android:hint="Nachname"
android:inputType="textPersonName"
android:singleLine="true"
whatever:customRegexp="[a-zA-Z]{2,}"
whatever:emptyErrorString="Bitte Nachnamen angeben"
whatever:testErrorString="Bitte Nachnamen angeben"
whatever:testType="regexp" >
</com.andreabaccega.widget.FormEditText>
I entered Kim in the firstname field, pressed send. Theres a warning on the lastname field. Enter Jong in the lastname field, but the exclamation mark won't hide. And the field does test valid!
As suggested I'll post my comment as an answer:
You can try field.setError(null): in this way you can hide the error from an EditText. It should work for FormEditText since FormEditText extends EditText.
Related
I am new to android development and still learning the basics.
What I'm attempting to do is extract the user message from the Edit text, that is the user's name, and then begin another activity if the user clicks the button below the edit text.
But the condition is that the length of the name must not be 0 else, a toast message will be flashed saying to Enter The Name.
However, when I try to do so, the toast message appears even if the length of the name is greater than zero.
I'll be very thankful if someone helps me with this out.
MainActivity.kt
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button: Button = findViewById(R.id.button)
val editText = findViewById<EditText>(R.id.name_txt)
val name = editText.text.toString()
button.setOnClickListener {
if (name.isEmpty()) {
Toast.makeText(this, "Please Enter Your Name", Toast.LENGTH_LONG).show()
} else {
Toast.makeText(this, "Sent to Next Activity", Toast.LENGTH_LONG).show()
val intent = Intent(this, SecondActivity::class.java).apply {
putExtra(EXTRA_MESSAGE, name)
}
startActivity(intent)
}
}
}
activity_mai.xml
<EditText
android:id="#+id/name_txt"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Your Name"
android:maxLength="20"
android:inputType="textPersonName"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.028"
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Send Information"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/name_txt"
app:layout_constraintVertical_bias="0.168" />
The API is working correctly, you are using it wrong. When you execute this code
val name = editText.text.toString()
The name variable will be initialized with the value from the EditText at that point (in this case it will return an empty string). Any future modifications of the text inside the EditText will not be reflected in this variable (it's only one time query).
You would have to refactor the code to query the EditText each time you wand to perform the validation.
button.setOnClickListener {
val name = editText.text.toString()
if (name.isEmpty()) {
....
You can either use String.isNullOrEmpty or TextUtils.isEmpty (they essentially do the same thing).
Also, as lulianPopescu pointed out, you need to get the text of the EditText inside the setOnClickListener(). As of now, you're getting the text even before you can enter any text.
val name = editText.text.trim().toString() //This will remove all white spaces
Try writing inside onClickListener
First of all, if anything can be better in my question, please let me know, it's my first one here.
I am building an app for android.
I want my users to be able to enter a time in an edittext field quickly. There usually already is a time in there, which should be selected so any input from keyboard will result in it being overwritten, while just hitting "next" (or enter on keyboard" will leave it the way it is and jump to the next field.
For all my fields this works nicely, but for some reason I cannot grasp, the text in this specific field (and its twin) won't get selected no matter what I tried.
I putandroid:selectAllOnFocus="true" in the res file, and when that didn't work I also put v.selectAll() in its onFocusChangedListener.
flighttOutStringField?.onFocusChangeListener = View.OnFocusChangeListener { v, hasFocus ->
if (hasFocus) {
with(v as TextInputEditText) {
previousText = this.text.toString()
v.selectAll()
}
} else {
with(v as TextInputEditText) {
val currentText = this.text.toString()
if (!(("([01]\\d|2[0-3]):[0-5]\\d".toRegex().containsMatchIn(currentText) && currentText.length == 5)
|| ("([01]\\d|2[0-3])[0-5]\\d".toRegex().containsMatchIn(
currentText.padStart(
4,
'0'
)
) && currentText.length <= 4))
|| (currentText == "")
)
this.setText(previousText) // not a valid new entry, so no update on flight
else {
this.setText(
if (currentText.length < 5) "${currentText.padStart(
4,
'0')
.slice(0..1)}:${currentText.padStart(4, '0').slice(2..3)}" else currentText)
flight = flight.copy (tOutString = "${date?.format(DateTimeFormatter.ISO_DATE)}T${this.text}:00", changed = 1)
}
}
}
updating the "flight" var will refill all fields through its setter.
<android.support.design.widget.TextInputLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:id="#+id/flighttOutStringWrapper"
app:layout_constraintStart_toEndOf="#+id/flighttOutSelector" android:layout_marginTop="4dp"
app:layout_constraintTop_toBottomOf="#+id/flightOrigWrapper"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintEnd_toStartOf="#+id/flighttInStringWrapper">
<android.support.design.widget.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="time"
android:ems="10"
android:id="#+id/flighttOutStringField"
android:textAlignment="center"
android:includeFontPadding="false"
android:hint="#string/timeOut"
android:nextFocusForward="#id/flighttInStringField" android:imeOptions="actionNext"
android:selectAllOnFocus="true"/>
</android.support.design.widget.TextInputLayout>
I would think that upon selecting the TextInputEditText, all text would be selected, but it isn't.
Then, I thought the v.selectAll() would do that for me, but it also doesn't.
Try this
v.setOnFocusChangeListener(null)
v.clearFocus();
v.requestFocus();
v.selectAll()
v.setOnFocusChangeListener(listener)
I have a form with multiple EditText items each wrapped in a TextInputLayout. When clicking the Submit button, I check to see if the EditText is empty. If it is, I call an error on that field, e.g. ageWrapper.setError("Age required"). This shows an error message under the field, and also changes the hint of the EditText to red. This occurs for all input fields on the page and the errors are working fine.
The problem occurs after I clear the error. I first leave the field blank and submit - error shows up and things are displayed red. I then type something into the field, and submit again. Now, the error goes away as it should (ageWrapper.setErrorEnabled(false)), but the hint remains in red rather than changing back to its normal, non-error, colour.
This should not be happening because the error has been cleared by typing something into the field, and yet the hint is still red implying an error, even though the error message itself (under the field) disappears.
When I click the field again, or any other field on the page, the red hint text then changes back to its normal colour.
Clearly the error display is working - it displays and goes away as it should. But why does the hint text remain red after Ive cleared the error by typing something into the field, and only changes back to its regular colour after a click to the field itself (or another field)? How do I get rid of this behaviour?
In my mind, if both fields are empty, both will display red and show error messages. If I then fill in one of the fields, setErrorEnabled(false) should be set on that field and the hint text should go back to normal but it doesnt.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="#dimen/new_layout_padding">
<android.support.design.widget.TextInputLayout
android:id="#+id/input_condition_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/input_subnum_wrapper">
<EditText
android:id="#+id/input_condition"
android:layout_width="match_parent"
android:layout_height="#dimen/new_form_element_height"
android:hint="#string/input_text_condition"
android:inputType="number" />
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="#+id/input_age_wrapper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/input_condition_wrapper">
<EditText
android:id="#+id/input_age"
android:layout_width="match_parent"
android:layout_height="#dimen/new_form_element_height"
android:hint="#string/input_text_age"
android:inputType="number" />
</android.support.design.widget.TextInputLayout>
<Button
android:id="#+id/input_submit"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:layout_alignParentRight="true"
android:ems="5"
android:text="#string/input_button_save" />
</RelativeLayout>
Java class for the fragment:
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_new, container, false);
//Get all text fields
conditionWrapper = (TextInputLayout) view.findViewById(R.id.input_condition_wrapper);
ageWrapper = (TextInputLayout) view.findViewById(R.id.input_age_wrapper);
//Listener for create button
createButton = (Button) view.findViewById(R.id.input_submit);
createButton.setOnClickListener(this);
// Inflate the layout for this fragment
return view;
}
//Create/submit button click
#Override
public void onClick(View v) {
//Get input values
String condition = conditionWrapper.getEditText().getText().toString();
String age = ageWrapper.getEditText().getText().toString();
//If all the validation passes, submit the form. Else, show errors
if (!isEmpty(condition) & !isEmpty(age)) {
//Submit form data
} else {
if (isEmpty(condition)) {
conditionWrapper.setError("Condition required");
} else {
conditionWrapper.setErrorEnabled(false);
}
if (isEmpty(age)) {
ageWrapper.setError("Age required");
} else {
ageWrapper.setErrorEnabled(false);
}
}
}
//Check if a string is empty
public boolean isEmpty(String string) {
if (string.equals("")) {
return true;
} else {
return false;
}
}
change your code to
if (isEmpty(condition)) {
conditionWrapper.setError("Condition required");
} else {
conditionWrapper.setError(null);
}
Use doOnTextChanged listner on edit text and check whenever user write something is there error enable if then make it null and change box color
binding.loginEmailValue.doOnTextChanged { text, start, before, count ->
if(binding.loginEmailContainer.error.toString().isNotEmpty()){
binding.loginEmailContainer.error = null
}
}
I wanted to display blinking cursor at the end of the text in TextView .
I tried by android:cursorVisible="true" in TextView But no go .
Even i tried text.setCursorVisible(true); Doesn't work .
<TextView
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:cursorVisible="true"
android:textCursorDrawable="#null" />
Does any one know any solution for it ?
First of all you should use EditText in place of TextView for taking input. If still the cursor doesn't blink, set the android:cursorVisible="true"attribute in xml file, it should make the cursor blink. If your cursor is not visible in edit text, that's also a reason one can't see the cursor blinking. Set android:textCursorDrawable="#null". This should solve your problem
<EditText
android:id="#+id/editext1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textCursorDrawable="#null"
android:cursorVisible="true">
</EditText>
In your activity class, add this code as well.
EditText input = (EditText)findViewById(R.id.edittext1);
input.setSelection(input.getText().length());
There is a solution for this.
I had to do this when I was making a terminal app and I used a simple runnable put a cursor at the end and make it blink.
I made 3 class variables:
private boolean displayCursor;
private boolean cursorOn;
private String terminalText;
private TextView terminal; // The TextView Object
terminalText keeps track of the text to be displayed.
Created a class method that runs the runnable the first time
private void runCursorThread() {
Runnable runnable = new Runnable() {
public void run() {
if (displayCursor) {
if (cursorOn) {
terminal.setText(terminalText);
} else {
terminal.setText(terminalText + '_');
}
cursorOn = !cursorOn;
}
terminal.postDelayed(this, 400);
}
};
runnable.run();
}
And initiated the variables and called runCursorThread() in onCreate()
cursorOn = false;
displayCursor = true;
runCursorThread();
I think you should go for EditText. You can set its background and make it appears like TextView with below code.
Step 1
<EditText
android:id="#+id/edtText"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#android:color/transparent" >
</EditText>
Step 2
EditText edt = (EditText) findViewById(R.id.edtText);
edt.setSelection(edt.getText().length());
Output
Finally Fixed this Using the EditText as per #Chintan Rathod advice.
<EditText
android:id="#+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#android:color/transparent"/> //reference to #Chintan Rathod.
Code
EditText text=(EditText) findViewById(R.id.text);
text.setText("hello");
text.setSelection(text.getText().length()); // reference to #Umer Farooq code.
In my application, in an activity i have 4 edit Text fields and a button. Only After entering data for all 4 edit text fields, data will be submitted. If one is empty, i am showing an alert dialog stating my custom error message. Now in the activity if i click on edit text and press any key on keyboard, the text is not appened to edit text.
If you have faced a similar issue please do let me know.enter code here
<EditText
android:id="#+id/first_field"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#id/TextView01"
android:layout_centerHorizontal="true"
android:layout_marginBottom="6dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:digits="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'."
android:gravity="left|center"
android:hint="First Name"
android:imeOptions="actionNext"
android:inputType="text"
android:textSize="11sp"
android:typeface="sans" >
</EditText>
In .java File
in Oncreate Method
first_field = (EditText)findViewById(R.id.first_field);
InputFilter[] filter = new InputFilter[1];
filter[0] = new InputFilter.LengthFilter(24);
first_field.setFilters(filter);
in Onclick event for the button
NumberKeyListener keyListener1 = new NumberKeyListener() {
public int getInputType() {
return InputType.TYPE_CLASS_TEXT;
}
#Override
protected char[] getAcceptedChars() {
return new char[] { '.','‘' };
}
};
first_field.setKeyListener(keyListener1);
I believe you need to specify android:editable in your xml definition.
According to the setFilters method it "Sets the list of input filters that will be used if the buffer is Editable."
I commented this part of the code in Onclick method and it worked fine.
NumberKeyListener keyListener1 = new NumberKeyListener() {
public int getInputType() {
return InputType.TYPE_CLASS_TEXT;
}
#Override
protected char[] getAcceptedChars() {
return new char[] { '.','‘' };
}
};
first_field.setKeyListener(keyListener1);
editText in change u pot inputtext = true