#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 () был избыточным, поэтому я отредактировал свой пост, чтобы отразить это.