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?
CodePudding user response:
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>
CodePudding user response:
You should set a 11 digits text (the font must be a monospace, in order to have all the characters of the same width) into the xml of your EditText
widget (like 12345678901), with android:layout_width="wrap_content"
, then define a ViewTreeObserver.OnGlobalLayoutListener
in your fragment, that calculates the width when the layout is available to be measured:
int viewWidth;
ViewTreeObserver.OnGlobalLayoutListener viewTreeObserver = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
YOUR_FRAME_OR_LINEAR_LAYOUT.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
YOUR_FRAME_OR_LINEAR_LAYOUT.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
viewWidth = YOUR_EDITTEXT.getMeasuredWidth();
update();
}
};
You could instantiate the observer in onResume()
of your fragment, and remove it in onPause()
:
@Override
public void onResume() {
super.onResume();
ViewTreeObserver vto = YOUR_FRAME_OR_LINEAR_LAYOUT.getViewTreeObserver();
vto.addOnGlobalLayoutListener(viewTreeObserver);
}
@Override
public void onPause() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
YOUR_FRAME_OR_LINEAR_LAYOUT.getViewTreeObserver().removeGlobalOnLayoutListener(viewTreeObserver);
} else {
YOUR_FRAME_OR_LINEAR_LAYOUT.getViewTreeObserver().removeOnGlobalLayoutListener(viewTreeObserver);
}
super.onPause();
}
Your update method simply sets the width and the text (initially empty?) of your EditText widget:
public void update() {
// Set all the width of your EditText using the viewWidth value,
// all LayoutParams parameters of the widget,
// and set an empty text on it
}