Set width of TextInputEditText to n characters - android

I'm trying to implement a layout where user will input their phone number. The phone number will be 11 digits. And so I wanted to build a text input field with a fixed width that can accommodate 11 characters.
NOTE: I don't want the input field to be wider than 11 characters. Let's say each character is 10px wide. So the input field should be 11*10px = 110px wide (I'm not taking the drawable icon into account here).
Here's what I've tried in XML:
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_48"
app:startIconDrawable="#drawable/ic_phone">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="11"
android:inputType="phone"
android:maxLength="11"
android:maxLines="1"
android:minEms="11"
android:text="01"
android:textSize="20sp"
android:typeface="monospace" />
</com.google.android.material.textfield.TextInputLayout>
But this produces an output like the following:
As you can see, despite using ems and minEms, the field is 2 characters wide (it's 0 character wide if I don't add android:text). But I want it to have a width of 11 characters (not more or less). Why is ems not effective here and what's the solution?

Just edit your layout width
from
android:layout_width="wrap_content"
to
android:layout_width="match_parent"
I just edited your code
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_48"
app:startIconDrawable="#drawable/ic_phone">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="11"
android:inputType="phone"
android:maxLength="11"
android:maxLines="1"
android:minEms="11"
android:text="01"
android:textSize="20sp"
android:typeface="monospace" />
</com.google.android.material.textfield.TextInputLayout>

You should set a 11 digits monospace text in your TextInputEditText widget (for example 12345678901), then define a ViewTreeObserver.OnGlobalLayoutListener in your fragment, that calculates the width when the layout is available to be measured.
You could instantiate the observer in onResume() of your fragment, and remove it in onPause(). You should also store the width during the rotation of the activity.
Here below a full working example:
MainActivity.java:
public class MainActivity extends AppCompatActivity {
ConstraintLayout constraintLayout;
TextInputEditText textInputEditText;
int viewWidth;
ViewTreeObserver.OnGlobalLayoutListener viewTreeObserver = new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
constraintLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
constraintLayout.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
viewWidth = textInputEditText.getMeasuredWidth();
textInputEditText.setWidth(viewWidth);
textInputEditText.setText("");
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
viewWidth = savedInstanceState.getInt("viewWidth", 0);
}
constraintLayout = findViewById(R.id.id_constraintlayout);
textInputEditText = findViewById(R.id.phone);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("viewWidth", viewWidth);
}
#Override
public void onResume() {
super.onResume();
if (viewWidth == 0) {
textInputEditText.setText("12345678901");
ViewTreeObserver vto = constraintLayout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(viewTreeObserver);
} else textInputEditText.setWidth(viewWidth);
}
#Override
public void onPause() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
constraintLayout.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver);
} else {
constraintLayout.getViewTreeObserver().removeOnGlobalLayoutListener(viewTreeObserver);
}
super.onPause();
}
}
activity_main.xml:
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/id_constraintlayout"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/textField"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:startIconDrawable="#drawable/ic_phone">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ems="11"
android:inputType="phone"
android:maxLength="11"
android:maxLines="1"
android:minEms="11"
android:textSize="20sp"
android:typeface="monospace" />
</com.google.android.material.textfield.TextInputLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
I enclose an image of the result here below, where I already typed 6 digits:

For me the given answers didn't work. But this did:
<com.google.android.material.textfield.TextInputLayout
...
android:maxEms="12"
minEms="12">
<com.google.android.material.textfield.TextInputEditText
...
singleLine="true">
</com.google.android.material.textfield.TextInputLayout>

Related

Is there a way to make EditText focusable with disabled focusableInTouchMode?

I have some EditTexts, and I want to control their focus order programmatically. However, EditText will get focus when touched by default, so this will break the order.
I have tried to make EditText's focusableInTouchMode false, but it never got focus then, like it has disabled focusable.
So, there is a way to disable it's focusableInTouchMode but still focusable?
hope it's impossible Alan.Work around is ,Create one fake editText with 0dp hight and 0dp width.
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:fitsSystemWindows="true">
<EditText
android:id="#+id/edit_fake"
android:layout_width="0dp"
android:layout_height="0dp"
android:focusable="true"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<EditText
android:id="#+id/edit_title"
android:focusableInTouchMode="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="32dp"/>
<EditText
android:id="#+id/edit_name"
android:focusableInTouchMode="true"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintTop_toBottomOf="#id/edit_title"
app:layout_constraintStart_toStartOf="parent"
android:layout_margin="32dp"/>
<Button
android:id="#+id/btn_done"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="done"
app:layout_constraintTop_toBottomOf="#id/edit_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
//activity code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
fake=findViewById(R.id.edit_fake);
name=findViewById(R.id.edit_name);
title=findViewById(R.id.edit_title);
done=findViewById(R.id.btn_done);
fake.setOnFocusChangeListener(this);
name.setOnFocusChangeListener(this);
title.setOnFocusChangeListener(this);
done.setOnClickListener(this);
}
#Override
public void onClick(View v) {
if(v.getId()==R.id.btn_done){
//clear focus
name.clearFocus();
fake.clearFocus();
fake.requestFocus();
}
}
#Override
public void onFocusChange(View v, boolean hasFocus) {
if(v.getId()==R.id.edit_name){
Log.d("onFocusChangename:", "name");
}
if(v.getId()==R.id.edit_fake){
Log.d("onFocusChangenfake:", "fake");
}
if(v.getId()==R.id.edit_title){
Log.d("onFocusChangenfake:", "tit");
}
}

Align password toggle icon

How to position and align the password toggle drawable to the right of TextInputEditText?
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="#style/DefaultTextInputLayout"
android:paddingStart="#dimen/activity_default_margin"
android:paddingEnd="#dimen/activity_default_margin"
app:passwordToggleEnabled="true"
app:passwordToggleDrawable="#drawable/select_show_password"
app:passwordToggleTint="#AFB5C0"
app:errorEnabled="true"
app:layout_constraintBottom_toTopOf="#+id/rememberPasswordCheckBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/emailTextInputLayout" >
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_password"
android:textSize="16sp"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
I need to position the password toggle to the right of TextInputEditText like on the image (where the red arrow are pointing).
You can try the following:
1) MainActivity.class:
public class MainActivity extends AppCompatActivity {
private final String TAG = MainActivity.class.getSimpleName();
private TextInputLayout textInputLayout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textInputLayout = (TextInputLayout) findViewById(R.id.passwordTextInputLayout);
/**
* By inspecting the source code of TextInputLayout, one can find that:
*
* - edit text (called editText) and show password (
* called startIconView) views are both placed inside
* a frame layout (called inputFrame).
* - edit text view is the first child of the frame layout
* and that the show password view is the third child of this layout.
*
*/
FrameLayout inputFrame = null;
TextInputEditText editText = null;
CheckableImageButton startIconView = null;
for (int i = 0; i < textInputLayout.getChildCount(); i++) {
View child = textInputLayout.getChildAt(i);
if (child instanceof FrameLayout) {
inputFrame = (FrameLayout) child;
for (int j = 0; j < inputFrame.getChildCount(); j++) {
View child1 = inputFrame.getChildAt(j);
if (child1 instanceof TextInputEditText) {
editText = (TextInputEditText) child1;
} else if (child1 instanceof CheckableImageButton) {
if (j == 2) {
startIconView = (CheckableImageButton) child1;
}
}
}
break;
}
}
/**
*
* - relocate editText and startIconView inside inputFrame.
* In our case we want startIconView to be located to the
* right of editText
*
**/
if (inputFrame != null) {
RelativeLayout rl = new RelativeLayout(MainActivity.this);
FrameLayout.LayoutParams params_rl = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
rl.setLayoutParams(params_rl);
if (editText != null &&
startIconView != null) {
inputFrame.addView(rl);
inputFrame.removeView(startIconView);
inputFrame.removeView(editText);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
params.addRule(RelativeLayout.ALIGN_PARENT_END);
startIconView.setLayoutParams(params);
rl.addView(startIconView);
RelativeLayout.LayoutParams params1 = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
params1.addRule(RelativeLayout.ALIGN_PARENT_START);
params1.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
params1.addRule(RelativeLayout.LEFT_OF, startIconView.getId());
params1.addRule(RelativeLayout.START_OF, startIconView.getId());
editText.setLayoutParams(params1);
rl.addView(editText);
}
}
}
}
2) activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/colorPrimaryDark"
tools:context=".MainActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:layout_marginTop="100dp"
app:passwordToggleDrawable="#drawable/select_show_password"
app:passwordToggleTint="#AFB5C0"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:hint="123"
android:text=""
android:background="#color/colorPrimary"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:passwordToggleEnabled="true"
android:layout_below="#id/passwordTextInputLayout2"
app:passwordToggleDrawable="#drawable/select_show_password"
app:passwordToggleTint="#AFB5C0"
app:errorEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:hint="123"
android:text=""
android:background="#color/colorPrimary"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>
</RelativeLayout>
3) Result:
I think this will help
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/input_layout_password"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtxt_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password"
android:imeOptions="actionNext"
android:paddingTop="10dp"
android:paddingBottom="20dp"
android:paddingStart="10dp"
android:inputType="textPassword"
android:drawableRight="#drawable/ic_visibility_off"
android:maxLines="1"/>
</com.google.android.material.textfield.TextInputLayout>
Below is working code for me
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/input_layout_password"
style="#style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:hint="Password"
app:layout_constraintTop_toBottomOf="#id/input_layout_username"
app:passwordToggleEnabled="true">
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/edtxt_password"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:imeOptions="actionNext"
android:inputType="textPassword"
android:maxLines="1" />
</com.google.android.material.textfield.TextInputLayout>
Below is my output
I solved using negative padding, maybe it not a good pratic, but I can't think how to do it using good practics
<com.google.android.material.textfield.TextInputLayout
android:id="#+id/passwordTextInputLayout"
android:layout_width="0dp"
android:layout_height="wrap_content"
style="#style/DefaultTextInputLayout"
android:paddingStart="#dimen/activity_default_margin"
android:paddingEnd="#dimen/activity_default_margin"
app:passwordToggleEnabled="true"
app:passwordToggleDrawable="#drawable/select_show_password"
app:passwordToggleTint="#AFB5C0"
app:errorEnabled="true"
app:layout_constraintBottom_toTopOf="#+id/rememberPasswordCheckBox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/emailTextInputLayout" >
<com.google.android.material.textfield.TextInputEditText
android:id="#+id/passwordEditText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/login_password"
android:textSize="16sp"
android:paddingEnd="-10dp"
app:setDebugText="#{password}"
android:inputType="textPassword" />
</com.google.android.material.textfield.TextInputLayout>

Animate LayoutChanges does not work properly

I want to animate text in my textswitcher. I went through all the stack questions and the documentation, but they didn't solve my problem.
Here is my XML:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="#+id/tv__inc_pre_sing__screen_title"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="#fff"
android:gravity="center"
android:text="PRACTICE"
android:textAllCaps="true"
android:textColor="#color/colorAccent"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.ConstraintLayout
android:id="#+id/rl__inc_pre_sing__tm_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:animateLayoutChanges="true"
android:background="#efff"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv__inc_pre_sing__screen_title">
<ImageView
android:id="#+id/tv__inc_pre_sing__quotation_mark"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:src="#drawable/ic_archive_black_24dp"
app:layout_constraintTop_toTopOf="parent" />
<TextSwitcher
android:id="#+id/tv__inc_pre_sing__teacher_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/tv__inc_pre_sing__quotation_mark"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="#+id/iv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginTop="8dp"
android:src="#drawable/ic_archive_black_24dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/tv__inc_pre_sing__teacher_message" />
</android.support.constraint.ConstraintLayout>
<Button
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:text="Click Me"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<View
android:layout_width="0dp"
android:layout_height="16dp"
android:background="#drawable/ic_launcher_background"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#id/rl__inc_pre_sing__tm_container" />
</android.support.constraint.ConstraintLayout>
Here is my code
public class Main3Activity extends AppCompatActivity {
private TextSwitcher mSwitcher;
Button btnNext;
int currentIndex=-1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
Resources resources = getApplicationContext().getResources();
final String[] textString = resources.getStringArray(R.array.teacher_messages);
btnNext = findViewById(R.id.button);
mSwitcher = findViewById(R.id.tv__inc_pre_sing__teacher_message);
mSwitcher.setFactory(new ViewSwitcher.ViewFactory() {
public View makeView() {
// TODO Auto-generated method stub
// create new textView and set the properties like clolr, size etc
TextView myText = new TextView(Main3Activity.this);
myText.setGravity(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
myText.setTextColor(Color.BLUE);
return myText;
}
});
// Declare the in and out animations and initialize them
Animation in = AnimationUtils.loadAnimation(this,android.R.anim.slide_in_left);
Animation out = AnimationUtils.loadAnimation(this,android.R.anim.slide_out_right);
// set the animation type of textSwitcher
mSwitcher.setInAnimation(in);
mSwitcher.setOutAnimation(out);
// ClickListener for NEXT button
// When clicked on Button TextSwitcher will switch between texts
// The current Text will go OUT and next text will come in with specified animation
btnNext.setOnClickListener(new View.OnClickListener() {
//
public void onClick(View v) {
// TODO Auto-generated method stub
currentIndex++;
// If index reaches maximum reset it
if(currentIndex==textString.length)
currentIndex=0;
mSwitcher.setText(textString[currentIndex]);
((ViewGroup) findViewById(R.id.rl__inc_pre_sing__tm_container)).getLayoutTransition()
.enableTransitionType(LayoutTransition.CHANGING);
}
});
}
}
The animation on ConstraintLayout whose id is rl__inc_pre_sing__tm_container does not work properly. Suppose my TextSwitcher has text whose length is greater than 3 and then TextSwitcher shows text whose length is 1 then the ConstraintLayout does not animate, if the next text is of length 1 then the constraintlayout animates.
I am not able to figure out this weird behaviour.
Here is the issue: When the TextSwitcher transitions from X lines of text to something less than X lines then the TextSwitcher's height does not change.
The TextSwitcher inherits some behavior from ViewAnimator which considers the height of all views when determining the height of the widget. The solution is to add the following XML to the TextSwitcher definition in the layout file that will inhibit this behavior:
android:measureAllChildren="false"
Thanks to this Stack Overflow answer that states all this better than I have.

onFocus function not working properly in Android ?

Hi I am newbie in android, I have 3 edit box and I have set 3 setOnFocusChangeListener based on edit box wise, When I focus mobile no edit box ,I am getting sim no id instead mobile no Id. onFocus function getting called with wrong id's. If I did any any mistake please let us know or else solve the solution.
Source code :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_temp);
objMobileNo = (EditText) findViewById(R.id.mobile_no);
objSimNo = (EditText) findViewById(R.id.sim_no);
objImsiNo = (EditText) findViewById(R.id.imsi_no);
View.OnFocusChangeListener a = new View.OnFocusChangeListener() {
public void onFocusChange(View view, boolean hasFocus) {
if (!hasFocus) {
//this if condition is true when edittext lost focus...
//check here for number is larger than 10 or not
// focusText = "MOBILE";
// Log.d("BKS", "onFocusChange: " + focusText);
Log.d("BKS", "onFocusChange: " + view.getId());
Log.d("BKS", "onFocusChange: " + R.id.mobile_no);
}
}
};
objMobileNo.setOnFocusChangeListener(a);
objSimNo.setOnFocusChangeListener(a);
objImsiNo.setOnFocusChangeListener(a);
XML Code :
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<EditText
android:layout_marginTop="100dp"
android:id="#+id/mobile_no"
style="#style/Material_Action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_mob_no"
android:inputType="number"
android:maxLength="10" />
<EditText
android:id="#+id/sim_no"
style="#style/Material_Action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_sim_no"
android:inputType="number"
android:maxLength="20" />
<EditText
android:id="#+id/imsi_no"
style="#style/Material_Action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint_imsi_no"
android:inputType="number"
android:maxLength="15" />
<EditText
android:id="#+id/status"
style="#style/Material_Action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:visibility="gone" />
<EditText
android:id="#+id/scanning_type"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text"
android:visibility="gone" />
<LinearLayout
android:id="#+id/mLlayoutBottomButtons"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal">
<Button
android:id="#+id/verify"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#android:color/holo_green_light"
android:text="Verify"
android:textColor="#android:color/white">
</Button>
</LinearLayout>
Thanks in Advance,
Kalanidhi.
You are setting same OnFocusChangeListener for all EditText. so when you focus a new EditText, the current one loses its focus. So for both the events onFocusChange() will be called. But your if condition filters only the view that loses the focus and not the one which got the focus.
So replace
if (!hasFocus) {
}
with this to make it work as expected
if (hasFocus) {
}

Android EditText error message not showing on bottom

I have a form where the user enter the client info. When I try to validate the fields I have a problem, I used editText.setError(errorMessage) and it's showing the error message, but it shown on the top of my EditText making it confusing to the user. Like the image below.
Any ideas of how I can fix this?
EditText on XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="br.com.intelecto.intesigmobile.activity.ClienteEditActivityFragment">
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_nome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_nome"
android:imeActionId="#+id/cli_name"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="textPersonName"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_telefone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_telefone"
android:imeActionId="#+id/cli_cpf"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="phone"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_email"
android:imeActionId="#+id/cli_cpf"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="textEmailAddress"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_cpf"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_cpf"
android:imeActionId="#+id/cli_cpf"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="number"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_endereco"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_endereco"
android:imeActionId="#+id/cli_address"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="textPostalAddress"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_bairro"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_bairro"
android:imeActionId="#+id/cli_district"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<Spinner
android:id="#+id/sp_estados"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"/>
<Spinner
android:id="#+id/sp_cidade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:prompt="#string/cliente_cidade"/>
This ClienteEditActivity holds two fragments with different forms so I listen for a action menu click at the fragment, when menu is clicked I use this to call may validation:
if (!isValidEmail(etEmail)) {
cancel = true;
focusView = etEmail;
}
//after other validations
if (cancel){
focusView.reqeustFocus();
} else {
//save datas
}
The isValidEmail method is like this:
protected boolean isValidEmail(EditText editText) {
validate = new Validate(editText);
validate.addValidador(new ValidadorVazio(getContext()));
validate.addValidador(new ValidadorEmail(getContext()));
return validate.isValid();
}
My Validateclass looks like this:
public class Validate{
private EditText etFonte;
public Validate(EditText etFonte){
this.etFonte = etFonte;
}
public void addValidador(AbstractValidador validador){
lalidadores.add(validador);
}
public boolean isValid(){
for (AbstractValidador validator : lValidadores) {
try {
if (!validator.isValid(etFonte.getText().toString())) {
if(errorNotification != null) {
errorNotification.onInvalid(this);
} else {
setSourceViewError(validator.getMessage(), validator.getErrorDrawable());
}
return false;
} else {
if(errorNotification != null) errorNotification.onValid(this);
}
} catch (ValidadorException e) {
e.printStackTrace();
if(errorNotification != null) {
errorNotification.onInvalid(this);
} else {
setSourceViewError(e.getMessage(),validator.getErrorDrawable());
}
return false;
}
}
etFonte.setError(null);
return true;
}
private void setSourceViewError(String errorMessage, Drawable errorDrawable) {
if(errorDrawable != null) {
etFonte.setError(errorMessage, errorDrawable);
} else {
etFonte.setError(errorMessage);
}
}
}
Set error on TextInputLayout instead of EditText, Here's your code...
<android.support.design.widget.TextInputLayout
android:id="#+id/textInputLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="#+id/et_nome"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/cliente_nome"
android:imeActionId="#+id/cli_name"
android:imeActionLabel="#string/str_next"
android:imeOptions="actionUnspecified"
android:inputType="textPersonName"
android:maxLines="1"
android:singleLine="true"/>
Get your TextInputLayout at runtime and apply following code...
TextInputLayout textInputLayout = (TextInputLayout) findVeiwById(R.id.textInputLayout);
textInputLayout.setErrorEnabled(true);
textInputLayout.setError("Please enter a valid license number");
It will produce output something like this...
In your layout's root element, find the following line and remove it.
app:layout_behavior="#string/appbar_scrolling_view_behavior"
Everything will be fine!
I assume that you have set an error on wrong reference of edit text. You have to set error on the same edit email edit text and also have to request focus on same edit text.
Here is the code snippet for activity:-
private EditText mEmailET;
#Override
protected void onCreate(Bundle savedInstanceState) {
mEamilET = (EditText)findViewById(R.id.et_email);
}
private void setSourceViewError(String errorMessage, Drawable errorDrawable) {
if(errorDrawable != null) {
mEamilET.setError(errorMessage, errorDrawable);
mEamilET.requestFocus();
} else {
mEamilET.setError(errorMessage);
mEamilET.requestFocus();
}
}
If you still face the issue please send the activity code too for better understanding for us and appropriate answer.
Do not use "include" tag to show your layout. Just replace that tag with your layout and you good to go. And you would want to set marginTop="60dp" so the toolbar is accessible.

Categories

Resources