Я создал собственный класс, который расширяет TextView и добавляет метод «setSpacing». Обходной путь похож на то, что сказал @Noah. Метод добавляет пробел между каждой буквой строки, а с помощью SpannedString изменяет TextScaleX пробелов, обеспечивая положительный и отрицательный интервал.
Надеюсь, что это поможет кому-то ^^
/**
* Text view that allows changing the letter spacing of the text.
*
* @author Pedro Barros (pedrobarros.dev at gmail.com)
* @since May 7, 2013
*/
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ScaleXSpan;
import android.util.AttributeSet;
import android.widget.TextView;
public class LetterSpacingTextView extends TextView {
private float spacing = Spacing.NORMAL;
private CharSequence originalText = "";
public LetterSpacingTextView(Context context) {
super(context);
}
public LetterSpacingTextView(Context context, AttributeSet attrs){
super(context, attrs);
}
public LetterSpacingTextView(Context context, AttributeSet attrs, int defStyle){
super(context, attrs, defStyle);
}
public float getSpacing() {
return this.spacing;
}
public void setSpacing(float spacing) {
this.spacing = spacing;
applySpacing();
}
@Override
public void setText(CharSequence text, BufferType type) {
originalText = text;
applySpacing();
}
@Override
public CharSequence getText() {
return originalText;
}
private void applySpacing() {
if (this == null || this.originalText == null) return;
StringBuilder builder = new StringBuilder();
for(int i = 0; i < originalText.length(); i++) {
builder.append(originalText.charAt(i));
if(i+1 < originalText.length()) {
builder.append("\u00A0");
}
}
SpannableString finalText = new SpannableString(builder.toString());
if(builder.toString().length() > 1) {
for(int i = 1; i < builder.toString().length(); i+=2) {
finalText.setSpan(new ScaleXSpan((spacing+1)/10), i, i+1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}
super.setText(finalText, BufferType.SPANNABLE);
}
public class Spacing {
public final static float NORMAL = 0;
}
}
Использование:
LetterSpacingTextView textView = new LetterSpacingTextView(context);
textView.setSpacing(10); //Or any float. To reset to normal, use 0 or LetterSpacingTextView.Spacing.NORMAL
textView.setText("My text");
//Add the textView in a layout, for instance:
((LinearLayout) findViewById(R.id.myLinearLayout)).addView(textView);
Реализация библиотеки времени выполнения AC не должна вводить имена, которых нет в стандарте, если они не следуют определенному соглашению об именах (например, начинаются с подчеркивания). Ранние версии компилятора Microsoft не следовали этому правилу особенно внимательно, но со временем Microsoft все больше продвигалась к тому, чтобы сделать их реализацию более совместимой со стандартами. Таким образом, функции, которые они использовали для предоставления, вторглись бы в пространство имен пользователя, которое они реализуют, используя имена, которые зарезервированы для реализаций компилятора и не рекомендуют старые имена.
Если определено _CRT_NONSTDC_NO_WARNINGS
, компилятор MS не будет жаловаться на то, что функция itoa ()
устарела. Но он все равно будет жаловаться на то, что это небезопасно (вы должны определить _CRT_SECURE_NO_WARNINGS
, чтобы заглушить это предупреждение). Или используйте более безопасную версию функции ( _itoa_s ()
), которая предоставляет функции размер целевого буфера
Оба _itoa ()
и itoa ()
разрешаются к той же самой функции в библиотеке по тому же адресу - нет никакой разницы, кроме имени.
В документации MSDN для itoa ()
говорится:
Эта функция POSIX устарела, начиная с Visual C ++ 2005. Используйте совместимый с ISO C ++
_itoa
или безопасность -enhanced_itoa_s
вместо этого.
itoa не является стандартом C.
«Эта функция не определена в ANSI-C и не является частью C ++, но поддерживается некоторыми компиляторами ". - cplusplus.com
Итак, MSVS предлагает вам использовать _itoa, чтобы сообщить вам, что это не стандартный C ++ и что вы должны отметить его как таковой.
itoa
не является стандартным, поэтому вам следует использовать вместо него строковый поток.
вам понадобится #include
, пример его использования будет :
int i = 5;
std::stringstream ss;
ss << i;
std:: cout << ss.str();
В ответ на ответ Брюса:
itoa
не является стандартным, поэтому вам следует использовать вместо него stringstream.вам понадобится
#include
пример его использования:
int i = 5;
std :: stringstream ss;
ss << i;
std :: cout << ss.str ( );
Вы также можете написать свою собственную функцию itoa ()
вместо
, например:
const char* itoa (int num)
{
if (num == 0)
{
return "0";
}
bool neg = false;
if (num < 0)
{
neg = true;
num = -num;
}
int digits = 0;
int tmp = num;
while (tmp > 0)
{
digits++;
tmp /= 10;
}
int digs[digits];
for (tmp = digits; num > 0; tmp--)
{
digs[tmp] = num % 10;
num /= 10;
}
string s = neg == true ? "-" : "";
for (tmp = 1; tmp <= digits; tmp++)
{
s += (char)(digs[tmp] + 48);
}
return s.c_str();
}