所以我在android中有一个TextView,它具有屏幕整个长度的宽度和dip 5的填充。如何计算屏幕上适合单行的字符数?我想换句话说,我正在尝试获取textview的列数?
我考虑了手工计算取决于文本大小和宽度,但是1)不知道相关性和2)由于以dip为单位的填充,不同的屏幕将使用不同数量的实际像素来填充。
总体问题:我正在尝试使用它来解决:如果给出一个字符串,我怎样才能手动编辑为字符串,以便当textview按字符打印字符串时,我将知道何时开始一个不会出现的字符串适合下一行。注意:我知道textview会自动放入不适合下一行的单词,但是,由于我是逐个字符打印,比如输入动画,textview不知道这个单词在打印出来之前是不适合的这个词的字符溢出。
到处寻找这个......
谢谢!
添加了解决方案:
一种可能的解决方案:
public String measure2 (TextView t, String s) {
String u = "";
int start = 0;
int end = 1;
int space = 0;
boolean ellipsized = false;
float fwidth = t.getMeasuredWidth();
for(;;) {
//t.setText(s.substring(start, end));
float twidth = t.getPaint().measureText(s.substring(start, end));
if (twidth < fwidth){
if (end < s.length())
end++;
else {
if (!ellipsized)
return s;
return u + s.subSequence(start, end);
}
}
else {
ellipsized = true;
space = (u + s.substring(start, end)).lastIndexOf(" ");
if (space == -1)
space = end - 1;
u += s.subSequence(start, space) + "\n";
start = space + 1;
end = start + 1;
}
}
}
解决方案2,但有时仍使用solution1:
public String measure3 (TextView t, String s) {
List<String> wlist = Arrays.asList(s.split(" "));
if (wlist.size() == 1)
return measure2(t, s);
String u = "";
int end = 1;
float fwidth = t.getMeasuredWidth();
for(;;) {
//t.setText(s.substring(start, end));
if (wlist.isEmpty())
return u;
String temp = listStr(wlist, end);
float twidth = t.getPaint().measureText(temp);
if (twidth < fwidth){
if (end < wlist.size())
end++;
else {
return u + temp;
}
}
else {
temp = listStr(wlist, end-1);
if (end == 1)
temp = measure2(t, temp);
if (wlist.isEmpty())
return u + temp;
else
u = u + temp + "\n";
wlist = wlist.subList(end - 1, wlist.size());
end = 1;
}
}
}
public String listStr (List<String> arr, int end) {
String s = "";
for (String e : arr.subList(0, end) ){
s = s + e + " ";
}
return s.trim();
}
我使用上面的代码生成一个原始字符串s,一个将被打印的字符串u。但是,我认为这种方法效率很低。还有其他方法或更好的算法吗?注意:我修复了measure3中的一些错误,但是懒得编辑
答案 0 :(得分:28)
试试这个:
private boolean isTooLarge (TextView text, String newText) {
float textWidth = text.getPaint().measureText(newText);
return (textWidth >= text.getMeasuredWidth ());
}
由于字符的宽度可变,检测到适合的字符数是不可能的。上面的函数将测试TextView中是否符合特定字符串。 newText的内容应该是特定行中的所有字符。如果为true,则启动一个新行(并使用新字符串作为参数传递)。
回答评论:
str.size()>numCol
vs之间有什么区别?您需要实现动画(提示#1:插入换行符)setText
时实现所有这些)。 (提示#3:跟踪使用static int lines;
创建的行并使用newString.split("\\r?\\n")[lines-1]
检查长度。)答案 1 :(得分:1)
您可以通过以下代码获取Textview的总行数并获取每个字符的字符串。然后您可以将样式设置为您想要的每一行。
我将第一行设为粗体。
private void setLayoutListner( final TextView textView ) {
textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
textView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
final Layout layout = textView.getLayout();
// Loop over all the lines and do whatever you need with
// the width of the line
for (int i = 0; i < layout.getLineCount(); i++) {
int end = layout.getLineEnd(0);
SpannableString content = new SpannableString( textView.getText().toString() );
content.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, end, 0);
content.setSpan(new StyleSpan(android.graphics.Typeface.NORMAL), end, content.length(), 0);
textView.setText( content );
}
}
});
}
试试这种方式。你可以用这种方式应用多种风格。
答案 2 :(得分:0)
我遇到了同样的问题,我通过2个步骤计算了每行的字符数: 步骤1:计算行数
import matplotlib.pyplot as plt
x = [(370, 560), (550,980), (380,440)]
def activity_filler(x,y1,y2):
# Shade the area between y1 and y2
plt.fill_between(x, y1, y2,
facecolor="grey", # The fill color
color='grey', # The outline color
alpha=0.4, hatch = 'X\/|-') # Transparency of the fill
activity_filler(x[0],[1],[2])
activity_filler(x[1],[2],[3])
activity_filler(x[2],[3],[4])
plt.show()
第2步:计算每行的字符数
mAuth.createUserWithEmailAndPassword(email, password)
.addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
@Override
public void onComplete(@NonNull Task<AuthResult> task) {
if (task.isSuccessful()) {
// user account created successfully
showMessage("Account created");
// after we created user account we need to update his profile picture and name
updateUserInfo(name, pickedImgUri, mAuth.getCurrentUser());
} else {
// account creation failed
showMessage("account creation failed" + task.getException().getMessage());
regBtn.setVisibility(View.VISIBLE);
loadingProgress.setVisibility(View.INVISIBLE);
}
}
});