Ситуация: У меня есть несколько пользовательских компонентов в моем макете. У меня есть общий фрейм макета, который я загружаю в onCreate()
моего базового класса Activity, а затем загружаю макеты содержимого в моих реализациях с помощью инфлатера, устанавливая корень для столбца содержимого основного макета.
Проблема: Когда я беру ссылку на представления, чтобы фактически извлечь ввод пользователя, Activity.findViewById()
возвращает null
. Возможно, это подсказка, что CheckBox и Button, которые есть в макете, НЕ возвращают null
; Я получаю действительную ссылку на виджет.
Вещи, которые я пробовал: Я знаю, что я правильно загружаю и раздуваю макет xml, потому что все отображается, и стандартные представления в том же макете можно найти по идентификатору. Я могу взаимодействовать со своими представлениями и помещать в них содержимое и все, но я не могу получить ссылку на них в своем коде.
Я пытался очистить проект несколько раз. R.id
свежо и актуально.
Я проверил консоль и журнал ошибок, и нет сообщений об ошибках интерфейса / XML.
Я попытался получить указатель на корневой макет содержимого, загруженного для этого действия, и вызвал View.findViewById()
, чтобы получить мои ссылки, и это также возвращает null
. Если я проверю макет в отладчике, я могу развернуть его и найти свои представления в mChildren
.
Возможно, другая подсказка:
public VideoChooser(Context pCtxt, AttributeSet pAttrs)
{
super(pCtxt, pAttrs);
Log.d("VideoChooser", "Expected ID: " + R.id.vchShareVids + " | actual: " + getId());
}
приведет к следующему выводу:
DEBUG/VideoChooser(10372): Expected ID: 2131296271 | actual: 268435456
Идентификатор, присвоенный представлению, не совпадает с идентификатором в R.id
! С чего бы это? Я знаю, что он загружает атрибут android:id
, иначе это будет -1 (View.NO_ID
).
Рамка общего формата:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res/com.foo"
android:id="@+id/common_frame" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<!-- top banner -->
<LinearLayout android:id="@+id/frame_header" android:orientation="horizontal"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_marginBottom="16dp">
<ImageView android:src="@drawable/banner"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_weight="1" />
</LinearLayout>
<!-- content column -->
<LinearLayout android:id="@+id/frame_content" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginLeft="32dp" android:layout_marginRight="32dp" />
</LinearLayout>
Макет содержимого:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:foo="http://schemas.android.com/apk/res/com.foo"
android:id="@+id/content_panel" android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent">
<com.foo.view.VideoChooser android:id="@+id/vchShareVids"
foo:prompt_text="@string/prompt_share_vid" foo:prompt_size="16dp"
foo:preview_height="80dp"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<com.foo.view.ContactChooser android:id="@+id/cchRecipients"
foo:prompt_text="@string/prompt_share_email" foo:prompt_size="16dp"
foo:preview_lines="3" foo:dialog_title="Pretend you are picking contacts"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<com.foo.view.TextChooser android:id="@+id/tchDescription"
foo:prompt_text="@string/prompt_share_description" foo:prompt_size="16dp"
foo:preview_lines="1" foo:dialog_title="@string/title_msg_chooser_dlg"
android:layout_width="match_parent" android:layout_height="wrap_content"
android:layout_marginBottom="12dp" android:hapticFeedbackEnabled="true" />
<CheckBox android:id="@+id/chkReshare" android:text="@string/prompt_reshare"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:checked="true" android:hapticFeedbackEnabled="true" />
<Button android:id="@+id/btnSend" android:text="@string/btn_send"
android:layout_width="@dimen/btn_width" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:hapticFeedbackEnabled="true" />
</LinearLayout>
Базовый класс активности onCreate ():
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.common_frame);
}
Реализация действия onCreate ():
@Override
protected void onCreate(Bundle pState)
{
super.onCreate(pState);
load_content_view(R.layout.content_layout);
ViewGroup tLayout = (ViewGroup)findViewById(R.id.content_panel);
// These all return null
mCchVideo = (ContentChooser)tLayout.findViewById(R.id.vchShareVids);
mCchContact = (ContentChooser)tLayout.findViewById(R.id.cchRecipients);
mCchDescription = (ContentChooser)tLayout.findViewById(R.id.tchDescription);
// These return valid references
mChkReshare = (CheckBox)findViewById(R.id.chkReshare);
mBtnSend = (Button)findViewById(R.id.btnSend);
// ...
}
protected void load_content_view(int pResId)
{
LinearLayout tColumn = (LinearLayout)findViewById(R.id.frame_content);
getLayoutInflater().inflate(pResId, tColumn);
}