0

我做了一个“GraphBar”自定义视图,该视图的底部为TextView,而ImageView为高度不等,高度为的RelativeLayout。下面是代码:我的自定义视图只在添加到onCreate时绘制

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

我终于找到了一种方式再次打电话给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 
    } 
//...