I am using TextInputLayout for input fields.
But when I add an icon at the end of the field, a problem occurs.
If I click on the field, the TextInputLayout gets focus AND the end icon get focus after it. Now if I want to leave that field, one back press will only removes the focus from the end icon, then I have to press it a second time so the field will lose focus and close the keyboard.
GIF of the behavior
TextInputLayout XML code:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/fieldsInputField"
style="#style/Widget.MaterialComponents.TextInputLayout.FilledBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxBackgroundColor="#android:color/transparent"
app:hintTextColor="#color/primaryColor"
android:textColorHint="#color/hintColor"
app:startIconDrawable="#drawable/ic_list"
app:startIconTint="#color/primaryColor"
app:endIconDrawable="#drawable/ic_list"
app:endIconTint="#color/primaryColor"
android:hint="#string/hint">
<AutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:labelFor="#id/fieldsInputField"
android:maxLines="2" />
</com.google.android.material.textfield.TextInputLayout>
Kotlin code:
fieldsInputField.setEndIconOnClickListener {
// create a new field
val newTextInputLayout = LayoutInflater.from(requireContext()).inflate(
R.layout.fields_item, null) as TextInputLayout
// add the new field id to the list of ids
newTextInputLayout.id = View.generateViewId()
fieldsIds.add(newTextInputLayout.id)
newTextInputLayout.hint = "${newTextInputLayout.hint}"
setTextInputLayoutHandler(newTextInputLayout, SignUpRegex.dummy, "")
// add 'remove field' button to the new field
newTextInputLayout.setEndIconOnClickListener {
fieldsLayout.removeView(newTextInputLayout)
fieldsIds.remove(newTextInputLayout.id)
}
// add the new field to the layout
fieldsLayout.addView(newTextInputLayout)
}
Related
My normal edittext which works:
<EditText
android:id="#+id/emailEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8_dp"
android:hint="Email"
android:imeOptions="actionNext"
android:inputType="textEmailAddress"
android:text="#={viewModel.emailId}"
android:textSize="#dimen/font_size_default_input" />
Now Im using:
<myapp.app.widgets.edittext.MyCustomEditText
android:id="#+id/panEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/dimen_8_dp"
android:hint="PAN number"
android:imeOptions="actionNext"
android:inputType="textCapCharacters"
android:maxLength="10"
android:text="#{viewModel.pan}"
android:textSize="#dimen/font_size_default_input" />
Now this doesnt work.
my method
!viewModel.isPanValid() -> binding.panEditText.setError(viewModel.panError.value)
doesnt work but for email it works what to do?
the
MyCustomEditText is just en extended class
public class MyCustomEditText extends LinearLayout implements View.OnFocusChangeListener, TextWatcher, TextView.OnEditorActionListener, View.OnClickListener {
It includes just a UI stuff and on focus listener etc
setError is a function of EditText. Your MyCustomEditText is not an EditText but a LinearLayout so you can't call setError on it because it simply doesn't exist for that class. I don't know the rest of MyCustomEditText but I assume it has an EditText inside it and you might have a reference to it, say editTextInThisClass. If not you will need to create one. Then you could write this in your MyCustomEditText:
public void setError(CharSequence error) {
editTextInThisClass.setError(error)
}
but I wonder if you actually intended for it to be a LinearLayout. If not you should just change LinearLayout to EditText
I am using a TextInputLayoutHelper widget in order to follow the material guidelines for floating label inputs. It currently looks like this:
My code
In my activities onCreate function, I have:
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val passwordInputLayout = this.findViewById<TextInputLayoutHelper>(R.id.input_layout_password)
passwordInputLayout.error = "8+ characters and at least one uppercase letter, a number, and a special character (\$, #, !)"
passwordInputLayout.isErrorEnabled = true
}
and my widget in my xml looks like...
<TextInputLayout
android:id="#+id/input_layout_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/EditTextTheme"
app:errorEnabled="true"
app:errorTextAppearance="#style/ErrorAppearance"
app:passwordToggleDrawable="#drawable/asl_password_visibility"
app:passwordToggleEnabled="true"
app:passwordToggleTint="?colorControlNormal">
<EditText
android:id="#+id/password_edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="#string/set_a_password"
android:inputType="textPassword"
android:singleLine="true" />
</TextInputLayout>
What I want to do
I want to put an icon in the error/hint text (the exclamation triangle) to the right of the error text.
My Attempt
Attempt 1
I found an implementation which uses setError(text, drawable) but I am using Kotlin to setError is not available.
So I tried:
val warningIcon = ResourcesCompat.getDrawable(resources, R.drawable.ic_warning_black_24dp, null)
warningIcon?.setBounds(0, 0, warningIcon.intrinsicWidth, warningIcon.intrinsicHeight)
passwordInputLayout.error = "8+ characters and at least one uppercase letter, a number, and a special character (\$, #, !) $warningIcon"
but that does not render the drawable, only a string of the resource path.
Attempt 2
I found another one that overrides the TextInputLayoutHelper in order to set a drawable next to the text. As you can see, setError only contains the interface override fun setError(error: CharSequence?) which does not have a parameter for drawable.
override fun setError(error: CharSequence?) {
super.setError(error)
val warningIcon = ResourcesCompat.getDrawable(resources, R.drawable.ic_warning_black_24dp, null)
warningIcon?.setBounds(0, 0, warningIcon.intrinsicWidth, warningIcon.intrinsicHeight)
// mHelperView is a TextView used in my custom `TextInputLayout` override widget
mHelperView!!.setCompoundDrawables(null, null, warningIcon, null)
}
Is there an override or built in "Android way" to add this icon next to the error/hint text?
You can use SpannableString with ImageSpan like this
val errorDrawable = ContextCompat.getDrawable(context!!, R.drawable.ic_error)
your_text_input_layout.error = SpannableString("your string").apply {
setSpan(ImageSpan(errorDrawable, ImageSpan.ALIGN_BASELINE), 0, 1, Spanned.SPAN_INCLUSIVE_EXCLUSIVE)
This might help others who've fallen in to similar trouble. I looked at source codes. The thing is setError(text, drawable) has defined in EditText class not TextInputLayout as your layout is based on.
I have similar code and issue like you and since TextInputLayout doesn't have any method to replace Drawable then we have to create a TextView below TextInputLayout in order to simulate error message.
You want to place an icon inside the error container of TextInputLayout
If you check the real layout
You'll find that your textview is even wrap content.
Also in SDK sources
if (enabled) {
mErrorView = new AppCompatTextView(getContext());
mErrorView.setId(R.id.textinput_error);
...
So there is no place to insert an icon on the right AS IS.
One possible solution is to find this view programatically inside your layout, change width and apply drawable.
Second (and probably easiest) solution is to implement your own simple error layout and not to set error for TextInputLayout but manage the error state by yourself
i'm a beginner with xamarin android mvvmcross
i have an app who works fine with two activity
in the first activity i have a button when i click on the button i have this
<Button
android:layout_height="50dp"
android:layout_weight=".35"
android:layout_width="0dp"
android:background="#drawable/button_Green"
style="#style/button_text_white"
local:MvxBind="Click StartCommand" />
this button launch a second activity
on the second activity i have a edit text and a button
i would like on click on the button add text to the edit text ..but i don't know how to do this ...
is not really clear in my head sorry ...
thanks for your time
First declare a EditText in your layout:
<EditText
android:layout_height="wrap_content"
android:layout_width="fill_parent"
local:MvxBind="Text MyText">
</EditText>
Notice the Binding of the Text-property to "MyText". You need to add a public property with this name in your ViewModel:
class SecondViewModel: MvxViewModel
{
private string m_MyText;
public string MyText
{
get { return m_MyText; }
set
{
m_MyText = value;
RaisePropertyChanged();
}
}
// ...
}
As soon as you set the property MyText from within your ViewModel it will update the layout accordingly. It is required to call RaisePropertyChange in the setter of the property to tell the layout that there are changes.
I made my first application for Android using only Java code. How do I create an EditText in Java Code?
Is more or less works like this:
EditText et = new EditTex(context);
where the context is e.g. the Activity that hosts the EditText.
In practice you may want to do some customizing and then attach it to an existing layout like e.g.
EditText et = new EditText(getActivity());
et.setTextAppearance(getActivity(),R.style.table_cell); // add some style
et.setTag(name); // add a tag
if(PropertyType.isNumeric(spd.getType())) {
et.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); // Input are numbers only
}
if (spd.getDefaultValue()!=null) {
et.setText(""+spd.getDefaultValue()); // set a default text to be displayed
}
row.addView(et); // add it to a parent
After you have formatted it in XML:
<EditText
android:id="#+id/edittextid"
android:inputType="text" >
You can call it by declaring it and linking it to the view you specified in the XML like so:
EditText et = (EditText)view.findViewById(R.id.edittextid);
You can get more info on the class here
actually i am displaying a pop up with ok cancel button when user clicks on edit text.
My problem is when ever user double clicks on edit text two pop up comes. so if user has selected any value from pop up its second pop up still remain there.
I don't know how to deal with it.
Any help will appreciated. thanks in advance.
This is my layout
<EditText
android:id="#+id/date_control"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#drawable/bg_edit_text"
android:focusableInTouchMode="false"
android:inputType="none"
android:editable="false"
android:clickable="true"
android:layout_marginRight="5dp" />
My java class calling the controller
datePicker = (EditText) findView(R.id.date_control);
datePicker.setOnClickListener(myControllerClass);
its controller
MyDialog myDialog = new myDialog(activity, "Select Date",
date, DateTimeDialog.DATE_PICKER);
myDialog.show();
If you keep a field reference to your dialog you could check to see if its already showing
if(myDialog == null) {
myDialog = new myDialog(activity, "Select Date",
date, DateTimeDialog.DATE_PICKER);
}
if(!myDialog.isShowing()) {
myDialog.show();
}
You just need to set your edittext clickable false after click (means your dialog gets display) then on dialog dismiss you can again make your edittext clickable true.
you have to set this property programmatically .. for EditText properties link..
Hope this explanation works for you..