3

This is a followup to this post:

findViewById in a subclassed SurfaceView throwing RuntimeException

Based on Romain Guy's feedback (which I'll accept shortly as it is a solution), I'd like to obtain the calling Activity from within the View, so that I can use it to obtain the desired TextView resource.

I don't see any methods in View that return Activity. What is the proper way to do this? Or is there a better alternative for working with TextViews from within another View context.

Basically, I am calling setContentView(R.layout.xxx) in onCreate() (as usual), so I don't really have a way to pass in references to additional TextViews unless I awkwardly retrieve the View after setContentView and then make calls on it.

Community
  • 1
  • 1

2 Answers2

7

An Activity is a Context, but there is no guarantee that the Context used by a View is always an Activity. Getting the views from onCreate() to do some setup is perfectly valid and is how Android applications are usually written. You could do something like this for instance:

setContentView(...);
MySurfaceView v = findViewById(R.id.theusrface);
TextView t = findViewById(R.id.thecontent);
v.setContent(v);

The logic should not go in your Views.

sjngm
  • 12,423
  • 14
  • 84
  • 114
Romain Guy
  • 97,993
  • 18
  • 219
  • 200
  • 1
    Thanks. It "feels" awkward to do it that way, but I guess it is the Android Way(tm). I'll probably do it like: MySurfaceView v = findViewById(R.id.something); setContentView(v); v.setContent(findViewById(R.id.content)); to make it less awkward. –  Oct 10 '10 at 19:55
  • 1
    You can't do a findViewById() before calling setContentView(). – Romain Guy Oct 11 '10 at 01:55
  • Quite right. What a weird, weird arrangement, to have to identify an object, set it on another object, and ask that other object for a copy of it again, and to not allow for subordinate views within views. I think what I'm facing here is that the Android API is fundamentally different than anything I would have designed. Anyway, thank you. The code is working as expected now. –  Oct 11 '10 at 16:17
  • What do you mean by "ask that other object for a copy of it again"? You definitely don't need to do it. And Views (well ViewGroups) can contain children Views, there's no problem with that. It just happens that SurfaceView is *not* a ViewGroup. – Romain Guy Oct 11 '10 at 17:07
  • I'm wondering in what uses would the Context, not be an Activity. The example I need this for is that I have a View that really should be a fragment in that it has a menu item for the Options menu, but unfortunately it also wants to be within another fragment and nested fragments are not allowed. I'm trying to decide between using a view or figuring out how to have a view pager where each page is composed of multiple fragments. –  Oct 18 '12 at 21:13
  • _«An Activity is a Context, but there is no guarantee that the Context used by a View is always an Activity.»_ can you back that? – cYrus Jan 05 '13 at 17:41
  • 1
    @cYrus Views can be created using Service contexts and I'm pretty sure they can be created with Application contexts. Additionally, if you're using something like Square's Mortar, your context may be something else entirely (a Context that wraps another normal Android context). –  Oct 03 '15 at 13:26
4

If you already know the Activity class your View is in, i.e. MyActivity, you can use the static member MyActivity.this from inside your View and its listeners, as in the following example:

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Are you sure you want to exit?")
       .setCancelable(false)
       .setPositiveButton("Yes", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
                MyActivity.this.finish();
           }
       })
       .setNegativeButton("No", new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
                dialog.cancel();
           }
       });
AlertDialog alert = builder.create();

which I've found in this Android tutorial:

http://developer.android.com/guide/topics/ui/dialogs.html

It worked wonders for me.

PJ_Finnegan

  • 1
    The main problem of that approach is that, in Java, you're supposed to write independent classes, and there's lots of reasons why that's a good idea. If you in your view makes references to static members of external classes, it's not independent. – Sune Rasmussen Mar 28 '12 at 08:44