我正在创建一个自定义布局(viewgroup子类),它将自身划分为单元格,然后根据单元格位置和单元格宽度/高度定位子布局。
将其视为小部件的组织方式。
我添加了一堆具有不同背景颜色的框架布局,它们似乎正确定位。然而,当我放入textview时,它会在垂直方向上扩展得更好,并且水平地保持固定宽度。这个职位可以正常运作。
代码:
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
public class DynamicLayout extends ViewGroup {
int numCellsX = 6, numCellsY = 8;
int cellSize;
int blockMap[];
public DynamicLayout(Context context) {
super(context);
init();
}
public DynamicLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public DynamicLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init()
{
blockMap = new int[numCellsX * numCellsY];
clearBlockMap();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
cellSize = getMeasuredWidth() / numCellsX;
int specWidth = MeasureSpec.getSize(widthMeasureSpec);
int specHeight = MeasureSpec.getSize(heightMeasureSpec);
this.setMeasuredDimension(specWidth, specHeight);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (getChildCount() > 0) {
int wspec = MeasureSpec.makeMeasureSpec(getMeasuredWidth()
/ getChildCount(), MeasureSpec.EXACTLY);
int hspec = MeasureSpec.makeMeasureSpec(getMeasuredHeight(),
MeasureSpec.EXACTLY);
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
v.measure(wspec, hspec);
}
}
Log.i("DYNA", "Measured");
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
Log.i("DYNA", "On Layout");
clearBlockMap();
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if (v instanceof DynaServiceView) {
DynaServiceView serviceView = (DynaServiceView) v;
if (serviceView.getVisibility() == GONE)
continue;
int x = serviceView.getXPos();
int y = serviceView.getYPos();
int width = serviceView.getXCells();
int height = serviceView.getYCells();
//Is the thing too big?
if (width > numCellsX)
{
Log.i("DYNA", "Warning, service too big, shrinking to size");
width = numCellsX;
serviceView.setWidth(width);
}
//Is there space?
if (checkBlockMap(x, y, width, height))
{
Log.i("DYNA", "Found collision at child " + i +", resolving...");
//Find somewhere to put this
boolean foundSpot = false;
for (int j = y; j <= numCellsY - height; j++)
{
for (int k = x; k <= numCellsX - width; k++)
{
if (!checkBlockMap(k, j, width, height))
{
x = k;
y = j;
foundSpot = true;
break;
}
}
if (foundSpot)
break;
}
if (!foundSpot)
Log.i("DYNA", "No spot for child at: " + i + ", skipping!");
else
Log.i("DYNA", "Resolved! New X/Y: " + x + ", " + y);
}
setBlockMap(x, y, width, height);
//Has spot now, set layout
serviceView.layout(l + (x * cellSize), t + (y * cellSize), (x * cellSize)
+ (width * cellSize), (y * cellSize)
+ (height * cellSize));
}
}
}
private boolean checkBlockMap(int x, int y, int width, int height)
{
for (int j= y; j < y + height; j++)
{
for (int k = x; k < x + width; k++)
if (blockMap[(j * numCellsX) + k] == 1)
return true;
}
return false;
}
private void setBlockMap(int x, int y, int width, int height)
{
for (int j= y; j < y + height; j++)
{
for (int k = x; k < x + width; k++)
blockMap[(j * numCellsX) + k] = 1;
}
}
private void clearBlockMap()
{
for (int i = 0; i < blockMap.length;i++)
blockMap[i] = 0;
}
}
这是解释问题的图片。在右侧,您可以看到布局的边框正确排列,但是在左侧显然,子文本视图没有跟随它。
答案 0 :(得分:1)
发现问题.... onMeasure设置不正确。愚蠢的错误。