我被困在一个奇怪的小问题上。Android:动态创建的TextView的宽度有时会出错
这个活动的目标是显示两个文本,一个是原文,第二个答案文本。答案文本包含错误,用户必须找到并标记这些错误。 我们提出的解决方案是将文本拆分为单词,并在TextView中将每个单词显示为自己的单词。所有这些TextView都是在运行时动态创建的,因为可以显示许多不同的文本。 有两种情况,我们需要“换行符”:a)文本中包含换行符(
)和b)显示的宽度不适合任何其他文本。
该解决方案大部分时间都在工作,但每个文本都有2-4个单词,这些单词不符合线宽,因此会在视觉上分成多行。
下面的代码:
String[] questionSplit = exercise.exerciseQuestion.split(" ");
ids = new Integer[questionSplit.length];
int displayWidth = getResources().getDisplayMetrics().widthPixels;
int currentLineWidth = 0;
Integer lastIdInRow = 0;
int counter = 0;
for(String bit : questionSplit) {
TextView tv = new TextView(this);
tv.setId(generateViewId());
ids[counter] = tv.getId();
//Exception for <br>
if(bit.equals("<br>")) {
lastIdInRow = ids[counter - 1];
currentLineWidth = 0;
} else {
tv.setText(bit);
tv.setPadding(dpToPx(3), dpToPx(3), dpToPx(2), dpToPx(2));
tv.measure(0, 0);
currentLineWidth += tv.getMeasuredWidth();
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
if(currentLineWidth <= displayWidth && counter == 0) {
// move along, nothing to see here
} else if(currentLineWidth <= displayWidth && counter != 0) {
p.addRule(RelativeLayout.RIGHT_OF, ids[counter - 1]);
} else {
lastIdInRow = ids[counter - 1];
currentLineWidth = 0;
}
if(lastIdInRow != 0 && lastIdInRow != tv.getId()) {
p.addRule(RelativeLayout.BELOW, lastIdInRow);
}
rlTextComparisonOriginal.addView(tv,p);
}
counter++;
}
为了解释TextViews的布局规则:如果是measuredWidth适合的线路,RIGHT_OF加入最后的ID规则。如果它会溢出,则会添加行规则中的最后一个ID。 正如我前面提到的,对于大多数完美工作的文本。但有些话不适合。如果我将displayWidth更改为显示宽度的80%,则错误只会保留单词更改,所以我认为它不是特定的文本/单词。
这里是视图的XML
<ScrollView
android:id="@+id/svTextComparisonDesc"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/tvTextComparisonHeaderMiddle"
android:paddingBottom="55dp"
>
<RelativeLayout
android:id="@+id/rlTextComparison"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/tvTextComparisonDescription"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="@color/text_background"
android:padding="10dp"
android:text="@string/text_exercise_desription"
android:textSize="@dimen/activity_text_description_size"
android:scrollHorizontally="false"
/>
<RelativeLayout
android:id="@+id/rlTextComparisonOriginal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@color/text_background"
android:layout_below="@id/tvTextComparisonDescription"
/>
<RelativeLayout
android:id="@+id/rlTextComparisonAnswer"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="@id/rlTextComparisonOriginal"
/>
</RelativeLayout>
</ScrollView>
信息的最后一位的相关部分:现在上面的代码驻留在活动的onCreate方法。如果我记录measuredWidth和displayWidth和currentWidth,逻辑没有被破坏,measuredWidth适合该行,但是在渲染之后,它不会。
任何想法实际上可能是什么问题?提前致谢!
使用上述LIB中的代码后是更清洁,看起来像这样:
//Exception for <br>
if(bit.equals("<br>")) {
FlowLayout.LayoutParams lp = new FlowLayout.LayoutParams(0,0);
lp.setNewLine(true);
flTextComparisonOriginal.addView(tv,lp);
} else {
tv.setText(bit);
tv.setPadding(dpToPx(3), dpToPx(3), dpToPx(2), dpToPx(2));
RelativeLayout.LayoutParams p = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
flTextComparisonOriginal.addView(tv, p);
}
完美,谢谢! 我用这个lib [link](https://github.com/ApmeM/android-flowlayout) –