Необходимо вписать текст в TextView ограниченный кругом. пример Подскажите, в какую сторону копать
Ответ
Написал код onDraw(Canvas canvas) своего класса наследника TextViewрешающий задачу для меня. Комментарии описываю последовательность действий:
@Override
protected void onDraw(Canvas canvas) {
// круг, в который вписан текст
canvas.drawCircle(mRadius, mRadius, mRadius, mGlowPaint);
// высота строки
float textHeight = mTextPaint.getFontSpacing();
// измеряем длинну текста
float widthText = mTextPaint.measureText(mText);
if(widthText <= mRadius*2) {
// всего одна строка помещается - рисуем ее и выходим
canvas.drawText(mText, mRadius, mRadius, mTextPaint);
return;
}
// 1 Делим строку на два, сдвигаем к ближайшему пробелу. получаем индекс пробела, близкого к середине текста
int centerSpace = calcCenterSpace(mText);
// 2 Сначала рисуем текст вверх :
String leftString = mText.substring(0, centerSpace);
int cnt = 0; // количество прорисованных строк вверх
float widthLine;
int n;
while (true) {
// измеряем длинну строки
widthLine = calcWidthLine(mRadius, textHeight * cnt++);
// считаем сколько символов поместится в новой строке
n = mTextPaint.breakText(leftString, false, widthLine, null);
if (n == 0) // прерываем, так как строка слишком длинная
break;
// создаем строку
int rest = leftString.length() - n;
// проверка на последнюю строку
if (rest != 0) {
String s = leftString.substring(leftString.length() - n);
// обрезаем до первого пробела
int fixed = s.indexOf(' ');
// создаем новую аккуратную строку
s = s.substring(fixed + 1);
// рисуем ее на высоте соответствующую данной строке
canvas.drawText(s, mRadius, mRadius - textHeight * cnt + textHeight, mTextPaint);
// сокращаем левый кусок текста на длинну отрисованной строки
leftString = leftString.substring(0, leftString.length() - s.length());
} else { // последняя строка
canvas.drawText(leftString, mRadius, mRadius - textHeight * cnt + textHeight, mTextPaint);
break;
}
}
// 3. Теперь рисуем вниз
String rightString = mText.substring(centerSpace);
cnt = 0; // количество прорисованных строк вверх
while(true){
widthLine = calcWidthLine(mRadius, textHeight * cnt++);
n = mTextPaint.breakText(rightString, false, widthLine, null);
if (n == 0) // прерываем если весь текст не поместился
break;
int rest = rightString.length() - n;
if(rest != 0) {
String s = rightString.substring(0, n);
int fixed = s.lastIndexOf(' ');
s = s.substring(0, fixed);
canvas.drawText(s, mRadius, mRadius + textHeight * cnt, mTextPaint);
rightString = rightString.substring(s.length(), rightString.length());
}
else {
canvas.drawText(rightString, mRadius, mRadius + textHeight * cnt, mTextPaint);
break;
}
}
}
private static int calcWidthLine(float r, float b){
double a = Math.sqrt(r * r - b * b);
return (int)(2*a);
}
private static int calcCenterSpace(String text){
int index = text.length()/2;
if(text.charAt(index) == ' ') return index;
String subLeft = text.substring(0, index);
int indexSpaceLeft = subLeft.lastIndexOf(' ');
String subRight = text.substring(index + 2);
int indexSpaceRight = subRight.indexOf(' ');
if(index - indexSpaceLeft <= indexSpaceRight)
return indexSpaceLeft;
else
return indexSpaceRight;
}
Алгоритм не идеален, на поставленную задачу выполняет. Еще в планах сделать растягивание строки. Оптимизация и недочеты приветствую.
Вот скриншоты:
Комментариев нет:
Отправить комментарий