Android: пользовательское представление со ссылкой на объект из attrs.xml, всегда null

Я пытаюсь установить иерархию отношений между объектами. У каждого объекта есть родитель того же типа, что и он сам, или null.

У меня есть main.xml, который содержит некоторые из них:

<com.morsetable.MorseKey
    android:id="@+id/bi"
    android:layout_weight="1"
    custom:code=".."
    custom:parentKey="@id/be"
    android:text="@string/i" />

res/values/attrs.xml, который содержит один из них:

<declare-styleable name="MorseKey">
    <attr name="code" format="string"/>
    <attr name="parentKey" format="reference"/>
</declare-styleable>

и класс (это не моя деятельность), который содержит это:

public class MorseKey extends Button {

    public MorseKey(Context context, AttributeSet attrs) {
        super(context, attrs);
        initMorseKey(attrs);
    }

    private void initMorseKey(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs,
                          R.styleable.MorseKey);
        final int N = a.getIndexCount();
        for (int i = 0; i < N; i++) {
            int attr = a.getIndex(i);
            switch (attr)
            {
            case R.styleable.MorseKey_code:
                code = a.getString(attr);
                break;
            case R.styleable.MorseKey_parentKey:
                parent = (MorseKey)findViewById(a.getResourceId(attr, -1));
                //parent = (MorseKey)findViewById(R.id.be);
                Log.d("parent, N:", ""+parent+","+N);
                break;
            }
        }
        a.recycle();
    }

    private MorseKey parent;
    private String code;
}

Это не работает. Каждый MorseKey экземпляр сообщает N == 2 (хорошо) и parent == null (плохо). Более того, parent == null даже когда я явно пытаюсь установить произвольное значение (см. комментарий). Я также пробовал custom:parentKey="@+id/be" (со знаком плюс), но это тоже не сработало. Что я делаю неправильно?


person mkjeldsen    schedule 08.03.2012    source источник


Ответы (1)


Если ваш класс MorseKey находится в отдельном java-файле, что, как я предполагаю, имеет место в вашем статусе «класс (это не моя деятельность)». Тогда я считаю, что проблема в том, что вы используете findViewById(). findViewById() будет искать ресурс в самом представлении MorseKey, а не в файле main.xml.

Возможно, попробуйте получить родителя экземпляра MorseKey и вызвать parent.findViewById().

case R.styleable.MorseKey_parentKey:
    parent = this.getParent().findViewById(a.getResourceId(attr, -1));

Хотя это будет работать только в том случае, если ваш родитель и дочерний элемент MorseKey находятся в одном и том же макете.

<LinearLayout ...>
     <MorseKey ..../><!-- parent -->
     <MorseKey ..../><!-- child -->
</LinearLayout>

Но было бы довольно сложно найти представление, если ваш макет похож на этот, когда родительский и дочерний элементы находятся в разных макетах.

<LinearLayout ...>
     <MorseKey ..../><!-- parent -->
</LinearLayout>
<LinearLayout ...>
     <MorseKey ..../><!-- child -->
</LinearLayout>
person triggs    schedule 08.03.2012
comment
Научите меня обращать внимание на API. Если я вызову this.getRootView(), я узнаю, что каждый ключ MorseKey является собственным корневым представлением. - person mkjeldsen; 09.03.2012
comment
Ах! Вызов getParent() из конструктора слишком ранний, представления еще не добавлены в их родительские представления. Я смог отложить звонок и заставить его работать. - person mkjeldsen; 10.03.2012