Я пытаюсь изменить пример кода HoneyCombGallery, чтобы изменить отображаемый вид при изменении вкладок. В примере, предоставленном Google, отображаемые фрагменты всегда одинаковы при переключении вкладок. Меняются только отображаемые данные. Однако я хочу изменить фрагменты и классы, отображаемые при изменении вкладок.
Вот код, который я изменил в примере с HoneyCombGallery: (MainActivity.java)
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
int nTabSelected = tab.getPosition();
switch (nTabSelected) {
case 0:
setContentView(R.layout.settings_fragment);
break;
case 1:
setContentView(R.layout.main);
break;
}
все остальное примерно так же. (также обратите внимание, что, как и ранее, MainActivity.onCreate вызывает setContentView(R.layout.main) - я не слышал, что вызов setContentView несколько раз не разрешен. Я все равно собираюсь делать это при каждом щелчке вкладки)
А вот макет, который надувается в коде (settings_fragment.xml)
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/frags2">
<fragment class="com.example.android.hcgallery.SettingsFragment"
android:id="@+id/settings_fragment2"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="@dimen/titles_size"
android:layout_height="match_parent" />
</LinearLayout>
«Фрагмент настроек» - это мой класс, который расширяет фрагмент: (SettingsFragment.java)
public class SettingsFragment extends Fragment {
private View v;
@Override
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, final Bundle savedInstanceState) {
if (v != null)
return v;
v = inflater.inflate(R.layout.settings_layout, container, false);
return v;
}
}
XML также очень прост (settings_layout.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/settings_layout" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingTop="10dip">
<TextView android:text="1.0.0" android:id="@+id/tv_version2"
android:layout_marginTop="?android:attr/actionBarSize"
android:textSize="15dp" android:textStyle="bold" android:typeface="sans"
android:layout_height="wrap_content" android:layout_width="200dp"
android:paddingTop="10dip" android:gravity="right" >
</TextView>
</RelativeLayout>
Это кажется простым, и когда приложение запускается, settings_fragment виден, поскольку по умолчанию выбрана 0-я вкладка. Когда мы выбираем следующую вкладку, я ожидаю, что setContentView(R.layout.main) будет выполнен, и я увижу основной макет (это то же самое, что и в примере Google: никаких изменений). Однако я получаю это исключение:
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): FATAL EXCEPTION: main
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): android.view.InflateException: Binary XML file line #23: Error inflating class fragment
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:688)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.rInflate(LayoutInflater.java:724)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.inflate(LayoutInflater.java:391)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.inflate(LayoutInflater.java:347)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:224)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.app.Activity.setContentView(Activity.java:1777)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.example.android.hcgallery.MainActivity.onTabSelected(MainActivity.java:109)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.app.ActionBarImpl.selectTab(ActionBarImpl.java:462)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.app.ActionBarImpl$TabImpl.select(ActionBarImpl.java:787)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.widget.ActionBarView$TabClickListener.onClick(ActionBarView.java:950)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.View.performClick(View.java:3100)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.View$PerformClick.run(View.java:11644)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.os.Handler.handleCallback(Handler.java:587)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.os.Handler.dispatchMessage(Handler.java:92)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.os.Looper.loop(Looper.java:126)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.app.ActivityThread.main(ActivityThread.java:3997)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at java.lang.reflect.Method.invokeNative(Native Method)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at java.lang.reflect.Method.invoke(Method.java:491)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:841)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:599)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at dalvik.system.NativeStart.main(Native Method)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): Caused by: java.lang.IllegalArgumentException: Binary XML file line #23: Duplicate id 0x7f09000a, tag null, or parent id 0x7f090009 with another fragment for com.example.android.hcgallery.TitlesFragment
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.app.Activity.onCreateView(Activity.java:4095)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:664)
12-15 16:49:28.501: ERROR/AndroidRuntime(31485): ... 21 more
Ошибка выглядит так: «android.view.InflateException: строка двоичного XML-файла № 23: ошибка при раздувании фрагмента класса»
Что это значит? Могу ли я не использовать setContentView для изменения фрагментов и макетов по своему усмотрению, когда выбраны разные вкладки? Если это неправильный способ иметь разные макеты для разных вкладок, как правильно это сделать?
У меня есть весь исходный код в архиве, загруженный в HoneycombGallery_Modified.zip - https://docs.google.com/open?id=0B0FHtQOpOYx6YWFiMDcxYmEtOGFkMy00NWU2LTk2MzMtZWY0YzdmZWUzMDU0 (Нажмите «Файл->Загрузить оригинал», если хотите загрузить весь zip-файл)