Android: Custom View with object reference from attrs.xml, always null
Asked Answered
H

1

2

I'm trying to setup a relationship hierarchy between objects. Every object has a parent of the same type as itself, or null.

I have a main.xml that contains some of these:

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

a res/values/attrs.xml that contains one of these:

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

and a class (that is not my activity) that contains this:

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;
}

This isn't working. Every MorseKey instance reports N == 2 (good) and parent == null (bad). More, parent == null even when I explicitly try setting it to some arbitrary value (see comment). I have also tried custom:parentKey="@+id/be" (with the plus sign) but that didn't work either. What am I doing wrong?

Haily answered 8/3, 2012 at 21:8 Comment(0)
L
1

If your MorseKey class is in a separate java file, which I assume is the case from your statment "a class (that is not my activity)". Then I believe the problem is in your use of findViewById(). findViewById() will look for a resource within the MorseKey view itself rather than the main.xml file.

Maybe try getting the parent of the MorseKey instance and calling parent.findViewById().

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

Though this will only work if your MorseKey parent and child are in the same layout.

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

But it would be quite difficult to find the view if your layout is something like this with the parent and child in separate layouts.

<LinearLayout ...>
     <MorseKey ..../><!-- parent -->
</LinearLayout>
<LinearLayout ...>
     <MorseKey ..../><!-- child -->
</LinearLayout>
Loyce answered 8/3, 2012 at 22:15 Comment(2)
Teach me to pay attention to the API. If I call this.getRootView() I get that every MorseKey is its own root View.Haily
Ah! Calling getParent() from the constructor is too soon, the views haven't yet been added to their parent views. I was able to delay the call and get it working.Haily

© 2022 - 2024 — McMap. All rights reserved.