我的自定义视图仅在 onCreate 中添加时才会绘制
我制作了一个“GraphBar”自定义视图,它是一个 RelativeLayout
,底部有一个 TextView
,上面有一个高度不同的 ImageView
。代码如下:
public class GraphBar extends RelativeLayout {
private int mAvailHeight; // space for the bar (component minus label)
private float mBarHeight; // 0.0-1.0 value
public GraphBar(Context context) {
this(context, null);
}
public GraphBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GraphBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater.from(context).inflate(R.layout.graphbar, this, true);
setId(R.id.graphBar); // defined in <merge> but not assigned (?)
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mAvailHeight = getHeight()-findViewById(R.id.label).getHeight();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
View bar2 = findViewById(R.id.smallBar);
RelativeLayout.LayoutParams llp2 = (RelativeLayout.LayoutParams) bar2.getLayoutParams();
llp2.height = Math.round((float)mAvailHeight * mBarHeight);
}
public void setBarHeight(float value, float max) {
mBarHeight = value / max;
findViewById(R.id.smallBar).requestLayout();
}
public void setLabel(CharSequence c) {
((TextView) findViewById(R.id.label)).setText(c);
}
}
虽然添加这些 GraphBar 并在 onCreate()
中设置它们的高度效果很好,但如果我在 onClickSomething 上创建它们或在创建的条上再次调用 setBarHeight()
,查看更改的唯一方法是加载视图层次结构。 此处告诉我,这意味着我需要调用某个地方requestLayout()
。除了修改 mBarHeight
之后,还能在哪里呢?有什么帮助吗?我到处都尝试过,也尝试了 invalidate()
。
谢谢你, Andrea
(如果您需要,我可以发布我进行测试的活动和 graphbar.xml)
我发现它可能是 一个错误。解决方法应该是再次调用 requestLayout()
。我还是不明白在哪里可以打电话。
I made a "GraphBar" custom view that is a RelativeLayout
with a TextView
on the bottom and an ImageView
, varying in height, above that. Here is the code:
public class GraphBar extends RelativeLayout {
private int mAvailHeight; // space for the bar (component minus label)
private float mBarHeight; // 0.0-1.0 value
public GraphBar(Context context) {
this(context, null);
}
public GraphBar(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public GraphBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater.from(context).inflate(R.layout.graphbar, this, true);
setId(R.id.graphBar); // defined in <merge> but not assigned (?)
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mAvailHeight = getHeight()-findViewById(R.id.label).getHeight();
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
View bar2 = findViewById(R.id.smallBar);
RelativeLayout.LayoutParams llp2 = (RelativeLayout.LayoutParams) bar2.getLayoutParams();
llp2.height = Math.round((float)mAvailHeight * mBarHeight);
}
public void setBarHeight(float value, float max) {
mBarHeight = value / max;
findViewById(R.id.smallBar).requestLayout();
}
public void setLabel(CharSequence c) {
((TextView) findViewById(R.id.label)).setText(c);
}
}
While adding these GraphBars and setting their height in onCreate()
works well, if I create them onClickSomething or call again setBarHeight()
on the created bars, the only way to see changes is Load View Hierarchy. I've been told here that it means I need to call somewhere requestLayout()
. Where else than after modifying mBarHeight
? Any help? I tried everywhere, and with invalidate()
too.
Thank you,
Andrea
(if you need I can post the activity with which i do my tests and the graphbar.xml)
I've found it's probably a bug. The workaround should be, again, calling requestLayout()
. Still i don't understand where i can put the call.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我终于找到了再次调用
requestLayout()
的方法。我在构造函数中调用了setWillNotDraw(false)
,以便在onDraw()
(即onLayout()
之后)中我可以调用额外的 <代码> requestLayout() 。这会产生一个愚蠢的循环,但从美学上解决了问题。如果有人知道更好的解决方案,请告诉我...这里是新代码(修改位于注释旁边):
I've finally found a way to call again
requestLayout()
. I calledsetWillNotDraw(false)
in the constructor so that inonDraw()
(that is afteronLayout()
) I can call the extrarequestLayout()
. This generates a stupid cycle but solves the problem aesthetically.If anyone knows a better solution, let me know... here the new code (modifies are next to comments):