Po uaktualnieniu do Support Library v21 mój ActionBar PreferenceActivity
zniknął.
Czy przegapiłem jakieś atrybuty w moim motywie, aby go ponownie aktywować? Miałem podobny problem z czarnym ActionBarem .
Próbowałem też dodać trochę hackingu, dodając Toolbar
do układu głównego, ale to nie zadziałało zgodnie z oczekiwaniami.
Odpowiedzi:
Znajdź repozytorium GitHub: tutaj
Bardzo podobny do twojego własnego kodu, ale dodano XML, aby umożliwić ustawienie tytułu:
Kontynuacja użytkowania
PreferenceActivity
:settings_toolbar.xml :
<?xml version="1.0" encoding="utf-8"?> <android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/toolbar" app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="?attr/actionBarSize" app:navigationContentDescription="@string/abc_action_bar_up_description" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:title="@string/action_settings" />
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
Result :
UPDATE (zgodność z piernikami):
Jak wskazano tutaj , Gingerbread Devices zwracają NullPointerException w tej linii:
LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent();
NAPRAWIĆ:
SettingsActivity.java :
public class SettingsActivity extends PreferenceActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); Toolbar bar; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top } else { ViewGroup root = (ViewGroup) findViewById(android.R.id.content); ListView content = (ListView) root.getChildAt(0); root.removeAllViews(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); int height; TypedValue tv = new TypedValue(); if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); }else{ height = bar.getHeight(); } content.setPadding(0, height, 0, 0); root.addView(content); root.addView(bar); } bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } }); } }
Wszelkie problemy z powyższym daj mi znać!
AKTUALIZACJA 2: OBEJŚCIE BARWIENIA
Jak wskazano w wielu notatkach deweloperów,
PreferenceActivity
nie obsługuje barwienia elementów, jednak używając kilku wewnętrznych klas MOŻESZ to osiągnąć. Dzieje się tak do momentu usunięcia tych klas. (Działa przy użyciu appCompat support-v7 v21.0.3).Dodaj następujące importy:
import android.support.v7.internal.widget.TintCheckBox; import android.support.v7.internal.widget.TintCheckedTextView; import android.support.v7.internal.widget.TintEditText; import android.support.v7.internal.widget.TintRadioButton; import android.support.v7.internal.widget.TintSpinner;
Następnie nadpisz
onCreateView
metodę:@Override public View onCreateView(String name, Context context, AttributeSet attrs) { // Allow super to try and create a view first final View result = super.onCreateView(name, context, attrs); if (result != null) { return result; } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { // If we're running pre-L, we need to 'inject' our tint aware Views in place of the // standard framework versions switch (name) { case "EditText": return new TintEditText(this, attrs); case "Spinner": return new TintSpinner(this, attrs); case "CheckBox": return new TintCheckBox(this, attrs); case "RadioButton": return new TintRadioButton(this, attrs); case "CheckedTextView": return new TintCheckedTextView(this, attrs); } } return null; }
Result:
AppCompat 22.1
AppCompat 22.1 wprowadził nowe przyciemniane elementy, co oznacza, że nie ma już potrzeby wykorzystywania klas wewnętrznych, aby osiągnąć ten sam efekt, co podczas ostatniej aktualizacji. Zamiast tego wykonaj następujące czynności (nadal nadrzędne
onCreateView
):@Override public View onCreateView(String name, Context context, AttributeSet attrs) { // Allow super to try and create a view first final View result = super.onCreateView(name, context, attrs); if (result != null) { return result; } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { // If we're running pre-L, we need to 'inject' our tint aware Views in place of the // standard framework versions switch (name) { case "EditText": return new AppCompatEditText(this, attrs); case "Spinner": return new AppCompatSpinner(this, attrs); case "CheckBox": return new AppCompatCheckBox(this, attrs); case "RadioButton": return new AppCompatRadioButton(this, attrs); case "CheckedTextView": return new AppCompatCheckedTextView(this, attrs); } } return null; }
EKRANY PREFERENCYJNE ZAGNIEŻDŻONE
Wiele osób ma problemy z włączaniem paska narzędzi do zagnieżdżonych
<PreferenceScreen />
s, jednak znalazłem rozwiązanie! - Po wielu próbach i błędach!Dodaj do swojego
SettingsActivity
:@SuppressWarnings("deprecation") @Override public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference) { super.onPreferenceTreeClick(preferenceScreen, preference); // If the user has clicked on a preference screen, set up the screen if (preference instanceof PreferenceScreen) { setUpNestedScreen((PreferenceScreen) preference); } return false; } public void setUpNestedScreen(PreferenceScreen preferenceScreen) { final Dialog dialog = preferenceScreen.getDialog(); Toolbar bar; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); root.addView(bar, 0); // insert at top } else { ViewGroup root = (ViewGroup) dialog.findViewById(android.R.id.content); ListView content = (ListView) root.getChildAt(0); root.removeAllViews(); bar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.settings_toolbar, root, false); int height; TypedValue tv = new TypedValue(); if (getTheme().resolveAttribute(R.attr.actionBarSize, tv, true)) { height = TypedValue.complexToDimensionPixelSize(tv.data, getResources().getDisplayMetrics()); }else{ height = bar.getHeight(); } content.setPadding(0, height, 0, 0); root.addView(content); root.addView(bar); } bar.setTitle(preferenceScreen.getTitle()); bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { dialog.dismiss(); } }); }
Powodem tego
PreferenceScreen
jest to, że są one oparte na oknach opakowujących, więc musimy uchwycić układ okna dialogowego, aby dodać do niego pasek narzędzi.Cień paska narzędzi
Zgodnie z projektem importowanie
Toolbar
nie pozwala na elewację i cieniowanie w urządzeniach starszych niż 21, więc jeśli chcesz mieć elewację na swoimToolbar
, musisz owinąć ją wAppBarLayout
:`settings_toolbar.xml:
<android.support.design.widget.AppBarLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <android.support.v7.widget.Toolbar .../> </android.support.design.widget.AppBarLayout>
Nie zapominając o dodaniu biblioteki Design Support jako zależności w
build.gradle
pliku:compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' compile 'com.android.support:design:22.2.0'
Android 6.0
Zbadałem zgłoszony problem nakładania się i nie mogę go odtworzyć.
Pełny kod używany, jak powyżej, daje następujące wyniki:
Jeśli czegoś mi brakuje, daj mi znać za pośrednictwem tego repozytorium, a zbadam sprawę.
źródło
android:theme
obejście naprawia tylko czarny kolor tekstu na pasku narzędzi w systemie Android 5.0+. Wygląda na to, że coś się zmieniło w nowej bibliotece wsparcia (używam 22.2.0).Użyj AppCompatActivity & PreferenceFragment, aby rozwiązać problem:
AppCompatActivity:
public class SettingsActivity extends AppCompatActivity { @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit(); }}
PreferenceFragment:
public class SettingsFragment extends PreferenceFragment { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.settings_preferences); }}
źródło
Skończyło się na samodzielnym dodaniu paska narzędzi za pomocą tego prostego kodu:
// get the root container of the preferences list LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar bar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.preferences_toolbar, root, false); root.addView(bar, 0); // insert at top bar.setNavigationOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { finish(); } });
Oto moje preferencje_toolbar.xml:
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_height="wrap_content" android:layout_width="match_parent" android:minHeight="?attr/actionBarSize" app:navigationContentDescription="@string/abc_action_bar_up_description" android:background="?attr/colorPrimary" app:navigationIcon="?attr/homeAsUpIndicator" app:theme="@style/Theme.Toolbar" />
źródło
Lepszym rozwiązaniem niż „toczenie własnego” paska akcji jest użycie klasy AppCompatDelegate , która umożliwia wprowadzenie rzeczywistego paska działań z biblioteki pomocy technicznej. Oto przykładowy kod, aby go użyć, zaczerpnięty z odpowiedzi Ľubomíra Kučery na to pytanie .
... import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatDelegate; import android.support.v7.widget.Toolbar; ... public class SettingsActivity extends PreferenceActivity { private AppCompatDelegate mDelegate; @Override protected void onCreate(Bundle savedInstanceState) { getDelegate().installViewFactory(); getDelegate().onCreate(savedInstanceState); super.onCreate(savedInstanceState); } @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); getDelegate().onPostCreate(savedInstanceState); } public ActionBar getSupportActionBar() { return getDelegate().getSupportActionBar(); } public void setSupportActionBar(@Nullable Toolbar toolbar) { getDelegate().setSupportActionBar(toolbar); } @Override public MenuInflater getMenuInflater() { return getDelegate().getMenuInflater(); } @Override public void setContentView(@LayoutRes int layoutResID) { getDelegate().setContentView(layoutResID); } @Override public void setContentView(View view) { getDelegate().setContentView(view); } @Override public void setContentView(View view, ViewGroup.LayoutParams params) { getDelegate().setContentView(view, params); } @Override public void addContentView(View view, ViewGroup.LayoutParams params) { getDelegate().addContentView(view, params); } @Override protected void onPostResume() { super.onPostResume(); getDelegate().onPostResume(); } @Override protected void onTitleChanged(CharSequence title, int color) { super.onTitleChanged(title, color); getDelegate().setTitle(title); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); getDelegate().onConfigurationChanged(newConfig); } @Override protected void onStop() { super.onStop(); getDelegate().onStop(); } @Override protected void onDestroy() { super.onDestroy(); getDelegate().onDestroy(); } public void invalidateOptionsMenu() { getDelegate().invalidateOptionsMenu(); } private AppCompatDelegate getDelegate() { if (mDelegate == null) { mDelegate = AppCompatDelegate.create(this, null); } return mDelegate; } }
źródło
Cześć, nie jestem, jeśli nadal masz ten problem. Ale myślę, że opublikuję, co zrobiłem, aby rozwiązać ten problem i mam nadzieję, że to komuś pomoże.
1) Po pierwsze, mogłeś zauważyć, że PreferenceActivity rozszerza ListActivity, które z kolei rozszerza się z Activity.
Zgodnie z komentarzami na blogu deweloperów ( http://android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html ), aby używać wersji 21, wszystkie Twoje działania muszą dziedziczyć po ActionBarActivity . Więc jest twój problem.
2) Kroki, które rozwiązałem, to:
a) Make sure that you set the Theme of your PreferenceActivity to inherits one ot the Theme.AppCompat Themes. b) Make your class PreferenceActivity extends ActionBarActivity. c) Use the PreferenceFragment as your container for all your preferences.
To powinno rozwiązać problem.
Twoje zdrowie!
źródło
Zrobiłem coś podobnego do zaakceptowanego pytania, ale używam swojego układu również w innych działaniach
MainActivity
, więc nie mogę po prostu zakodować w nim strzałki.Co mi pomogło:
private void setupActionBar() { LinearLayout root = (LinearLayout)findViewById(android.R.id.list).getParent().getParent().getParent(); Toolbar toolbar = (Toolbar)LayoutInflater.from(this).inflate(R.layout.app_bar, root, false); root.addView(toolbar, 0); setSupportActionBar(toolbar); ActionBar ab = getSupportActionBar(); ab.setDisplayHomeAsUpEnabled(true); }
źródło
Miałem ten sam problem. po prostu spróbuj zmienić Motyw działania na taki, który zawiera dowolny ActionBar. Dodanie następującego wiersza w tagu aktywności SettingsActivity wyszło dla mnie:
android:theme="Theme.AppCompat.DayNight.DarkActionBar"
źródło
Prostym sposobem, który odkryłem, jest zastąpienie:
@android:style/Theme.Material.Light.DarkActionBar
W Twoim stylu:
<style name="SettingsTheme" parent="@android:style/Theme.Material.Light.DarkActionBar"> <item name="android:colorPrimary">@color/sunshine_blue</item> <item name="android:colorPrimaryDark">@color/sunshine_dark_blue</item> </style>
źródło