我正在开发Android游戏,我有一个问题,我一直试图解决一段时间。
我有自定义视图,我已覆盖其onDraw
和onMeasure
。此自定义视图位于LinearLayout或RelativeLayout内,如下所示
<LinearLayout
android:layout_width="0dip"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_weight="2">
<com.leftcorner.craftersofwar.images.BitmapView
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
现在的问题是,在onMeasure
函数中,父级的大小为0.我唯一能做的就是根据所需的内容大小扩展我的视图。但是,如果位图大于视图的最终大小,则当我输入onDraw
函数时,这将导致布局放错位置。画布的(0,0)坐标位于视图边缘的某处。
我可以在使用((View) this.getParent()).getWidth();
进行绘制之前获取父级大小,将位图大小与其进行比较并以正确的比例绘制位图,但是将其绘制到画布会失败,因为位图超出了视图范围在我不知道的地方。
那么,我怎么能把我的这个位图绘制到画布上,以便它实际上可见?如果它也在视图中居中会更好。
以下是我目前的代码:
@Override
protected void onDraw(Canvas canvas) {
pWidth = ((View) this.getParent()).getWidth();
pHeight = ((View) this.getParent()).getHeight();
fWidth = Utility.smaller(pWidth, bWidth);
fHeight = Utility.smaller(pHeight, bHeight);
if(bitmap != null){
// As you can see, I'm not using a custom bitmap class.
// This function draws the bitmap to the canvas.
// (x, y, width, height, canvas)
bitmap.getStorageBitmap().drawScaledBitmap(0, 0, fWidth, fHeight, canvas);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
bWidth = Math.round(bitmap.getWidth() * scale);
bHeight = Math.round(bitmap.getHeight() * scale);
if(bitmap != null) setMeasuredDimension(bWidth, bHeight);
else setMeasuredDimension(0, 0);
}
答案 0 :(得分:2)
要获取父级的维度,您可以执行以下操作:
// set the id of your LinearLayout to parentLayout
LinearLayout parent = (LinearLayout)findViewById(R.id.parentLayout);
final ViewTreeObserver observer = parent.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@SuppressLint("NewApi")
@SuppressWarnings("deprecation")
@Override
public void onGlobalLayout() {
parent.measure(MeasureSpec.UNSPECIFIED,
MeasureSpec.UNSPECIFIED);
int parentHeight = parent.getMeasuredHeight();
int parentWidth = parent.getMeasuredWidth();
// set dimensions to bitmap
bitmap.getLayoutParams().height = parentHeight * scale;
bitmap.getLayoutParams().width= parentWidth * scale;
bitmap.requestLayout();
ViewTreeObserver obs = parent.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
您可以将此代码直接放在onCreate
中答案 1 :(得分:0)
cYrixmorten给出的答案是正确的,但我以一种不同的方式解决了这个问题。请注意我的LinearLayout的高度设置为wrap_content,但它的宽度来自权重。
这是我的代码:
@Override
protected void onDraw(Canvas canvas) {
if(getWidth() < 1 || getHeight() < 1){
requestLayout();
} else if(bitmap != null){
bitmap.getStorageBitmap().drawScaledBitmap(0, 0, getWidth(), getHeight(), canvas);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if(bitmap != null) {
bitmapWidth = Math.round(bitmap.getWidth() * scale);
bitmapHeight = Math.round(bitmap.getHeight() * scale);
} else {
setMeasuredDimension(0, 0);
return;
}
parentWidth = MeasureSpec.getSize(widthMeasureSpec);
if(parentWidth < bitmapWidth){
bitmapHeight = bitmapHeight * parentWidth / bitmapWidth;
bitmapWidth = parentWidth;
}
setMeasuredDimension(bitmapWidth, bitmapHeight);
}