我制作了一个“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);
}
}
虽然添加这些GraphBars并在onCreate()
中设置其高度效果很好,但如果我在onClickSomething上创建它们或在创建的栏上再次调用setBarHeight()
,则查看更改的唯一方法是加载视图层次结构。我被告知here这意味着我需要在某个地方requestLayout()
打电话。除了修改mBarHeight
之外的其他地方?有帮助吗?我到处尝试,并invalidate()
。
谢谢你, 安德烈
(如果您需要,我可以发布我进行测试的活动和graphbar.xml)
我发现它可能是a bug。解决方法应该再次调用requestLayout()
。我仍然不明白我可以拨打电话的地方。
答案 0 :(得分:0)
我终于找到了再次致电requestLayout()
的方法。我在构造函数中调用了setWillNotDraw(false)
,以便在onDraw()
(即onLayout()
之后)我可以调用额外的requestLayout()
。这会产生一个愚蠢的循环,但在美学上解决了这个问题。
如果有人知道更好的解决方案,请告诉我...... 这里有新代码(修改后会在评论旁边):
//...
public GraphBar(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
LayoutInflater.from(context).inflate(R.layout.graphbar, this, true);
setWillNotDraw(false); // WORKAROUND: onDraw will be used to make the
// redundant requestLayout() call
setId(R.id.graphBar);
}
//...
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// i think it's one of the worst workaround one could think of.
// luckily android is smart enough to stop the cycle...
findViewById(R.id.smallBar).requestLayout();
}
public void setBarHeight(float value, float max) {
mBarHeight = value / max;
View bar = findViewById(R.id.smallBar);
bar.requestLayout(); // because when we create this view onDraw is called...
bar.invalidate(); // ...but not when we modify it!!!
//so we need to invalidate too
}
//...