带有包装内容项的 RecyclerView
RecyclerView with wrap content items
我需要实施下一个 UI 元素:
- 未知大小的字符串列表(来自服务器调用)
- 任何项目都应该是包装内容。
- 如果一个项目不适合一行,他将在下一行。
- 全部list/grid居中
我想用 RecyclerView
和 StaggeredGridLayoutManager
但我不知道这样做是否正确,有什么想法吗?
每行中的单元格数量不同这一事实意味着您必须相当努力地工作才能从回收方法中获得任何价值。因为为了知道第 17 行中有哪些数据,您必须(预先)测量第 0 - 16 行中的所有数据。
取决于您的用例。如果列表限制在一些合理数量的项目上。使用单个 TextView
和一些 clever use of spans 可能是更好的解决方案。只需将所有主题标签收集到一个字符串中,然后使用 RoundedBackgroundSpan
(参见 link)添加彩色背景。然后将整个内容包装在 ScrollView
.
中
编辑 1:添加了可能的解决方案代码。
public class RoundedBackgroundSpan extends ReplacementSpan {
int mBackgroundColor;
int mTextColor;
float mRoundedCornerRadius;
float mSidePadding = 10; // play around with these as needed
float mVerticalPadding = 30; // play around with these as needed
public RoundedBackgroundSpan(final int backgroundColor, final int textColor, final float roundedCornerRadius)
{
mBackgroundColor = backgroundColor;
mTextColor = textColor;
mRoundedCornerRadius = roundedCornerRadius;
}
@Override
public int getSize(final Paint paint, final CharSequence text, final int start, final int end, final Paint.FontMetricsInt fm)
{
return Math.round(MeasureText(paint, text, start, end) + (2 * mSidePadding));
}
@Override
public void draw(final Canvas canvas, final CharSequence text, final int start, final int end, final float x, final int top, final int y, final int bottom, final Paint paint)
{
// draw the rounded rectangle background
RectF rect = new RectF(x, -mVerticalPadding + ((bottom + top) / 2) + paint.getFontMetrics().top, x + MeasureText(paint, text, start, end) + (2 * mSidePadding), mVerticalPadding + ((bottom + top) / 2) + paint.getFontMetrics().bottom);
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, mRoundedCornerRadius, mRoundedCornerRadius, paint);
// draw the actual text
paint.setColor(mTextColor);
canvas.drawText(text, start, end, x + mSidePadding, ((bottom + top) / 2), paint);
}
private float MeasureText(Paint paint, CharSequence text, int start, int end)
{
return paint.measureText(text, start, end);
}
}
还有其他地方(activity/片段最有可能)
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
for (String hashTag : hashTags)
{
stringBuilder.append(hashTag);
stringBuilder.setSpan(new RoundedBackgroundSpan(getRandomColor(), getResources().getColor(android.R.color.darker_gray), 10), stringBuilder.length() - hashTag.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.append(" ");
}
textView.setText(stringBuilder);
还有你的 xml 中的某处(注意 android:lineSpacingMultiplier="3" 和 android:gravity="center")
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:lineSpacingMultiplier="3"
android:gravity="center"
android:padding="10dp"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
我不确定该方法是否对您有帮助,但
using RecyclerView with StaggeredGridLayoutManager
你可以使用第三方 FlowLayout
:
查看此要点以获取完整示例:
https://github.com/davidbeloo/Hashtags
我需要实施下一个 UI 元素:
- 未知大小的字符串列表(来自服务器调用)
- 任何项目都应该是包装内容。
- 如果一个项目不适合一行,他将在下一行。
- 全部list/grid居中
我想用 RecyclerView
和 StaggeredGridLayoutManager
但我不知道这样做是否正确,有什么想法吗?
每行中的单元格数量不同这一事实意味着您必须相当努力地工作才能从回收方法中获得任何价值。因为为了知道第 17 行中有哪些数据,您必须(预先)测量第 0 - 16 行中的所有数据。
取决于您的用例。如果列表限制在一些合理数量的项目上。使用单个 TextView
和一些 clever use of spans 可能是更好的解决方案。只需将所有主题标签收集到一个字符串中,然后使用 RoundedBackgroundSpan
(参见 link)添加彩色背景。然后将整个内容包装在 ScrollView
.
编辑 1:添加了可能的解决方案代码。
public class RoundedBackgroundSpan extends ReplacementSpan {
int mBackgroundColor;
int mTextColor;
float mRoundedCornerRadius;
float mSidePadding = 10; // play around with these as needed
float mVerticalPadding = 30; // play around with these as needed
public RoundedBackgroundSpan(final int backgroundColor, final int textColor, final float roundedCornerRadius)
{
mBackgroundColor = backgroundColor;
mTextColor = textColor;
mRoundedCornerRadius = roundedCornerRadius;
}
@Override
public int getSize(final Paint paint, final CharSequence text, final int start, final int end, final Paint.FontMetricsInt fm)
{
return Math.round(MeasureText(paint, text, start, end) + (2 * mSidePadding));
}
@Override
public void draw(final Canvas canvas, final CharSequence text, final int start, final int end, final float x, final int top, final int y, final int bottom, final Paint paint)
{
// draw the rounded rectangle background
RectF rect = new RectF(x, -mVerticalPadding + ((bottom + top) / 2) + paint.getFontMetrics().top, x + MeasureText(paint, text, start, end) + (2 * mSidePadding), mVerticalPadding + ((bottom + top) / 2) + paint.getFontMetrics().bottom);
paint.setColor(mBackgroundColor);
canvas.drawRoundRect(rect, mRoundedCornerRadius, mRoundedCornerRadius, paint);
// draw the actual text
paint.setColor(mTextColor);
canvas.drawText(text, start, end, x + mSidePadding, ((bottom + top) / 2), paint);
}
private float MeasureText(Paint paint, CharSequence text, int start, int end)
{
return paint.measureText(text, start, end);
}
}
还有其他地方(activity/片段最有可能)
SpannableStringBuilder stringBuilder = new SpannableStringBuilder();
for (String hashTag : hashTags)
{
stringBuilder.append(hashTag);
stringBuilder.setSpan(new RoundedBackgroundSpan(getRandomColor(), getResources().getColor(android.R.color.darker_gray), 10), stringBuilder.length() - hashTag.length(), stringBuilder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.append(" ");
}
textView.setText(stringBuilder);
还有你的 xml 中的某处(注意 android:lineSpacingMultiplier="3" 和 android:gravity="center")
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:lineSpacingMultiplier="3"
android:gravity="center"
android:padding="10dp"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>
我不确定该方法是否对您有帮助,但
using RecyclerView with StaggeredGridLayoutManager
你可以使用第三方 FlowLayout
:
查看此要点以获取完整示例:
https://github.com/davidbeloo/Hashtags