set spaces between letters in textview - android

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

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)

How to validate text with lot of empty spaces?

Description:
I am creating an app in which you can change your profile´s name. The problem is that users can write their names with a lot of empty spaces and I don´t know how to avoid this problem.
Example:
(I am going to represent empty spaces with underscore "_")
Edit your name: T_____omas_Men________n____i_ti //// (31 chars)
If someone writes that on an edit text, empty spaces are going to be saved and then we will see that large name into user's profile.
What do I want?
I need a code able to check when the edit text has more than one (> 1) empty spaces in a row in order to delete them. The code should be able to detect that "name" must have one empty space after "last name"
Use TextWatcher as described here: Android: How can I validate EditText input?
Then in onTextChanged(CharSequence s, int start, int before, int count) method you can validate user input, here is example :
if (s.contains(" ")) {
// ask user to edit input
// or change text programatically
String after = before.trim().replaceAll(" +", " ");
// set new text
}
You can restrict EditText by using TextWatcher in tricky way.
Working flow for below code
Create and added TextWatcher to EditText. Did the logic inside onTextChanged function
Logic 1 : To avoid empty space as a first character
Logic 2 : Restrict EditText to allow only one space after a character
Logic 3 : Restrict EditText to allow only one space for entire string
Logic 4 : Remove Text Change Lister before setting value in editText
Logic 5 : Set proper value in editText
Logic 6 : Again add Text Change Lister for editText
Try the below code.
package com.example.application;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
import com.example.myapplication.R;
public class SampleActivity extends AppCompatActivity {
EditText editText;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
editText = findViewById(R.id.editText);
editText.addTextChangedListener(textWatcher);
}
TextWatcher textWatcher = new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String preValue = editText.getText().toString();
/*
* To avoid empty space as a first character
* */
if (preValue.length() > 0 && preValue.trim().isEmpty()) {
editText.setText(preValue.substring(0, s.length() - 1));
editText.setSelection(editText.getText().toString().length());
}
/*
* Restrict EditText to allow only one space after a character
* */
if (preValue.endsWith(" ")) {
editText.setText(preValue.substring(0, s.length() - 1));
editText.setSelection(editText.getText().toString().length());
}
/*
* Restrict EditText to allow only one space for entire string
* */
if (preValue.trim().contains(" ") && preValue.endsWith(" ")) {
/*
* Remove Text Change Lister before setting value in editText
* */
editText.removeTextChangedListener(textWatcher);
/*
* Set proper value in editText
* */
editText.setText(preValue.substring(0, s.length() - 1));
editText.setSelection(editText.getText().toString().length());
/*
* Again add Text Change Lister for editText
* */
editText.addTextChangedListener(textWatcher);
}
if (preValue.contains("---") && preValue.endsWith(" ")) {
String[] words = preValue.split(" ");
if (words.length >= 2) {
editText.setText(preValue.substring(0, s.length() - 1));
editText.setSelection(editText.getText().toString().length());
return;
}
StringBuilder stringBuilder = new StringBuilder();
for (String word : words) {
stringBuilder.append(word).append(" ");
}
/*
* Remove Text Change Lister before setting value in editText
* */
editText.removeTextChangedListener(textWatcher);
/*
* Set proper value in editText
* */
editText.setText(stringBuilder);
editText.setSelection(editText.getText().toString().length());
/*
* Again add Text Change Lister for editText
* */
editText.addTextChangedListener(textWatcher);
}
}
#Override
public void afterTextChanged(Editable s) {
}
};
}
I hope this will solve your problem.
I'm offering a different kind of solution that focuses on working with bare Strings instead of the EditText. Bear in mind that this answer works in combination with the other answers here.
private static String filterMultipleSpaces(String s) {
char[] result = new char[s.length()];
int iC = 0;
for (int iS = 0; iS < s.length(); ++iS) {
char currentChar = s.charAt(iS);
if (currentChar != ' ' || (iC > 0 && result[iC - 1] != ' ')) {
result[iC] = currentChar;
++iC;
}
}
return new String(result);
}
The above static function takes a String and removes multiple spaces. Ideally you would use this when the text changes (see #Divakar's answer) or when submitting the EditText's value if you wish

How to change text color while typing special word

on MultpuAutocompletTexView while Typing I want to make some special word that is start with # want to make that word alone with some colour, how can I do this any help.
so when ever I type with # that word should be in colour text.
like this image
Use TextWatcher with Spanable text, and every time you need to check the last enter word, means the 0 index of last word is #, if YES then apply Spanable for EditText.
please have a look on below code.
define this variable on public level
int beforeChangeSize = 0, afterChangeSize = 0, cusrsorPos = 0, posOflastSpace = 0;
String lastcursorSubString = "";
#Override
public void afterTextChanged(Editable editable) {
if (afterChangeSize > beforeChangeSize) {
cusrsorPos = 0;
posOflastSpace = 0;
lastcursorSubString = "";
cusrsorPos = txt_search.getSelectionStart();
String sudString = txt_search.getText().toString().substring(0, cusrsorPos);
posOflastSpace = sudString.lastIndexOf(" ");
posOflastSpace = (posOflastSpace == -1) ? 0 : posOflastSpace;
lastcursorSubString = sudString.substring(posOflastSpace, cusrsorPos).trim();
if ((lastcursorSubString.length() > 1 &&(lastcursorSubString.charAt(0) == '#') {
textlable.setText(""+lastcursorSubString);
// txt_search.getText().replace(posOflastSpace+1, cusrsorPos, Html.fromHtml("<font color=#FE642E>" + lastcursorSubString + "</font>"));
// txt_search.showDropDown();
editable.setSpan(new ForegroundColorSpan(Color.RED),
posOflastSpace+1,
cusrsorPos,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
}
you should use combination of textWatcher and spannable text
use text watcher to see what user is typing and use spannable text to give special color or format to part of your text in textView or EditText
good tutorial for spannable text :
https://medium.com/google-developers/spantastic-text-styling-with-spans-17b0c16b4568
and documentation for text watcher here :
https://developer.android.com/reference/android/widget/TextView.html#addTextChangedListener(android.text.TextWatcher)
You can add your own TextChangedListener and implement onTextChanged method
myAutoTxtView.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence text, int start, int count, int after) {
}
#Override
public void onTextChanged(CharSequence text, int start, int before, int count) {
if (text.charAt(start) == '#') {
//change color
}
}
#Override
public void afterTextChanged(Editable s) {
}
});
this code to change color - use it in on text change listener like above (its kotlin you need to modify it to Java if you want to)
//get text
val str = editText.text.toString()
//get last word
val splitStr = str.trim { it <= ' ' }.split("\\s+".toRegex()).dropLastWhile {
it.isEmpty() }.toTypedArray()
val ColorWord = splitStr.last()
//get the sentence without the last word
val textButLast = str.substring(0, str.lastIndexOf(" "))
//change the last word color
val LastWord = "<font color='#EE0000'>$ColorWord</font>"
//put the last word with the sentence again
editText.setText(Html.fromHtml(textButLast + LastWord))

Prevent whitespace in a string after one is entered

I made a code where user can't enter first space in a string.
User is allowed to enter white space after min 2 characters.
I need to redefine my method so user enters white space once, and only once after the two or more characters. After that it should be prevented. How do I do that?
case UPDATE_NAME:
if (firstName.getText().toString().startsWith(" "))
firstName.setText(firstName.getText().toString().trim());
if (firstName.getText().toString().contains(" "))
firstName.setText(firstName.getText().toString().replace(" ", " "));
int indexOfSpace = firstName.getText().toString().lastIndexOf(" ");
if (indexOfSpace > 0) {
String beforeSpace = firstName.getText().toString().substring(0, indexOfSpace);
String[] splitted = beforeSpace.split(" ");
if (splitted != null && splitted.length > 0) {
if (splitted[splitted.length - 1].length() < 2)
firstName.setText(firstName.getText().toString().trim());
}
}
Use a regex pattern. I made one that should match your requirements.
\S{2}\S*\s\S*\n
Explanation:
\S{2} two non whitespace
\S* n non whitespace
\s a whitespace
\S* n non whitespace
\n newline (i only added that for regexr, you may not need it)
Alternate way:
Iterate over String.charAt(int), return false if there is a whitespace in the first two chars, count all whitespaces, return false if n > 1.
This method should meet your requirements:
private static boolean isValidFirstName(String firstName) {
if (firstName != null && !firstName.startsWith(" ")) {
int numberOfSpaces = firstName.length() - firstName.replace(" ", "").length();
if (firstName.length() < 2 || numberOfSpaces <= 1) {
return true;
}
}
return false;
}
What you need to do is use a TextWatcher
public class CustomWatcher implements TextWatcher {
private String myText;
private int count = 0;
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after){
myText= s;
}
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
#Override
public void afterTextChanged(Editable s) {
//check if there is a space in the first 2 characters, if so, sets the string to the previous before the space
if(s.length() < 3 && s.contains(" "))
s= myText;
//if the length is higher than 2, and the count is higher than 0 (1 space added already), puts the string back if a space is entered
else if(s.contains(" ") && count > 0)
s= myText;
//If none of the above is verified and you enter a space, increase count so the previous if statement can do its job
else if(s.contains(" "))
count++;
}
}
And then, set it to your EditText
mTargetEditText.addTextChangedListener(new CustomWatcher());
You can control your editText(I assume) with a TextWatcher, you would only need to check inside afterTextChanged() if length is <2 and else if the string contains the char " ".

Set max length to EditText layout_width

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.

Categories

Resources