Почему я получаю сообщение об ошибке при попытке установить содержимое tabspec в Android?

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

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

    TabHost tabHost = getTabHost();
    TabSpec spec;

    spec = tabHost.newTabSpec("controls");
    spec.setIndicator("Control");
    spec.setContent(R.layout.unit_control);
    tabHost.addTab(spec);

    spec = tabHost.newTabSpec("data");
    spec.setIndicator("Data");
    spec.setContent(R.layout.unit_data);
    tabHost.addTab(spec);
  }
}

Однако, когда я запускаю программу, она вылетает с ошибкой: «Не удалось создать содержимое вкладки, потому что не удалось найти представление с идентификатором 2130903042». Я не понимаю, в чем проблема, потому что R.layout.unit_data ссылается на файл макета в моем каталоге ресурсов (res/layout/unit_data.xml)

<?xml version="1.0" encoding="utf-8"?>
  <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent">
    <TableLayout
        android:stretchColumns="*"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent">
    <Spinner android:id="@+id/unit_num"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:prompt="@string/choose_unit"/>
    <TableRow android:padding="2dp">
      <TextView
          android:gravity="right"
          android:padding="5dp"
          android:text="@string/Power"/>
      <TextView android:id="@+id/unit_power"
          android:layout_span="3"
          android:gravity="center"
          android:padding="5dp"
          android:background="@android:color/white"
          android:textColor="@android:color/black"
          android:text="AUTO"/>
    </TableRow>
    ...
  </TableLayout>
</ScrollView>

насколько я могу судить, unit_data.xml правильно сформирован, и я даже успешно сослался на него в другом действии.

class UnitData extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.unit_data);
    Toast.makeText(this, "Hi from UnitData.onCreate", 5);
  }
}

который не дает ошибки и отлично отображает макет.

В чем дело? Почему я не могу ссылаться на этот макет при создании вкладки?


person rushinge    schedule 31.05.2010    source источник


Ответы (3)


Хотя Activity.setContentView принимает идентификатор Макет, TabSpec.setContent принимает идентификатор представления. Это означает, что вам нужно передать идентификатор, который выглядит как R.id.something, а не R.layout.something.

Чтобы решить вашу конкретную проблему, дайте представлению верхнего уровня в макете идентификатор представления:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent"
      android:id="@+id/unit_data">  <!-- NOTE THE CHANGE -->
  ...
</ScrollView>

и обновите свой источник:

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

    TabHost tabHost = getTabHost();
    TabSpec spec;

    spec = tabHost.newTabSpec("controls");
    spec.setIndicator("Control");
    spec.setContent(R.id.unit_control);  // NOTE THE CHANGE
    tabHost.addTab(spec);

    spec = tabHost.newTabSpec("data");
    spec.setIndicator("Data");
    spec.setContent(R.id.unit_data);   // NOTE THE CHANGE
    tabHost.addTab(spec);
  }
}

Дополнительные сведения см. в примерах вкладок в ApiDemos:

person Tim Kryger    schedule 31.05.2010
comment
Большое спасибо за совет. Вы правы, часть моей проблемы в том, что я использовал ссылку R.layout (которая выглядела очень похожей на ссылку id, которая сбила меня с толку). Я также думаю, что идентификатор, указанный таким образом, должен находиться в представлении, на которое ссылается @android:id/tabcontent. Я читал упоминание об этом в другом месте, и мое собственное тестирование, похоже, подтверждает это. - person rushinge; 31.05.2010

Если у вас есть макет вкладок в другом файле, вам нужно раздуть XML.

spec = tabHost.newTabSpec("data");
spec.setIndicator("Data");
// Add the layout to your tab view
getLayoutInflater().inflate(R.layout.unit_data, tabHost.getTabContentView(), true);
spec.setContent(R.id.unit_data);   
tabHost.addTab(spec);
person sww314    schedule 05.02.2012

Вы также должны использовать LayoutInflater после TabHost

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

Я тоже застрял с этим и, наконец, понял это.

person Allen    schedule 02.01.2011