HorizontalScrollView внутри TabHost вызывает проблемы при переключении ориентации

#android #android-layout

#Android #android-layout

Вопрос:

У меня есть TabActivity с TabWidget TabHost внутри HorizontalScrollView. Я пытаюсь программно выбрать вкладку при изменении ориентации, чтобы, например, когда пользователь переключается с книжной на альбомную, активная вкладка оставалась прежней.

Что происходит, так это то, что когда первая вкладка является активной вкладкой (выбранной и сфокусированной) при смене ориентации, вторая вкладка становится активной вкладкой, когда моя активность возобновляется. Если вторая по n-ю вкладку является активной при изменении ориентации, эта вкладка правильно становится активной; проблема возникает только для первой вкладки.

Когда действие приостанавливается, я сохраняю тег активной вкладки в общих настройках системы, а когда действие начинается, я беру тег из настроек, чтобы использовать setCurrentTabByTag(string) на TabHost. Проблема возникает независимо от того, сохраняю ли я / восстанавливаю вкладку по индексу или по тегу. Проблема также возникает, использую ли я onStop / OnStart или onPause / onResume для сохранения и восстановления активной вкладки соответственно.

Это не проблема, если TabWidget не находится внутри HorizontalScrollView, но отсутствие HorizontalScrollView не является вариантом (хотя мой пример кода показывает только 4 вкладки.)

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

Мой вопрос заключается в следующем: Как я могу заставить выбранную вкладку оставаться неизменной при изменении ориентации, даже для первой вкладки? Пожалуйста, имейте в виду, что я должен создавать вкладки программно, и у меня должен быть TabWidget в HorizontalScrollView.

Вот мой макет main.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">
        <HorizontalScrollView android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:fillViewport="true"
            android:scrollbars="none">
            <TabWidget android:id="@android:id/tabs"
                android:layout_width="fill_parent" android:layout_height="wrap_content" />
        </HorizontalScrollView>
        <FrameLayout android:id="@android:id/tabcontent"
            android:layout_width="fill_parent" android:layout_height="fill_parent" />
    </LinearLayout>
</TabHost>
  

И вот моя TabActivity:

 public class RestoreSelectedTabTestActivity extends TabActivity {
    private static final String SELECTED_TAB_PREFERENCE_KEY = "selectedTabPref";
    private static final String TAG = "RestoreTabTest";

    private Context mApp;
    private SharedPreferences mPrefs;
    private TabHost mTabHost;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
    }

    @Override
    protected void onStart() {
        super.onStart();

        mApp = getApplicationContext();
        mPrefs = PreferenceManager.getDefaultSharedPreferences(mApp);

        mTabHost = (TabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup();
        mTabHost.clearAllTabs();

        addTab(1);
        addTab(2);
        addTab(3);
        addTab(4);

        // restore tab selection
        String selectedTabTag = mPrefs.getString(
                SELECTED_TAB_PREFERENCE_KEY, "");
        Log.v(TAG, "restoring tab pref "   selectedTabTag);
        mTabHost.setCurrentTabByTag(selectedTabTag);
    }

    @Override
    protected void onStop() {
        super.onStop();

        // save tab selection
        String selectedTabTag = mTabHost.getCurrentTabTag();
        SharedPreferences.Editor editor = mPrefs.edit();
        editor.putString(SELECTED_TAB_PREFERENCE_KEY, selectedTabTag);
        editor.commit();
        Log.v(TAG, "saved tab pref "   selectedTabTag);
    };

    private void addTab(final int tabId) {
        TabSpec tabSpec = mTabHost.newTabSpec("tab"   tabId);
        tabSpec.setIndicator("Tab "   tabId);
        tabSpec.setContent(new TabContentFactory() {
            public View createTabContent(String tag) {
               Log.v(TAG, "createTabContent "   tag);
                TextView textView = new TextView(mApp);
                textView.setText("This is Tab #"   tabId);

                return textView;
            }
        });
        Log.v(TAG, "addTab "   tabSpec.getTag());
        mTabHost.addTab(tabSpec);

        // required for setting focus programmatically
        View tab = mTabHost.getTabWidget().getChildAt(
                mTabHost.getTabWidget().getChildCount() - 1);
        tab.setFocusableInTouchMode(true);
    }
}
  

Редактировать: вот вывод LogCat при переключении ориентации с выбранной первой вкладкой:

 addTab tab1
createTabContent tab1
addTab tab2
addTab tab3
addTab tab4
restoring tab pref tab1
createTabContent tab2
  

Откуда берется createTabContent tab2 вывод в последней строке?

Любая помощь очень ценится. Заранее спасибо!

Комментарии:

1. Является ли программный выбор вкладки при изменении ориентации обязательным в вашем приложении? Пожалуйста, попробуйте избежать этого. Также вы можете добавить вкладки в TabHost в onCreate.

2. Это обязательно с точки зрения пользовательского интерфейса. Например, если есть 10 вкладок, и пользователь находится на 9-й вкладке при переключении ориентации, я хочу, чтобы 9-я вкладка была их активной вкладкой после переключения, а не первой вкладкой. Это работает со 2-й по n-ю вкладку, но по какой-то причине не с 1-й вкладкой. Что касается того, какое событие я использую, я понимаю, что могу использовать onCreate, даже onResume, если на то пошло; проблема заключается в программном выборе 1-й вкладки.

3. Я просмотрел исходный код Android для TabHost, чтобы посмотреть, что может происходить, но я не смог найти ничего, что бросилось бы мне в глаза. Однако я заметил, что вызов setCurrentTab () и focusCurrentTab () после setCurrentTabByTag () был избыточным, поэтому я отредактировал свой пост, чтобы отразить это.