Why do I get a null pointer exception from TabWidget?

主宰稳场 提交于 2019-11-28 04:35:34

问题


I'm writing an android program in which I have an activity that uses tabs.

The Activity

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);
}

}

The XML referenced by 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>

As far as I can see I'm doing the same thing I see in the tabs1 api sample from the android sdk. I've tried "getLayoutInflator()" instead of "LayoutInflator.from(this)" with the same result.

If I replace the LayoutInflater line with "setContentView(R.layout.unit_view)" my program doesn't crash with a null pointer exception but my content is completely blank and empty. I get the tab and that's it.

I've checked to make sure R.layout.unit_view and tabHost are not null when it runs the LayoutInflater line and they seem to be fine. They're defenitely not null. I've also checked to make sure LayoutInflater.from(this) returns a valid layout inflater object and it does.

The logcat indicating the error says

 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'

Anybody have any idea how I can get this content into a tab without crashing my application? My actual program is more complex and has more than one tab but I simplified it down to this in an attempt to find out why it's crashing but it still crashes and I don't know why.

If I don't use LayoutInflator my program doesn't crash but I don't get any content either, just tabs.


回答1:


This does work for me:

tabHost = getTabHost();

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

Partial 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 -->



回答2:


For those of you who are using a TabHost not inside a TabActivity, then be sure to call TabHost.setup(). Here's the documentation for it: http://developer.android.com/reference/android/widget/TabHost.html#setup() Not doing so will result in a NullPointerException when you try to add tabs to your tabhost.

The tutorial fails to mention that, so I thought I'd bring it to your attention to save you guys the time I spent looking for it.




回答3:


Just wanted to provide some idea based on the statements from here:

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

The TabWidget is causing a crash if you try to draw it before loading the data. To prevent this just use your async tasks/handlers not only to load the data but to set the content view too. Of course you could use some other view or progress dialog during the data loading process, just don't present the tabs holder yet.




回答4:


YEAR! You need to call:

TabHost.setup()

before call the method. if not,the TabHost's TabWidget should be null. I made this mistake for so long.



来源:https://stackoverflow.com/questions/2942108/why-do-i-get-a-null-pointer-exception-from-tabwidget

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!