problem rozwiązany
Z jak popularne to pytanie stało się, postanowiłem ponownie powrócić do tego problemu ponownie i zobaczyć i f Mogę znaleźć rozwiązanie ... i zrobiłem to.Znaleziono małą, przyjemną pracę, która rozwiązuje pojedyncze okienko zamiast podwójnego panelu i zapewnia, że nagłówek jest zawsze wybierany wstępnie w trybie podwójnego panelu.
Jeśli nie interesuje Cię wyjaśnienie, możesz po prostu przejść do kodu. Jeśli nie zależy Ci na systemie ICS, wiele kodu śledzenia nagłówka może zostać usuniętych, ponieważ JB dodał moduł pobierający dla listy tablic nagłówków.
Podwójny Pane Issue
Podczas przeglądania listy preferencji nagłówka w trybie pojedynczym lub podwójnym trybie tafli szyby, istnieje zawsze tylko jeden PreferenceActivity stworzony i to samo działanie dla obu przypadków. W rezultacie nigdy nie ma problemu z obsługą obracania ekranu, który przełącza tryb panela.
Jednak w trybie pojedynczego panelu po kliknięciu nagłówka odpowiedni fragment jest dołączony do NOWEJ PreferencjiAktywności. Ten nowy fragment zawierający PreferenceActivity nigdy nie wywołuje onBuildHeaders()
. I dlaczego miałby to robić? Nie trzeba ich wyświetlać. To leży w tym problemie.
Po obróceniu tego fragmentu do trybu z dwoma panelami, nie ma żadnej listy nagłówków do pokazania, więc po prostu nadal wyświetla tylko ten fragment. Nawet jeśli wyświetliłby listę nagłówków, będziesz mieć problemy z backstackiem, ponieważ będziesz miał teraz dwie kopie nagłówków pokazujących PreferenceActivity. Kontynuuj klikanie wystarczającej liczby nagłówków, a będziesz mieć dość długi stos działań, aby użytkownik mógł nawigować z powrotem. W rezultacie odpowiedź jest prosta. Po prostu finish()
aktywność. Następnie załaduje oryginalną PreferenceActivity, która ma listę nagłówków i odpowiednio wyświetli tryb podwójnego panelu.
Auto Wybór Header
Kolejna kwestia, która była potrzebna przeciwdziałanie że przełączanie między trybem single do podwójnej szyby z nową poprawką nie auto wybrać nagłówek. Została ci lista nagłówków i nie załadowano fragmentów szczegółów. Ta poprawka nie jest tak prosta. Zasadniczo wystarczy śledzić, który nagłówek został ostatnio kliknięty i zapewnić podczas tworzenia PreferenceActivity ... zawsze wybierany jest nagłówek.
To kończy się nieco irytujące w ICS, ponieważ API nie wystawia gettera na wewnętrznie śledzoną listę nagłówków. Android już utrzymuje tę listę i możesz ją technicznie odzyskać za pomocą tego samego, prywatnego, przechowywanego klucza, jednak jest to po prostu zły wybór. Zamiast tego proponuję ręcznie samodzielnie go utrwalić.
Jeśli nie zależy Ci na systemie ICS, możesz po prostu użyć metody getHeaders()
ujawnionej w JB i nie martw się o żaden z zapisanych/przywróconych stanów.
Kod
public class SettingsActivity extends PreferenceActivity {
private static final String STATE_CUR_HEADER_POS = "Current Position";
private static final String STATE_HEADERS_LIST = "Headers List";
private int mCurPos = AdapterView.INVALID_POSITION; //Manually track selected header position for dual pane mode
private ArrayList<Header> mHeaders; //Manually track headers so we can select one. Required to support ICS. Otherwise JB exposes a getter instead.
@Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preference, target);
mHeaders = (ArrayList<Header>) target; //Grab a ref of the headers list
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//This is the only code required for ensuring a dual pane mode shows after rotation of a single paned preference screen
if (onIsMultiPane() && onIsHidingHeaders()) {
finish();
}
}
@Override
public boolean onIsMultiPane() {
//Override this if you want dual pane to show up on smaller screens
return getResources().getBoolean(R.bool.pref_prefer_dual_pane);
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
super.onListItemClick(l, v, position, id);
//Intercept a header click event to record its position.
mCurPos = position;
}
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
//Retrieve our saved header list and last clicked position and ensure we switch to the proper header.
mHeaders = state.getParcelableArrayList(STATE_HEADERS_LIST);
mCurPos = state.getInt(STATE_CUR_HEADER_POS);
if (mHeaders != null) {
if (mCurPos != AdapterView.INVALID_POSITION) {
switchToHeader(mHeaders.get(mCurPos));
} else {
switchToHeader(onGetInitialHeader());
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//Persist our list and last clicked position
if (mHeaders != null && mHeaders.size() > 0) {
outState.putInt(STATE_CUR_HEADER_POS, mCurPos);
outState.putParcelableArrayList(STATE_HEADERS_LIST, mHeaders);
}
}
}
Co "mówią" perspektywę debugowania? –
Masz wartości, które zawierają stan "widoczny". –
Funkcja PreferenceActivity obsługuje zmiany widoczności. W szczególności nie zmieniam tego. Powyższy kod jest dosłownie wszystkim, co robię. –