findViewById() возвращает null для представлений в диалоге
Проблема в том, что независимо от того, где и как я вызываю компоненты этого макета, они всегда возвращают ноль.
setView(inflater.inflate(R.layout.search_layout, null))
Это отлично работает. Он отображает макет в Dialog
, но findViewById(R.id.some_search_layout_children)
всегда возвращает дочерние элементы как нулевые.
Я пытался очистить свой проект несколько раз, пытался реализовать другой класс для моего Dialog
, называемый findViewById()
как член моей основной Activity
, внутри initSearch()
и внутри анонимной реализации OnClickListener
для Dialog
, но все с одинаковым результатом. Я также попытался разделить детей на независимые View
и программно вызвать их:
TextView text = (TextView) findResourceById(R.id.new_independant_textview);
Но, опять же, тот же результат.
Это соответствующий код:
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();
}
Эта строка:
EditText text = (EditText) findViewById(R.id.tagField);
всегда возвращает ноль, независимо от того, как и где он вызывался - глобально, локальный final
и т.д. - он просто возвращает ноль.
Вот XML моего пользовательского макета Dialog
:
<?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>
Это мой файл R.java
:
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
}
Ответы
Ответ 1
Вызов findViewById()
будет искать представления в макете "Активность" и не в диалоговом окне. Вам нужно вызвать findViewById()
для конкретного View
, который вы установили в качестве макета диалога.
Попробуйте это
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();
}
Обратите внимание, как я раздуваю представление и сохраняю его в View
с именем dialogView
. Затем, чтобы найти ваш EditText
с именем tagField
, я использую dialogView.findViewById(R.id.tagField);
Ответ 2
TextView
с идентификатором text123
должен быть объявлен внутри Layout
, установленного с помощью setContentView
Ответ 3
Ваша проблема в том, что вы пытаетесь сделать .show()
в AlertDialog Builder, а не в AlertDialog.
Попробуйте использовать следующий код:
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();
}
Ответ 4
У меня была такая же проблема при программировании многоязычного приложения.
В конце концов я узнал, что забыл обновлять метки в некоторых файлах [xml] для работы с макетом.
У меня было 3 из них за активность:
<activity_name>.xml
<activity_name>.xml(land)
<activity_name>.xml(iw)
Я обновил только первый и забыл обновить другое следующим образом:
У всех трех был один TextView с идентификатором:
<TextView
android:id="@+id/loading_textbox"
.../>
Затем я изменил имя идентификатора этого текстового представления - только в первом файле - на:
<TextView
android:id="@+id/status_textbox"
.../>
И, конечно же, в Java-коде Activity (который использует все три...):
TextView tv = findViewByID(R.id.status_textbox);
Это работало для обычной (английской <activity_name>.xml
) версии.
Но когда я пошел на IW-язык (иврит <activity_name>xml(iw)
) tv
получил нулевое значение, и даже получил некоторые раздатки.
Когда я изменил идентификатор текстового вида других файлов на "@+id/status_textbox"
, все работало как шарм...
Итак, просто убедитесь, что все ваши идентификаторы обновлены и учтены во всех ваших макетах и языках.
Это все равно решило мою проблему.