5

So I have a custom view set up in code (no XML layout defined for it) and am wondering how to get the child Views ID's defined correctly. I DO have an xml file defining id's similar to this.. But how I understand it, at least, since I don't have an xml layout there's no AttribSet to pass .. so my constructors are all just (Context context) types.

<resources>
    <item type="id" name="textview1"/>
    <item type="id" name="textview2"/>
</resources>

And my view looks something along these lines:

public class MyView extends View {

    protected RelativeLayout baseLayout;
    protected TextView textView1;
    protected TextView textView2;

    public MyView(Context context) {
        super(context);
        LayoutParams fill = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        setLayoutParams(fill);

        Resources res = getResources();

        baseLayout = new RelativeLayout(context);
        baseLayout.setLayoutParams(fill);

        textView1 = new TextView(context);
        textView1.setId(R.id.textview1);
        // other init stuff here

        textView2 = new TextView(context);
        textView2.setId(R.id.textview2);
        // other init stuff here

        baseLayout.addView(textView1);
        baseLayout.addView(textView2);
    }

    @Override
    public void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        // *snip lots of stuff*

        baseLayout.draw(canvas);
    }

    // This is only here because findViewById() returns NULL when I search
    public TextView getTextView1() {
        return textView1;
    }

    // This is only here because findViewById() returns NULL when I search
    public TextView getTextView2() {
        return textView2;
    }

}

Here's the Activity that uses the view..

public class MyActivity extends Activity {

    // This is only here because findViewById() returns NULL when I search
    private MyView myView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Resources res = getResources();

        myView = new myView(this);
        setContentView(myView);

        // This returns NULL.  :/       
        // final TextView textView1 = (TextView) findViewById(R.id.textView1);

        // This is only here because findViewById() returns NULL when I search..
        final TextView textView1 = myView.getTextView1();
        final Animation anim = AnimationUtils.loadAnimation(this, R.anim.my_animation);
        textView1.setAnimation(anim);
        anim.setAnimationListener(new AnimationListener() {
            @Override
            public void onAnimationEnd(Animation _anim) {
                Log.v("InsideAnimation", "Animation ended");
                textView1.setVisibility(View.INVISIBLE);
            }
            @Override
            public void onAnimationRepeat(Animation _anim) {
                Log.v("InsideAnimation", "Animation repeated");
            }
            @Override
            public void onAnimationStart(Animation _anim) {
                Log.v("InsideAnimation", "Animation started");
            }
        });
        anim.reset();
        textView1.startAnimation(anim);
    }
}

The main problem is that the animation I load (which is defined in xml) and start does absolutely nothing. I get a Log statement of "animation started" but that's it. It never ends and it never does anything when I emulate it. It's like it starts, but doesn't actually RUN. I think the issue is that maybe the animation is expecting to use xml id layout definitions to do it's work on, but since findViewById() returns NULL, I'm assuming that part is broken (and thus the animation doesn't work). So .. at least for right now, I want to find out what I'm doing wrong with setting the ID so that I can get findViewById() to return the correct view and not NULL... And then possibly the animation will work. (or if it still doesn't work after that point, I'll have to look at maybe defining the animation in code also instead of xml)

Any help or suggestions are appreciated.

Joishi Bodio
  • 438
  • 6
  • 17

2 Answers2

1

There's a setID-method for java coding a view.

keyser
  • 18,829
  • 16
  • 59
  • 101
  • You are indeed. But it seems weird that you're using setId(R.id...). I might have misunderstood the issue now, but aren't you initiating an id by referring to its already existing id (which....doesn't exist). If that's correct, then you just need to switch the argument from R.id.. to an actual nr. Sry if I'm saying stuff you think is obvious and stupid :p – keyser Jun 04 '11 at 23:02
  • The id only exists in xml. When I create the object, it has no id associated with it (since I haven't defined the object in xml with an @id+ tag). So I define an id in xml (my first code block) .. and then I link that ID to the view so I can get the view back later. It's np, Martin - I just didn't know if you were referring so something else. – Joishi Bodio Jun 04 '11 at 23:47
  • Yes, it does. If you load up and look at the R file (it's under the gen folder under your application's package name), you'll see the additional id's under the "id" section of it. – Joishi Bodio Jun 05 '11 at 16:45
0

My guess is, that your TextView is not instantiated at this point. try to trigger your animation outside of the oncreate-method.

Additionally, your MyView is extended from View and you´re creating a RelativeLayout inside. If you do this, you could also directly extend your class from RelativeLayout and then do something like

mRelativeLayout = new MyRelativeLayout(context)
mRelativeLayout.findViewById(R.id.textview1)

could also be the problem, because you haven´t got the reference to your RelativeLayout in your Activity. Although it´s more likely that my first guess is the solution...

Oh, and you could simply design your RelativeLayout in xml. I see no real point in using a programmatically Layout here...

stk
  • 6,311
  • 11
  • 42
  • 58
  • I can guarantee that the TextView IS instantiated.. I ran Log.v statements (before I ever posted this) to test that out. The output of instantiation was present before the output of trying to find it via it's ID. As for extending View - I already have already tried extending RelativeLayout instead of View .. but when I do that the other stuff that I have inside the onDraw method no longer draws (which I'm sure I could potentially fix, but I'm not sure why it wouldn't draw ... but none-the-less, it doesn't). (cont) – Joishi Bodio Jun 04 '11 at 20:29
  • However, I could try running myView.findViewById() instead of simply just findViewById() .. that might work. I'll let you know after I eat. In terms of just designing in inside an xml layout .. I know I can do that (and in fact already have). But the problem is that I want it to calculate values based off the dimensions of the display ... using XML won't do that, so I'm working within code instead of xml. I want my program to look the same on multiple displays without having to have an xml layout for each type of display I might encounter... I will try what you mentioned, though. – Joishi Bodio Jun 04 '11 at 20:31
  • So I added a method to my class that gave me the RelativeLayout, and then I ran `myRelativeLayout.findViewById(R.id.textview1)` and it actually DID return the correct object, so what you suggested worked. :) Unfortunately, the animation still appears to be doing nothing.. Sooooo.. I might have to program out the animation in code also. I don't know. I'm not a new programmer - just new to Android, and it does some things that seem strange to me. – Joishi Bodio Jun 04 '11 at 20:50
  • edit: ah, you fixed it yourself. don´t worry, I came from iOS-developing and there are maaaaaany things in Android that seem a bit odd to me. :) so good luck with your animation! – stk Jun 04 '11 at 20:57