Ответ vorrtex не сработал для меня, но я взял много от него и придумал свое решение. Вот он:
package ie.moses.keepitlocal.util;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.support.annotation.IntRange;
import android.text.Layout;
import android.text.style.LeadingMarginSpan;
import android.view.View;
import android.widget.TextView;
import ie.moses.keepitlocal.util.MeasurementUtils;
import ie.moses.keepitlocal.util.TextUtils;
import static com.google.common.base.Preconditions.checkArgument;
public class WrapViewSpan implements LeadingMarginSpan.LeadingMarginSpan2 {
private final Context _context;
private final int _lineCount;
private int _leadingMargin;
private int _padding;
public WrapViewSpan(View wrapeeView, TextView wrappingView) {
this(wrapeeView, wrappingView, 0);
}
/**
* @param padding Padding in DIP.
*/
public WrapViewSpan(View wrapeeView, TextView wrappingView, @IntRange(from = 0) int padding) {
_context = wrapeeView.getContext();
setPadding(padding);
int wrapeeHeight = wrapeeView.getHeight();
float lineHeight = TextUtils.getLineHeight(wrappingView);
int lineCnt = 0;
float linesHeight = 0F;
while ((linesHeight += lineHeight) <= wrapeeHeight) {
lineCnt++;
}
_lineCount = lineCnt;
_leadingMargin = wrapeeView.getWidth();
}
public void setPadding(@IntRange(from = 0) int paddingDp) {
checkArgument(paddingDp >= 0, "padding cannot be negative");
_padding = (int) MeasurementUtils.dpiToPixels(_context, paddingDp);
}
@Override
public int getLeadingMarginLineCount() {
return _lineCount;
}
@Override
public int getLeadingMargin(boolean first) {
if (first) {
return _leadingMargin + _padding;
} else {
return _padding;
}
}
@Override
public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline,
int bottom, CharSequence text, int start, int end,
boolean first, Layout layout) {
}
}
и в моем фактическом классе, где используется диапазон:
ViewTreeObserver headerViewTreeObserver = _headerView.getViewTreeObserver();
headerViewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
String descriptionText = _descriptionView.getText().toString();
SpannableString spannableDescriptionText = new SpannableString(descriptionText);
LeadingMarginSpan wrapHeaderSpan = new WrapViewSpan(_headerView, _descriptionView, 12);
spannableDescriptionText.setSpan(
wrapHeaderSpan,
0,
spannableDescriptionText.length(),
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
);
_descriptionView.setText(spannableDescriptionText);
ViewTreeObserver headerViewTreeObserver = _headerView.getViewTreeObserver();
headerViewTreeObserver.removeOnGlobalLayoutListener(this);
}
});
Мне нужен глобальный приемник макета, чтобы получить правильные значения для getWidth()
и getHeight()
.
Вот результат:
Воспользуйтесь преимуществом стандарта char_traits
. Напомним, что a std::string
на самом деле является typedef для std::basic_string<char>
или, точнее, std::basic_string<char, std::char_traits<char> >
. Тип char_traits
описывает, как сравниваются символы, как они копируются, как они преобразуются и т. Д. Все, что вам нужно сделать, это ввести новую строку над basic_string
и предоставить свой собственный char_traits
, который сравнивает регистр без учета регистра.
struct ci_char_traits : public char_traits<char> {
static bool eq(char c1, char c2) { return toupper(c1) == toupper(c2); }
static bool ne(char c1, char c2) { return toupper(c1) != toupper(c2); }
static bool lt(char c1, char c2) { return toupper(c1) < toupper(c2); }
static int compare(const char* s1, const char* s2, size_t n) {
while( n-- != 0 ) {
if( toupper(*s1) < toupper(*s2) ) return -1;
if( toupper(*s1) > toupper(*s2) ) return 1;
++s1; ++s2;
}
return 0;
}
static const char* find(const char* s, int n, char a) {
while( n-- > 0 && toupper(*s) != toupper(a) ) {
++s;
}
return s;
}
};
typedef std::basic_string<char, ci_char_traits> ci_string;
Подробная информация о Гуру Недели № 29 .