14

The problem is, no matter where or how I call for this layout's components, they always return null.

setView(inflater.inflate(R.layout.search_layout, null))

This works fine. It displays the layout inside the Dialog, yet, the children are always returned as null by findViewById(R.id.some_search_layout_children).

I've tried cleaning my project multiple times, tried to implement another class for my Dialog, called findViewById() as a member of my main Activity, inside the initSearch() method, and inside an anonymous implementation of OnClickListener for the Dialog, but all with the same result. I've also tried breaking the children out into independent Views and programmatically calling them:

TextView text = (TextView) findResourceById(R.id.new_independant_textview);

But, again, the same result.

This is the relevant code:

public class Xyz extends Activity {
    public void onCreate(...) { // some listener will trigger initSearch() }

    private void initSearch() {
        AlertDialog.Builder searchDialog = new AlertDialog.Builder(this);
        LayoutInflater inflater = this.getLayoutInflater();
        searchDialog.setTitle("Search Photos");
        searchDialog.setMessage("Specify tag and value...");
        // R.layout.search_dialog is my custom layour, it displays fine, it works. 
        searchDialog.setView(inflater.inflate(R.layout.search_dialog, null));
        EditText tagText = (EdiText) findViewById(R.id.tagField); // WILL RETURN NULL
        searchDialog.setPositiveButton( ... ) ...
        searchDialog.show();
    }

This line:

 EditText text = (EditText) findViewById(R.id.tagField);

always returns null, no matter how or where it's called – globally, local final, etc. – it just returns null.

Here is the XML of my custom Dialog layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/search_dialog"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/tagText" 
        android:padding="7dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:text="@string/tag" />
    <EditText 
        android:id="@+id/tagField"
        android:padding="7dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text"/>
    <TextView
        android:id="@+id/valueText" 
        android:padding="7dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="14sp"
        android:text="@string/value" />
    <EditText 
        android:id="@+id/valueField"
        android:padding="7dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text"/>
</LinearLayout>

This is my R.java file:

public static final class id {
    public static final int action_settings=0x7f0a0011;
    public static final int add_album=0x7f0a0001;
    public static final int add_photo=0x7f0a000d;
    public static final int albums_list=0x7f0a0003;
    public static final int delete_album=0x7f0a000b;
    public static final int exit_finder=0x7f0a000f;
    public static final int new_directory=0x7f0a000e;
    public static final int open_album=0x7f0a000a;
    public static final int photos_grid=0x7f0a0000;
    public static final int rename_album=0x7f0a000c;
    public static final int search_dialog=0x7f0a0004;
    public static final int search_icon=0x7f0a0002;
    public static final int splash_rutgers=0x7f0a0009;
    public static final int tagField=0x7f0a0006; // problematic
    public static final int tagText=0x7f0a0005; / problematic
    public static final int terminate_app=0x7f0a0010;
    public static final int valueField=0x7f0a0008; // problematic
    public static final int valueText=0x7f0a0007; // problematic
}
Mike M.
  • 38,532
  • 8
  • 99
  • 95
Fer
  • 460
  • 2
  • 4
  • 17
  • you wana find view in dialog calling findViewById from another activity ... good luck ... – Selvin Apr 24 '13 at 12:49
  • Sounds interesting,but I am not fuly understanding why I need a new activity. Then why R.layot.search_dialog returns the right layour yet it's children are null? No consistency there. – Fer Apr 24 '13 at 13:17

4 Answers4

47

Calling findViewById() will search for views within your Activity's layout and not your dialog's view. You need to call findViewById() on the specific View that you set as your dialog's layout.

Try this

private void initSearch() {
    AlertDialog.Builder searchDialog = new AlertDialog.Builder(this);
    LayoutInflater inflater = this.getLayoutInflater();
    searchDialog.setTitle("Search Photos");
    searchDialog.setMessage("Specify tag and value...");
    // R.layout.search_dialog is my custom layour, it displays fine, it works. 
    View dialogView = inflater.inflate(R.layout.search_dialog, null);
    searchDialog.setView(dialogView);
    EditText tagText = (EdiText) dialogView.findViewById(R.id.tagField); 
    searchDialog.setPositiveButton( ... ) ...
    AlertDialog myAlert = searchDialog.create(); //returns an AlertDialog from a Builder.
    myAlert.show();
}

Notice how I'm inflating the view and storing it in a View named dialogView. Then, to find your EditText named tagField, I'm using dialogView.findViewById(R.id.tagField);

dymmeh
  • 22,247
  • 5
  • 53
  • 60
2

The TextView with id text123 has to be declared inside the Layout you set with setContentView

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • Actually, I think `text123` was meant to be an example because OP has `EditText tagText = (EdiText) findViewById(R.id.tagField); // WILL RETURN NULL` in their "main" code section. But this answer did make me chuckle. +1. – TronicZomB Apr 24 '13 at 12:54
  • @TronicZomB I read this EditText text = (EditText) findViewById(R.id.text123); // returns null, ALWAYS – Blackbelt Apr 24 '13 at 12:59
  • Yea I know, I at least hope that OP was using that as an example, is I guess what I was trying to say. Since in other parts of the posted code it looks like they are referencing the items properly. But if they are trying to refernce an `EditText`, the one `text123`, that is not within the layout of the dialog then you are completely correct! – TronicZomB Apr 24 '13 at 13:03
  • Typo, I edited, it was an example which I forgot to change. Thanks mates. – Fer Apr 24 '13 at 13:07
  • No problem, so tagField is the part of your dialog? – Blackbelt Apr 24 '13 at 13:10
  • It is. Just as a hint: Even if I call EditText text = findViewById(R.id.tagField) OUTSIDE any dialog thing, it does the same thing, hence I don't believe has nothing to do with the dialog context. What is curious is that the main layour does inflate in the dialog yet its components don't. Thanks for asking. – Fer Apr 24 '13 at 13:15
  • 1
    @Fer have you tried something like `EditText text = (EditText) getDialog().findViewById()`? – TronicZomB Apr 24 '13 at 13:18
  • 1
    inside initSearc(), after setTitle and setMessage you can do: AlertDialog dialog = searchDialog.create(); dialog.setContentView(R.layout.search_dialog); dialog.findViewById(R.id.tagField); it should work. It has for me – Blackbelt Apr 24 '13 at 13:20
  • 1
    Both TronicZomB and blackbelt hit on the nail. Thanks mates for your knowledge. I was missing the context in an actual dialog. – Fer Apr 24 '13 at 13:32
0

Your problem is you are trying to do .show() on a AlertDialog Builder, not the AlertDialog itself.

Try the following code:

public class Xyz extends Activity {
public void onCreate(...) { // some listener will trigger initSearch() }

private void initSearch() {
    AlertDialog.Builder searchDialog = new AlertDialog.Builder(this);
    LayoutInflater inflater = this.getLayoutInflater();
    searchDialog.setTitle("Search Photos");
    searchDialog.setMessage("Specify tag and value...");
    // R.layout.search_dialog is my custom layour, it displays fine, it works. 
    searchDialog.setView(inflater.inflate(R.layout.search_dialog, null));
    EditText tagText = (EdiText) findViewById(R.id.tagField); // WILL RETURN NULL
    searchDialog.setPositiveButton( ... ) ...
    AlertDialog myAlert = searchDialog.create(); //returns an AlertDialog from a Builder.
    myAlert.show();
}
TronicZomB
  • 8,667
  • 7
  • 35
  • 50
  • 1
    Actually, it is possible to call `show()` on a `Builder`, it just creates the `AlertDialog` and shows it. http://developer.android.com/reference/android/app/AlertDialog.Builder.html – zbr Apr 24 '13 at 13:16
  • 1
    Good approach though. The solution is to Create a shell Dialog, instantiate it with the Builder, setContentView on the Dialog, setView on the Builder, then findViewById on the dialog instance. – Fer Apr 24 '13 at 14:36
  • @Fer oh thanks! I usually use DialogFragments and just return the `builder.create()` and then show it when I need to and thus I hadn't known that `.show()` will create and show it in one line. Though it's good to know. – TronicZomB Apr 24 '13 at 14:40
0

I had the exact same problem while programming a multilingual app. Eventually I found out that I forgot to update labels in some layout's activity [xml] files.

I had 3 of them per activity:

<activity_name>.xml
<activity_name>.xml(land)
<activity_name>.xml(iw)

I updated only the first and forgot to update the other as follows:

All three had the a single TextView with the id of:

    <TextView
    android:id="@+id/loading_textbox"
    .../>

Then I've changed the name of the id of that text view - only in the first file - to:

    <TextView
    android:id="@+id/status_textbox"
    .../>

And, of-course, in the Activity's Java code (that uses all three...):

    TextView tv = findViewByID(R.id.status_textbox);

This worked for the regular (English <activity_name>.xml) version.

But when I went the the IW language (Hebrew <activity_name>xml(iw)) tv got null value and I even got some crushes.

When I changed the text view id of the other files to "@+id/status_textbox" everything worked like a charm...

So, simply make sure all your IDs are updated and accounted for in all your layouts and languages.

This solved my problem anyway..

JamesC
  • 356
  • 4
  • 8