我想要在array
内显示可变大小的gridlayout
个标记。问题是标签的长度不一,将它们置于statically
定义的网格中看起来很麻烦,即使某些标签比其他标签大得多。
所以我希望能够在标记之后添加标记,直到没有剩余空间用于完整标记,然后转到下一行。基本上是这样的:
| *** ****** ****** ** ***** |
| ** ***** *** ********* *** |
| ********* ***** *** |
| ************** ******** |
| ****** ******** ******** |
| ***************** |
| ************** ***** ***** |
我认为你们明白了。
现在,我得到了类似的东西,但它并没有完全符合我的需要。
int total = tags.size();
int column = 3;
int row = total / column;
suggestedTagsLayout.setColumnCount(column);
suggestedTagsLayout.setRowCount(row + 1);
for (int i = 0, c = 0, r = 0; i < total; i++, c++) {
if (c == column) {
c = 0;
r++;
}
TextView tag = createNewTag(tags.get(i));
tag.setBackgroundColor(Color.BLUE);
tag.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
GridLayout.Spec rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 1);
GridLayout.Spec colspan = GridLayout.spec(GridLayout.UNDEFINED, 1);
if (r == 0 && c == 0) {
logger.e("spec");
colspan = GridLayout.spec(GridLayout.UNDEFINED, 1);
rowSpan = GridLayout.spec(GridLayout.UNDEFINED, 1);
}
logger.d("\n\ntag = " + tag.getText().toString());
int width = tag.getWidth();
int height = tag.getHeight();
logger.d("width = " + width);
logger.d("height = " + height);
width = tag.getMeasuredWidth();
height = tag.getMeasuredHeight();
logger.d("getMeasuredWidth = " + width);
logger.d("getMeasuredHeight = " + height);
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams(
rowSpan, colspan);
suggestedTagsLayout.addView(tag, gridParam);
}
这看起来更像是:
| ***** **** ******** **** |
| **** ******** |
| ******* ****** |
所以我也尝试获取每个TextView
的宽度,以便我可以手动计算空格并相应地添加项目,但由于维度不是0
,因此它们也会失败画。因此,我似乎必须相应地使用API来获得所需的行为。
我还是这个GridLayout
的新手,api非常大,所以你们可以帮帮我吗?
答案 0 :(得分:2)
好吧,我设法通过计算需要多少空间以及剩余多少空间来解决我自己的问题。当标签插入的空间太小时,它将转到下一行。
private void fillSuggestedTagsLayout() {
// get all strings to insert in tag
ArrayList<String> tagsText = getTagsList();
// maps for connecting string to textview and string to textview width
HashMap<String, TextView> tagMap = new HashMap<>();
HashMap<String, Integer> tagWidthMap = new HashMap<>();
// total width
float totalWidth = 0;
// for each string
for (String s : tagsText) {
// create textview
TextView txtView = createNewTag(s, false);
// store textview with string
tagMap.put(s, txtView);
// store width also
tagWidthMap.put(s, txtView.getMeasuredWidth());
logger.d("width of txtView = " + txtView.getMeasuredWidth());
// count all textview widths in order to calculate amount of rows needed for display
totalWidth += txtView.getMeasuredWidth();
}
// gridlayout width to calculate rows needed
final float layoutWidth = suggestedTagsLayout.getWidth();
logger.e("gridlayout width = " + layoutWidth);
logger.e("total = " + totalWidth);
// amount of rows equals to totalwidth of elements / layout width
final float rows = totalWidth / layoutWidth;
int rowsRounded = (int) rows;
// rows needed could be 1,2 or something meaning that we need extra space.
// every decimal will need to get rounded up. 1.2 becomes 2 for example
if (rows > rowsRounded) {
rowsRounded++;
}
// total amount of elements
int total = tagsText.size();
// column count, 200 in order to have great precision in position of elements
final int columns = 200;
// amount of space needed per column
final float dpPerColumn = layoutWidth / (float) columns;
// set layout specs
suggestedTagsLayout.setColumnCount(columns);
suggestedTagsLayout.setRowCount(rowsRounded);
for (int item = 0, column = 0, row = 0; item < total; item++) {
// get string
String s = tagsText.get(item);
// get txtview
TextView tag = tagMap.get(s);
tag.setLayoutParams(new ViewGroup.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT));
// calculate amount of columns needed for tag.
// tagwidth/sizePerColumn
float colsToSpan = tagWidthMap.get(s) / dpPerColumn;
// again, round up above in order to accomodate space needed
int colsToSpanRounded = (int) colsToSpan;
if (colsToSpan < colsToSpanRounded) {
colsToSpanRounded++;
}
// now that we know the amount space needed for tag,
// check if there is enough space on this row
if ((column + colsToSpanRounded) > columns) {
column = 0;
row++;
}
// put tag on row N, span 1 row only
GridLayout.Spec rowSpan = GridLayout.spec(row, 1);
// put tag on column N, span N rows
GridLayout.Spec colSpan = GridLayout.spec(column, colsToSpanRounded);
logger.d("tag: " + s + " is taking " + colsToSpanRounded + " columns");
logger.d("c = " + column + " colsToSpan =" + colsToSpanRounded);
logger.d("spanning between " + column + " and " + (column + colsToSpanRounded));
logger.d(" ");
// increment column
column += colsToSpanRounded;
GridLayout.LayoutParams gridParam = new GridLayout.LayoutParams(
rowSpan, colSpan);
// add tag
suggestedTagsLayout.addView(tag, gridParam);
}
}
使用以下内容创建标签并进行测量:
private TextView createNewTag(final String tagText, boolean withImage) {
TextView textView = new TextView(getActivity());
textView.setPadding(8,8,8,8);
textView.setTypeface(Typeface.DEFAULT);
textView.setText(tagText, TextView.BufferType.SPANNABLE);
textView.setTextSize(TypedValue.COMPLEX_UNIT_DIP, 15);
textView.setBackground(getActivity().getResources().getDrawable(R.drawable.tag_background));
if(withImage) {
Drawable img = getActivity().getResources().getDrawable(R.drawable.delete_tag_icon);
textView.setCompoundDrawablesWithIntrinsicBounds(img, null, null, null);
}
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
textView.measure(widthMeasureSpec, heightMeasureSpec);
logger.d(tagText);
return textView;
}
通过执行以下操作计算deviceWith:
DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
deviceWidth = metrics.widthPixels;
deviceHeight = metrics.heightPixels;