мой пользовательский вид отображается только при добавлении в onCreate - PullRequest
0 голосов
/ 12 ноября 2010

Я сделал пользовательский вид 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() работает хорошо, если я создаю их на ClickComething или снова вызываю setBarHeight() на созданных барах, единственный способ увидетьИзменения в Load View Hierarchy.Мне сказали здесь , что это означает, что мне нужно куда-нибудь позвонить requestLayout().Где еще, кроме как после изменения mBarHeight?Любая помощь?Я пробовал везде, и с invalidate() тоже.

Спасибо, Андреа

(если вам нужно, я могу опубликовать активность, с которой я делаю свои тесты и graphbar.xml)


Я обнаружил, что, вероятно, ошибка .Обходной путь должен снова вызывать requestLayout().Тем не менее я не понимаю, где я могу сделать звонок.

1 Ответ

0 голосов
/ 12 ноября 2010

Я наконец-то нашел способ позвонить снова 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
    }
//...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...