only call onLayout when needed