自定义视图类不在自定义ViewGroup中绘制自身

时间:2016-04-07 16:29:29

标签: android android-layout android-view viewgroup

我的自定义View中的自定义ViewGroup拒绝通过调用drawable来显示setImageResource()。它按照我的需要进行布局,但是,正如您在此屏幕截图中看到的那样,它是空的:

enter image description here

此外,它不会对onClick事件做出反应。

这是我的活动的

的java代码
public class MainActivity extends Activity {

public static final String TAG = "MainActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    BattleShipsGameBoard gb = (BattleShipsGameBoard) findViewById(R.id.gameboard);

    Tile tile = new Tile(this);
    tile.setImageResource(R.drawable.tile_hit);
    tile.setGameObjectType(BattleShipsGameBoard.LayoutParams.LAYOUT_TYPE_TILE);
    tile.setPosition(new Point(50, 50));
    tile.setWidth(90);
    tile.setHeight(90);
    gb.addView(tile);
    }
}

和我的自定义视图

public class Tile extends ImageView {

@SuppressWarnings("unused")
private static final String TAG = "Tile";

public int tag;
public int gameObjectType;
public Point position = new Point(0, 0);
public int mWidth = 1;
public int mHeight = 1;

public boolean isSelected = false;

public Tile(Context context) {
    super(context);
    setLayoutParams(new BattleShipsGameBoard.LayoutParams(
            BattleShipsGameBoard.LayoutParams.WRAP_CONTENT,
            BattleShipsGameBoard.LayoutParams.WRAP_CONTENT));
}

public Tile(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public Tile(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public void confirmChangesInLayout() {
    BattleShipsGameBoard.LayoutParams lp = (BattleShipsGameBoard.LayoutParams) this
            .getLayoutParams();
    lp.setPosition(this.position);
    lp.setWidth(this.mWidth);
    lp.setHeight(this.mHeight);
    setLayoutParams(lp);

    invalidate();
    requestLayout();
}

//... getters and setters, the setters all call confirmChangesInLayout() 
}

我的简单自定义ViewGroup:

public class BattleShipsGameBoard extends ViewGroup {

public static class LayoutParams extends MarginLayoutParams {

    public LayoutParams(Context c, AttributeSet attrs) {
        super(c, attrs);
    }

    public LayoutParams(int width, int height) {
        super(width, height);
    }

    public Point position = new Point(0, 0);
    public int type = 0;
    public int height = 0;
    public int width = 0;

    //getters and setters

    }

public BattleShipsGameBoard(Context context) {
    super(context);
}

public BattleShipsGameBoard(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public BattleShipsGameBoard(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

private float unitWidth;
private float unitHeight;
private int parentWidth;
private int parentHeight;

/**
 * count of units the screen estate is divided by
 */
public static int unitCount = 100;

/**
 * Rectangle in which the size of a child is temporarily stored
 */
private Rect mTmpChildRect = new Rect();

/**
 * lays out children
 */
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {

    Log.d(TAG, "-------------STARTING LAYOUT, " + getChildCount() + " children -------------");
    int count = getChildCount();

    for (int i = 0; i < count; i++) {
        final View child = getChildAt(i);

        if (child.getVisibility() != GONE) {
            LayoutParams lp = (LayoutParams) child.getLayoutParams();

            Point pos = lp.getPosition();
            int height = lp.getHeight();
            int width = lp.getWidth();

            measureChild(child, parentWidth, parentHeight);

            mTmpChildRect.left = (int) ((pos.x - (width / 2)) * unitWidth);
            mTmpChildRect.right = (int) ((pos.x + (width / 2)) * unitWidth);
            mTmpChildRect.top = (int) ((pos.y + (height / 2)) * unitHeight);
            mTmpChildRect.bottom = (int) ((pos.y - (height / 2)) * unitHeight);

            child.layout(mTmpChildRect.left, mTmpChildRect.top, mTmpChildRect.right, mTmpChildRect.bottom);
            Log.d(TAG,

        }
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    parentHeight = MeasureSpec.getSize(heightMeasureSpec);
    parentWidth = MeasureSpec.getSize(widthMeasureSpec);

    unitHeight = parentHeight / unitCount;
    unitWidth = parentWidth / unitCount;

    for (int i = 0; i < getChildCount(); i++) {
        View child = getChildAt(i);
        if (child.getVisibility() != View.GONE) {
            child.measure(widthMeasureSpec, heightMeasureSpec);

        }
    }

    setMeasuredDimension(parentWidth, parentHeight);
}

/**
 * Any layout manager that doesn't scroll will want this.
 */
@Override
public boolean shouldDelayChildPressedState() {
    return false;
}

}

1 个答案:

答案 0 :(得分:0)

我刚发现了这个问题。

onLayout()方法中,我混淆了mTmpChildRect.topmTmpChildRect.bottom,这就是为什么它看起来像是正确布局但没有任何东西可以绘制。