Почему я получаю исключение нулевого указателя из TabWidget? - PullRequest
4 голосов
/ 31 мая 2010

Я пишу программу для Android, в которой у меня есть активность, использующая вкладки.

Активность

public class UnitActivity extends TabActivity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  TabHost tabHost = getTabHost();
  TabSpec spec;
  Resources res = getResources();

  LayoutInflater.from(this).inflate(R.layout.unit_view, tabHost.getTabContentView(), true);

  spec = tabHost.newTabSpec("controls");
  spec.setIndicator("Control", res.getDrawable(R.drawable.ic_tab_equalizer));
  spec.setContent(R.id.txtview);
  tabHost.addTab(spec);
}

}

XML, на который ссылается R.layout.unit_view

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
<LinearLayout
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="5dp">
  <TabWidget android:id="@android:id/tabs"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"/>
    <FrameLayout android:id="@android:id/tabcontent"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:padding="5dp">
      <TextView android:id="@+id/txtview"
          android:layout_width="fill_parent"
          android:layout_height="fill_parent"
          android:gravity="bottom"
          android:text="nullpointer this!" />
    </FrameLayout>
  </LinearLayout>
</TabHost>

Насколько я вижу, я делаю то же самое, что вижу в примере API tabs1 из Android SDK. Я попытался "getLayoutInflator ()" вместо "LayoutInflator.from (this)" с тем же результатом.

Если я заменю строку LayoutInflater на «setContentView (R.layout.unit_view)», моя программа не завершится с ошибкой нулевого указателя, но мой контент будет полностью пустым и пустым. Я получаю вкладку и все.

Я проверил, чтобы R.layout.unit_view и tabHost не были равны NULL, когда он запускает строку LayoutInflater, и они кажутся нормальными. Они определенно не нулевые. Я также проверил, чтобы убедиться, что LayoutInflater.from (this) возвращает действительный объект наложения макета, и это происходит.

Logcat, указывающий на ошибку, говорит

 E/AndroidRuntime(  541): java.lang.NullPointerException
 E/AndroidRuntime(  541):  at android.widget.TabWidget.dispatchDraw(TabWidget.java:206)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.View.draw(View.java:6538)
 E/AndroidRuntime(  541):  at android.widget.FrameLayout.draw(FrameLayout.java:352)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1531)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.drawChild(ViewGroup.java:1529)
 E/AndroidRuntime(  541):  at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1258)
 E/AndroidRuntime(  541):  at android.view.View.draw(View.java:6538)
 E/AndroidRuntime(  541):  at android.widget.FrameLayout.draw(FrameLayout.java:352)
 E/AndroidRuntime(  541):  at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1830)
 E/AndroidRuntime(  541):  at android.view.ViewRoot.draw(ViewRoot.java:1349)
 E/AndroidRuntime(  541):  at android.view.ViewRoot.performTraversals(ViewRoot.java:1114)
 E/AndroidRuntime(  541):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1633)
 E/AndroidRuntime(  541):  at android.os.Handler.dispatchMessage(Handler.java:99)
 E/AndroidRuntime(  541):  at android.os.Looper.loop(Looper.java:123)
 E/AndroidRuntime(  541):  at android.app.ActivityThread.main(ActivityThread.java:4363)
 E/AndroidRuntime(  541):  at java.lang.reflect.Method.invokeNative(Native Method)
 E/AndroidRuntime(  541):  at java.lang.reflect.Method.invoke(Method.java:521)
 E/AndroidRuntime(  541):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
 E/AndroidRuntime(  541):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
 E/AndroidRuntime(  541):  at dalvik.system.NativeStart.main(Native Method)
 I/Process (   61): Sending signal. PID: 541 SIG: 3
 I/dalvikvm(  541): threadid=7: reacting to signal 3
 I/dalvikvm(  541): Wrote stack trace to '/data/anr/traces.txt'

Кто-нибудь знает, как я могу поместить этот контент на вкладку, не разбивая мое приложение? Моя настоящая программа более сложна и имеет более одной вкладки, но я упростил ее до этого, пытаясь выяснить, почему происходит сбой, но все равно происходит сбой, и я не знаю, почему.

Если я не использую LayoutInflator, моя программа не падает, но я также не получаю никакого контента, только вкладки.

Ответы [ 4 ]

20 голосов
/ 05 июня 2011

Для тех из вас, кто использует TabHost вне TabActivity, обязательно вызовите TabHost.setup (). Вот документация для этого: http://developer.android.com/reference/android/widget/TabHost.html#setup() Невыполнение этого условия приведет к исключению NullPointerException при попытке добавить вкладки к вашему tabhost.

В руководстве не упоминается об этом, поэтому я решил обратить ваше внимание, чтобы вы, ребята, сэкономили время, которое я потратил на его поиск.

1 голос
/ 31 мая 2010

Это работает для меня:

tabHost = getTabHost();

        tabHost.addTab(tabHost.newTabSpec("upcoming").setIndicator(
                getResources().getString(R.string.upcoming)).setContent(R.id.cell1));

Частичный XML

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout android:orientation="vertical"
        android:layout_width="fill_parent" android:layout_height="fill_parent">
        <TabWidget android:id="@android:id/tabs"
            android:layout_width="fill_parent" android:layout_height="wrap_content" />
        <FrameLayout android:id="@android:id/tabcontent"
            android:layout_width="fill_parent" android:layout_height="fill_parent">
            <include android:id="@+id/cell1"
                layout="@layout/my_layout_file" />
             <!-- another include for cell2, and the closing tags -->
0 голосов
/ 04 сентября 2012

ГОД! Вам нужно позвонить:

TabHost.setup ()

перед вызовом метода. если нет, TabWidget TabHost должен быть нулевым. Я так долго ошибался.

0 голосов
/ 26 сентября 2011

Просто хотел представить идею, основанную на утверждениях отсюда:

http://code.google.com/p/android/issues/detail?id=14929

TabWidget вызывает сбой, если вы пытаетесь нарисовать его перед загрузкой данных. Чтобы предотвратить это, просто используйте асинхронные задачи / обработчики не только для загрузки данных, но и для настройки представления содержимого. Конечно, вы можете использовать какой-то другой вид или диалоговое окно прогресса во время процесса загрузки данных, просто пока не отображайте держатель вкладок.

...