Nach dem Upgrade auf die Support Library v21 ist meine ActionBar in meiner PreferenceActivity
weg.
Habe ich einige Attribute in meinem Design vermisst, um es wieder zu aktivieren? Ich hatte ähnliche Probleme mit einer schwarzen ActionBar .
Ich habe auch versucht, es etwas hackig hinzuzufügen, indem ich ein Toolbar
zum Root-Layout hinzufügte, aber das funktionierte nicht wie erwartet.
Hier finden Sie das GitHub-Repo: HERE
Sehr ähnlich zu Ihrem eigenen Code, aber hinzugefügtes XML, um den Satztitel zu ermöglichen:
PreferenceActivity
weiterhin verwenden:
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 :
Wie hier hervorgehoben wird, geben Gingerbread-Geräte in dieser Zeile NullPointerException zurück:
LinearLayout root = (LinearLayout)findViewById(Android.R.id.list).getParent().getParent().getParent();
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();
}
});
}
}
Irgendwelche Probleme mit dem oben genannten lassen Sie mich wissen!
UPDATE 2: TINTENABARBEITUNG
Wie in vielen Dev-Hinweisen dargelegt, unterstützt PreferenceActivity
keine Tönung von Elementen. Durch die Verwendung einiger interner Klassen können Sie dies jedoch erreichen. Das ist so lange, bis diese Klassen entfernt werden. (Funktioniert mit AppCompat Support-v7 v21.0.3).
Fügen Sie die folgenden Importe hinzu:
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;
Dann überschreiben Sie die onCreateView
-Methode:
@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 führte neue getönte Elemente ein, so dass die internen Klassen nicht mehr verwendet werden müssen, um denselben Effekt wie beim letzten Update zu erzielen. Folgen Sie stattdessen diesem (überschreiben Sie 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;
}
NESTED PREFERENCE SCREENS
Viele Leute haben Probleme mit dem Einbinden der Toolbar in verschachtelten <PreferenceScreen />
s. Ich habe jedoch eine Lösung gefunden !! - Nach vielem Ausprobieren!
Fügen Sie Ihrer SettingsActivity
Folgendes hinzu:
@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();
}
});
}
Der Grund, dass PreferenceScreen
s so schmerzhaft sind, liegt darin, dass sie als Wrapper-Dialog basieren. Daher müssen wir das Dialoglayout erfassen, um die Symbolleiste hinzuzufügen.
Beim Design-Import von Toolbar
ist keine Erhöhung und Schattierung in Geräten vor Version 21 möglich. Wenn Sie also eine Erhöhung auf Ihrer Toolbar
haben möchten, müssen Sie sie in eine AppBarLayout
einschließen:
`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>
Vergessen Sie nicht, das Hinzufügen der Design Support-Bibliothek als Abhängigkeit in build.gradle
-Datei hinzuzufügen:
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'
Ich habe das berichtete überlappende Problem untersucht und kann das Problem nicht reproduzieren.
Der vollständige Code, der wie oben verwendet wird, erzeugt Folgendes:
Wenn mir etwas fehlt, lass es mich bitte über dieses Repo wissen und ich werde es untersuchen.
Verwenden Sie AppCompatActivity & PreferenceFragment, um das Problem zu lösen:
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);
}}
Ich beendete das Hinzufügen der Toolbar selbst mit diesem einfachen Code:
// 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();
}
});
Hier ist meine preferences_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" />
Eine bessere Lösung als das "Rollen Ihrer eigenen" Aktionsleiste ist die Verwendung der AppCompatDelegate Klasse, mit der Sie eine tatsächlich-tatsächliche Aktionsleiste aus der Support-Bibliothek einlesen können. Hier ist ein Beispielcode, den Sie verwenden können, der Antwort von Ľubomír Kučera auf diese Frage .
...
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;
}
}
Hi ich bin nicht, wenn du dieses Problem noch hast. Aber ich denke, ich werde posten, was ich getan habe, um das Problem zu lösen, und hoffe, dass es jemandem helfen wird.
1) Zunächst einmal haben Sie vielleicht bemerkt, dass PreferenceActivity die ListActivity-Funktion erweitert, die wiederum von Activity ausgeht.
Laut den Kommentaren im Entwickler-Blog ( http://Android-developers.blogspot.com/2014/10/appcompat-v21-material-design-for-pre.html ), verwenden Sie v21 alle Ihre Aktivitäten muss von ActionBarActivity erben. Also da ist dein Problem.
2) Die Schritte, die ich zur Lösung verwendet habe, sind:
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.
Dies sollte es lösen.
Prost!
Ich hatte das gleiche Problem. Versuchen Sie einfach, das Thema der Aktivität in das zu ändern, in dem sich eine ActionBar befindet. Die folgende Zeile im Activity-Tag von SettingsActivity hinzugefügt:
Android:theme="Theme.AppCompat.DayNight.DarkActionBar"
Ich habe etwas Ähnliches wie die akzeptierte Frage gemacht, aber ich verwende mein Layout auch in anderen Aktivitäten (auch MainActivity
), sodass ich einen Pfeil darin nicht einfach hartcodieren kann.
Was für mich funktioniert hat:
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);
}