views:

1349

answers:

2

In the Android docs on AlertDialog, it gives the following instruction and example for setting a custom view in an AlertDialog:

If you want to display a more complex view, look up the FrameLayout called "body" and add your view to it:

FrameLayout fl = (FrameLayout) findViewById(R.id.body);
fl.add(myView, new LayoutParams(FILL_PARENT, WRAP_CONTENT));

First off, it's pretty obvious that add() is a typo and is meant to be addView().

I'm confused by the first line using R.id.body. It seems that it's the body element of the AlertDialog ... but I can't just enter that in my code b/c it gives a compile error. Where does R.id.body get defined or assigned or whatever?

Here's my code. I tried to use setView(findViewById(R.layout.whatever) on the builder but it didn't work. I'm assuming because I didn't manually inflate it?

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Title")
    .setCancelable(false)
    .setPositiveButton("Go", new DialogInterface.OnClickListener() {

    @Override
    public void onClick(DialogInterface dialog, int id) {
        EditText textBox = (EditText) findViewById(R.id.textbox);
        doStuff();
    }
});

FrameLayout f1 = (FrameLayout)findViewById(R.id.body /*CURRENTLY an ERROR*/);
f1.addView(findViewById(R.layout.dialog_view));

AlertDialog alert = builder.create();
alert.show();
A: 

All constants in the R class are generated from your xml files. Youshould probably just define an xml-layout with id=body to get the example through.

aioobe
I understand this. However, the main layout of an AlertDialog is not defined by me in XML -- it's handled in the system outside of my application. The way the AlertDialog's doc is worded, it seems to be referencing "body" as the id of something in the AlertDialog created by the system.
stormin986
+3  A: 

You are correct, it's because you didn't manually inflate it. It appears that you're trying to "extract" the "body" id from your Activity's layout, and that won't work.

You probably want something like this:

LayoutInflater inflater = getLayoutInflater();
FrameLayout f1 = (FrameLayout)alert.findViewById(android.R.id.body);
f1.addView(inflater.inflate(R.layout.dialog_view, f1, false));
synic
Interestingly enough, body is not defined as a constant in android.R.id. I'm still not clear on how to access the 'body' element of the created AlertDialog. I'd still like to know how to do this, but for now I will just try to inflate a view and use setView in the builder.
stormin986
Actually this still leave me with a question then (I'm new to inflating views). Using `builder.setView(inflater.inflate(R.id.dialog, ROOT_VIEWGROUP[, ATTACH_TO_ROOT]))`, the docs say the root viewgroup is optional. Should this be used in this case? If so ... still have to figure out how to get a reference to the AlertDialog...
stormin986
It is optional, but then you won't have a reference to the parent from inside the layout you're inflating. Things like android:layout_gravity won't work on the toplevel view... and maybe you don't need them to.When you call AlertDialog alert = builder.create(), you have a reference to your AlertDialog.Long answer short, it *is* optional. Give it a try, depending on what you're doing in your custom layout, it'll probably work.
synic
I'm not clear on how to reference the *view* within the AlertDialog. What would you recommend doing in this case if I did want to reference the parent? The only thing I see within alertDialog that returns a view is getCurrentFocus()
stormin986
Interesting. I got it to display just fine the view using `null` for the root view. My custom layout has an EditText element in it. The following returns `null`, however! `EditText textBox = (EditText) findViewById(R.id.chat_username);` Is there a reason the Activity findViewById didn't work here? I wasn't aware of any nuances in this method, I assumed it was universal. I'm not sure how to call alert.findViewById when I'm still setting up the builder.
stormin986
Hold onto the `View` you inflate. Call `findViewById()` on that `View` when you need stuff from its contents. See: http://github.com/commonsguy/cw-android/tree/master/Database/Constants/
CommonsWare
Great. Thanks! Worked like a charm. One odd thing happening: I inflate the view at the top level of my above code, and when I try to reference it in the anonymous inner class used for onClick, I get this error: "Cannot refer to a non-final variable v inside an inner class defined in a different method". Making my inflated view object final fixes it, but why is this necessary?
stormin986