我有一个自定义视图,我试图动态地在Y方向上使它更大。这是唯一不起作用的方向。如果我在自定义视图中调整任何其他变量,则矩形会以适当的方式受到影响。如果我尝试添加到bottomY
,那么底部边框就会消失,并且没有任何内容可以在下方绘制。以下是视图的代码:
private class RectView extends View{
float leftX, rightX, topY, bottomY;
boolean isAppt;
boolean isBeforeTime;
boolean isSelected;
public Paint rectPaint;
private RectF rectangle;
String time;
public RectView(Context context, float _leftX, float _rightX, float _topY, float _bottomY,
boolean _isAppt, boolean _isBeforeTime, String _time){
super(context);
leftX = _leftX;
rightX = _rightX;
topY = _topY;
bottomY = _bottomY;
isAppt = _isAppt;
isBeforeTime = _isBeforeTime;
time = _time;
init();
}
private void init(){
rectPaint = new Paint();
if(leftX > rightX || topY > bottomY)
Toast.makeText(context, "Incorrect", Toast.LENGTH_SHORT).show();
MyUtility.LogD_Common("Left = " + leftX + ", Top = " + topY + ", Right = " + rightX +
", Bottom = " + bottomY);
rectangle = new RectF(leftX, topY, rightX, bottomY);
float height = bottomY;
float width = rightX - leftX;
MyUtility.LogD_Common("Height = " + height + ", Width = " + width);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.FILL_PARENT, (int) height);
//params.leftMargin = (int) leftX;
params.bottomMargin = 10;
//params.rightMargin = 10;
setLayoutParams(params);
}
protected void onDraw(Canvas canvas){
MyUtility.LogD_Common("Right = " + rightX);
rectangle.left = leftX;
rectangle.right = rightX;
rectangle.top = topY;
rectangle.bottom = bottomY;
if(!isSelected){
if(isAppt){
if(isBeforeTime)
rectPaint.setARGB(144, 119, 98, 95);
else
rectPaint.setARGB(144, 217, 131, 121);
//119,98,95
rectPaint.setStyle(Style.FILL);
}
else{
rectPaint.setARGB(0, 0, 0, 0);
rectPaint.setStyle(Style.FILL);
}
canvas.drawRect(rectangle, rectPaint);
if(isAppt){
rectPaint.setColor(Color.RED);
rectPaint.setStrokeWidth(2);
rectPaint.setStyle(Style.STROKE);
canvas.drawRect(rectangle, rectPaint);
}
}
else{
rectPaint.setARGB(144, 197, 227, 191);
rectPaint.setStyle(Style.FILL);
canvas.drawRect(rectangle, rectPaint);
rectPaint.setColor(Color.GREEN);
rectPaint.setStrokeWidth(2);
rectPaint.setStyle(Style.STROKE);
canvas.drawRect(rectangle, rectPaint);
}
}
}
为什么会发生这种情况,为什么只能在正Y方向发生?
答案 0 :(得分:0)
创建此对象时,请调用init()
,在其中将RelativeLayout参数的高度规格设置为您定义的局部变量height
:
float height = bottomY;
通过这样做,你告诉父亲RelativeLayout这个视图想要正好是创建对象时bottomY
的高度。
如果你为已经创建的对象增加bottomY
的值,它就不再适合你在第一次创建对象时在RelativeLayout参数中定义的高度。
首先,不建议以这种方式从类内部更改LayoutParams。这使您的自定义视图不灵活。如果在类中设置了一堆RelativeLayout.LayoutParams,那么您的自定义View只能在RelativeLayout中使用。 您应该在添加视图之前在代码中设置LayoutParams。例如:
RectView rectView = new RectView(...);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
addView(rectView, params);
其次,当系统绘制添加了自定义视图的布局时,它会经历一系列步骤。在布局过程中,它会在其所有子视图(包括您的自定义视图)上调用getMeasuredWidth()
和getMeasuredHeight()
。您应该覆盖自定义视图onMeasure()
方法,并让它报告正确的视图大小。请参阅ViewGroup参考文档中示例中的onMeasure()
。它比您的案例更复杂onMeasure()
,但它为您提供了基本的想法。
在您的特定情况下,类似下面的内容应该可以解决问题:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int width = measureWidth(widthMeasureSpec);
int height = measureHeight(heightMeasureSpec);
setMeasuredDimension(width, height);
}
// This method calculates the Width of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureWidth(int widthMeasureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(widthMeasureSpec);
int specSize = MeasureSpec.getSize(widthMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Return the width of the rectangle
result = rightX - leftX;
}
return result;
}
// This method calculates the Height of your view based on the dimensions of
// your rectangle and the current widthMeasureSpec.
private int measureHeight(int heightMeasureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(heightMeasureSpec);
int specSize = MeasureSpec.getSize(heightMeasureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Return the height of the rectangle
result = bottomY - topY;
}
return result;
}