Set max length to EditText layout_width - android

I'm currently doing an EditText where the user can type in one row of text. But I have the issue with setting it's max length. If I set it to a specific number it becomes very unpredictable since spaces takes up more for some reason. So I can type in "asdnknfoisanfo" etc and get the correct length I want, but when you start typing with spaces between the words the length get's smaller and doesn't fill the whole EditText.
<EditText
android:id="#+id/imageDescriptionTextEdit"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:hint="Enter a description of this picture.."
android:textSize="15sp"
android:textColorHint="#E9E9E9"
android:textColor="#ffffff"
android:maxEms="26"
android:imeOptions="actionDone"
android:typeface="monospace"
android:minEms="3"
android:singleLine="true"
fontPath="fonts/VarelaRound-Regular.ttf"
tools:ignore="MissingPrefix"/>
What I would say to be the ultimate solution is to set the length of characters to the length of the EditText itself. Then for sure, the user have the correct capacity always. Is this possible? Or are there another solution to my problem?

You can try with this.
String mStringStr = mEditText1.getText().toString().replaceAll("\\s", "");
Now you can get the actual length in string mStringStr(Without blank space)
mStringStr.length();
I hope this may help you.. :)

Try with this conditional
if(findViewById(R.id.imageDescriptionTextEdit).getText().toString().trim().length() <= "your max length here"){
//Do something
} else {
//Show alert message
}

What you can do is to remove the spaces from the input using below code
String input = Your_EditText.getText().toString();
input = input.replace(" ", "");
Then you can get the length of the string using
int inputlength = input.length();
Then you can check if the input is okay or not
so , overall the code should be
private final TextWatcher mywatcher = new TextWatcher() {
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
String input = Your_EditText.getText().toString();
input = input.replace(" ", "");
int inputlength = input.length();
if(inputlength>your_defined_length)
{
//do what you want to do
}
}
public void afterTextChanged(Editable s) {
}
};
Dont forget to add this watcher to your editText
Your_EditText.addTextChangedListener(mywatcher);

You can try it programatically :
final EditText et = (EditText)findViewById(R.id.editText);
et.addTextChangedListener(new TextWatcher() {
int yourMaxLength = 10;
boolean canNotAddMore = false;
String maxText = "";
public void afterTextChanged(Editable s) {
if(canNotAddMore){
et.removeTextChangedListener(this);
et.setText(maxText);
et.addTextChangedListener(this);
}
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
String realCoontent = s.toString().trim().replace(" ", "");
if(realCoontent.length() >= yourMaxLength){
canNotAddMore = true;
maxText = s.toString();
}
}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
This example will remove the spaces from the list of characters counted to determine if the max number of characters is reached.
For example for a limit of 10 characters, the user can enter :
"1234567890"
or
"1 2 3 4 5 6 7 8 9 0"

You can measure the width of the typed input text with a Paint object:
EditText input = findViewById(R.id.imageDescriptionTextEdit) // Your EditText
final Paint paint = input.getPaint();
float textWidth = paint.measureText(input.getText().toString());
if (textWidth > input.getWidth()) {
// Prevent further input.
}
You can combine this check with a TextWatcher.

Related

Hide only numbers in EditText for pin-code (Android)

I have EditText in myApp with this TextWatcher and numberSigned input type:
TextWatcher() {
#Override
public void afterTextChanged(Editable s)
{
codeinput.removeTextChangedListener(this);
String text = s.toString();
text = text.replaceAll("[^0-9]", "");
if (text.length() > 4)
text = text.substring(0, 4);
String newText = "";
for (char c : text.toCharArray())
newText += c + " ";
text = newText.trim();
String substring = "_ _ _ _".substring(text.length());
text += substring;
int length = text.replaceAll("([ ]?[_])+$", "").length();
codeinput.setText(text);
codeinput.setSelection(length);
codeinput.addTextChangedListener(this);
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) { }
};
When i change input type from numberSigned to numberPassword - all symbols in my EditText is hidden, i want to hide only numbers. How can i do it?
I'm affraid that password type field hides all characters and you can't do anything with that
but consider using setLetterSpacing and don't use spaces (method available since API21)
if you need lower API support and you still want to use numberPassword then you have to set up 4 EditTexts - use editText.requestFocus for jumping to another/next View. or you may keep one EditText with numberSigned, but exchange during text entering all digits to asterisks (keeping digits in some separated value, as editText.getText will return you only asterisks)

Automatically adding decimal values to number in EditText

I have an EditText where the user wants to enter the price. In order to maintain uniformity, I decided to automatically include the decimal values.
Hence "1" entered by user would become "1.00" for example.
Now, after working with my inefficient code, I can across a better code in StackOverFlow
amountEditText.setRawInputType(Configuration.KEYBOARD_12KEY);
amountEditText.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.toString().matches("^\\$(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
{
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
StringBuilder cashAmountBuilder = new StringBuilder(userInput);
while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') {
cashAmountBuilder.deleteCharAt(0);
}
while (cashAmountBuilder.length() < 3) {
cashAmountBuilder.insert(0, '0');
}
cashAmountBuilder.insert(cashAmountBuilder.length()-2, '.');
cashAmountBuilder.insert(0, '$');
amountEditText.setText(cashAmountBuilder.toString());
// keeps the cursor always to the right
Selection.setSelection(amountEditText.getText(), cashAmountBuilder.toString().length());
}
}
});
With the above code, the decimal value starts getting included once the user starts entering the number. But, the numerical value added by the user will be displayed with $ symbol. Hence, I made a little modification to the code in Line 07 and deleted Line 19.
The new code is
returnPrice.setRawInputType(Configuration.KEYBOARD_12KEY);
returnPrice.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.toString().matches("^(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$"))
{
String userInput= ""+s.toString().replaceAll("[^\\d]", "");
StringBuilder cashAmountBuilder = new StringBuilder(userInput);
while (cashAmountBuilder.length() > 3 && cashAmountBuilder.charAt(0) == '0') {
cashAmountBuilder.deleteCharAt(0);
}
while (cashAmountBuilder.length() < 3) {
cashAmountBuilder.insert(0, '0');
}
cashAmountBuilder.insert(cashAmountBuilder.length()-2, '.');
returnPrice.setText(cashAmountBuilder.toString());
// keeps the cursor always to the right
Selection.setSelection(returnPrice.getText(), cashAmountBuilder.toString().length());
}
}
});
My Problem
So the problem I am facing in case 02 is, when I am entering the numeric value in EditText - unless I am entering the decimal dot, the numeric value in EditText gets displayed as an integer.
For example : Case 01
For displaying 100.00 as I go on typing, the value starts displaying as $0.01, then $0.10, then $1.00, $10.00 and finally $100.00. At any instance, I don't need to enter a decimal dot manually in this case.
For example : Case 02
For displaying 100.00 as I go on typing, the value starts displaying as 1, then 10, then 100. Now, if I press the decimal dot on soft keyboard, the 100 becomes 1.00 and on typing the value turns 10.00 and finally 100.00. If the decimal dot is not touched on the keyboard, the resulting value on entering 10000 is 10000 and not 100.00.
What's the error I made? Any suggestions?

Output string with decimal format limited to 2 dp

Stuck on this which im sure there is an easy solution to, just cannot work it out!!
I have tried decmialformat, numberformat, string.format() etc and nothing works. .
code below, i want to calculation to just show the output limited to 2 decimal places. Have spent the last 2 hours trying various methods all of which causes the app to crash when run...
Output = (Output1 / (1 -(Output2/100)))
String OutputString = String.valueOf(Output);
Num.setText(OutputString);
Try this :
String OutputString = String.format("%.2f", Output);
Num.setText(OutputString);
String.format() to make sure you only get 2 decimal places in your output.
please try this:
double Output = (Output1 / (1 -(Output2/100d)))
Num.setText(String.format("%.2f",Output));
Hope this solves your problem.
Best regards
If you want to Limit the number of Digits before and after the 'decimal_point' then you can use my solution.
private class DecimalNumberFormatTextWatcher implements TextWatcher{
int pos;
int digitsBeforeDecimal = 6;
int digitsAfterDecimal = 2;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if(s.length() > 2)
pos = start;
else {
pos = start + 2;
}
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
mEdittext.removeTextChangedListener(this);
String text = s.toString();
if(text!= null && !text.equals("")){
if(!text.contains("$")){ //if it does not contains $
text = "$"+text;
} else {
if (text.indexOf("$") > 0) { //user entered value before $
text = s.delete(0, text.indexOf("$")).toString();
}else {
if(!text.contains(".")){ // not a fractional value
if(text.length() > digitsBeforeDecimal+1) { //cannot be more than 6 digits
text = s.delete(pos, pos+1).toString();
}
} else { //a fractional value
if(text.indexOf(".") - text.indexOf("$") > digitsBeforeDecimal+1){ //non fractional part cannot be more than 6
text = s.delete(pos,pos+1).toString();
}
if((text.length() - text.indexOf(".")) > digitsAfterDecimal+1) { //fractinal part cannot be more than 2 digits
text = s.delete(text.indexOf(".") + 2, text.length() - 1).toString();
}
}
}
}
}
mEdittext.setText(text);
mEdittext.setSelection(pos);
mEdittext.addTextChangedListener(this);
}
}
mEdittext.addTextChangedListener(new DecimalNumberFormatTextWatcher());
This also adds a currency sign as soon as the user types the value.
HOPE THIS HELPS ANYONE.

Validation allow only number and characters in edit text in android

In my application I have to validate the EditText. It should only allow character, digits, underscores, and hyphens.
Here is my code:
edittext.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
}
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// TODO Auto-generated method stub
}
#Override
public void afterTextChanged(Editable s) {
// validation codes here
location_name=s.toString();
Toast.makeText(getApplicationContext(),location_name, Toast.LENGTH_SHORT).show();
if (location_name.matches(".*[^a-z^0-9].*")) {
location_name = location_name.replaceAll("[^a-z^0-9]", "");
s.append(location_name);
s.clear();
Toast.makeText(getApplicationContext(),"Only lowercase letters and numbers are allowed!",Toast.LENGTH_SHORT).show();
}
}
});
location.add(location_name);
When I enter input into EditText, the application is force closed.
Instead of using your "manual" checking method, there is something very easy in Android:
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start,
int end, Spanned dest, int dstart, int dend) {
for (int i = start;i < end;i++) {
if (!Character.isLetterOrDigit(source.charAt(i)) &&
!Character.toString(source.charAt(i)).equals("_") &&
!Character.toString(source.charAt(i)).equals("-"))
{
return "";
}
}
return null;
}
};
edittext.setFilters(new InputFilter[] { filter });
Or another approach: set the allowed characters in the XML where you are creating your EditText:
<EditText
android:inputType="text"
android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm,_,-"
android:hint="Only letters, digits, _ and - allowed" />
<EditText
android:inputType="text"
android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm,_,-"
android:hint="Only letters, digits, _ and - allowed"
/>
the above code will also include , additionally to avoid , use the following code
<EditText
android:inputType="text"
android:digits="0123456789qwertzuiopasdfghjklyxcvbnm_-"
android:hint="Only letters, digits, _ and - allowed"
/>
This can be useful, especially if your EditText should allow diacritics (in my case, Portuguese Diacritic):
<EditText
android:digits="0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZzÁáÂâÃãÀàÇçÉéÊêÍíÓóÔôÕõÚú"
/>
A solution similar to the android:digits="0123456789*", is to use this:
EditText etext = new EditText(this);
etext.setKeyListener(DigitsKeyListener.getInstance("0123456789*"));
An added bonus is that it also displays the numeric keypad.
InputFilter filter = new InputFilter() {
public CharSequence filter(CharSequence source, int start,
int end, Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (!Character.toString(source.charAt(i)).matches("[a-zA-Z0-9-_]+")) {
return "";
edittext.setError("Only letters, digits, _ and - allowed");
}
}
return null;
}
};
edittext.setFilters(new InputFilter[] { filter });
Try this:
public static SpannableStringBuilder getErrorMsg(String estring) {
int ecolor = Color.BLACK; // whatever color you want
ForegroundColorSpan fgcspan = new ForegroundColorSpan(ecolor);
SpannableStringBuilder ssbuilder = new SpannableStringBuilder(estring);
ssbuilder.setSpan(fgcspan, 0, estring.length(), 0);
return ssbuilder;
}
Then setError() to EditText when you want show 'only Letters and digits are allowed' as below.
etPhone.setError(getErrorMsg("Only lowercase letters and numbers are allowed!"));
Hope this will help you. I use the same for Validation Check in EditText in my apps.
please try adding the android:digits="abcde.....012345789" attribute? although the android:digits specify that it is a numeric field it does work for me to set it to accept letters as well, and special characters as well (tested on SDK-7)
You can validate this by two ways , both worked for me, hope will be helpful for you too.
1> Mentioning the chars in your edittext .
android:digits="0,1,2,3,4,5,6,7,8,9,*,qwertzuiopasdfghjklyxcvbnm,_,-"
2> Can validate pragmatically as answered by milos pragmatically
use this 2 function
public static boolean isdigit(EditText input)
{
String data=input.getText().toString().trim();
for(int i=0;i<data.length();i++)
{
if (!Character.isDigit(data.charAt(i)))
return false;
}
return true;
}
public static boolean ischar(EditText input)
{
String data=input.getText().toString().trim();
for(int i=0;i<data.length();i++)
{
if (!Character.isDigit(data.charAt(i)))
return true;
}
return false;
}
pass Edittext variable in these function .. so you can have boolean value.

set spaces between letters in textview

is there a way to set a custom space (in pixels) between letters to an editText? I found only how to set spaces between the lines, but bot between letters on the same row
Using android:letterSpacing i was able to add spacing between characters in a textview
<android.support.v7.widget.AppCompatTextView
android:id="#+id/textViewValue"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:letterSpacing="0.35"
android:maxLines="1" />
Related methods:
setLetterSpacing(float)
I had to do this myself today so here are some updates about this problem :
From API 21 you can use XML attribute android:letterSpacing="2" or from code myEditText.setLetterSpacing(2);
Before API 21, use a TextWatcher with the following code
private static final String LETTER_SPACING = " ";
private EditText myEditText;
private String myPreviousText;
...
// Get the views
myEditText = (EditText) v.findViewById(R.id.edt_code);
myEditText.addTextChangedListener(this);
...
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
// Nothing here
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// Nothing here
}
#Override
public void afterTextChanged(Editable s) {
String text = s.toString();
// Only update the EditText when the user modify it -> Otherwise it will be triggered when adding spaces
if (!text.equals(myPreviousText)) {
// Remove spaces
text = text.replace(" ", "");
// Add space between each character
StringBuilder newText = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
if (i == text.length() - 1) {
// Do not add a space after the last character -> Allow user to delete last character
newText.append(Character.toUpperCase(text.charAt(text.length() - 1)));
}
else {
newText.append(Character.toUpperCase(text.charAt(i)) + LETTER_SPACING);
}
}
myPreviousText = newText.toString();
// Update the text with spaces and place the cursor at the end
myEditText.setText(newText);
myEditText.setSelection(newText.length());
}
}
You could implament a custom TextWatcher, and add X spaces every time the user enteres 1.
i have used this, and works for most API levels if not all of them.
KerningViews
Provides a set of views which allows to adjust the spacing between the characters of that view, AKA, Kerning effect.
https://github.com/aritraroy/KerningViews

Categories

Resources