add action bar with back button in preference activity [duplicate]

為{幸葍}努か 提交于 2019-12-30 06:04:13

问题


Here is my preference activity:

package com.example.hms.test;

import android.os.Bundle;
import android.preference.PreferenceActivity;

public class PrefsActivity extends PreferenceActivity {

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.prefs);
    }

}

here I want to show an actionbar with name settings and a back button to home


回答1:


You should do couple of things:

  1. Add the following to your onCreate of PreferenceActivity:

    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    
  2. Override onOptionsItemSelected in PreferenceActivity:

    @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         switch (item.getItemId())
         {
             case android.R.id.home:
                 NavUtils.navigateUpFromSameTask(this);
                 return true;
         }
         return super.onOptionsItemSelected(item);
     }
    
  3. change the <activity> tag in manifest for your PreferenceActivity to look something like this:

    <activity
      android:name=".PrefsActivity"
      android:label="@string/title_activity_settings"
      android:parentActivityName=".MainActivity">
      <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value="com.example.android.MainActivity" />
    </activity>
    
  4. Finally put android:launchMode="singleTop" in your MainActivity <activity> tag in manifest:

    <activity
      android:name=".MainActivity"
      android:label="@string/app_name"
      android:launchMode="singleTop"
      android:theme="@style/AppTheme.NoActionBar">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>
    



回答2:


The answer Pooya gave won't work for a PreferenceActivity. Instead make your class extend AppCompatActivity, and use a PreferenceFragment to load up the preference. Here is my code for settings:

public class MyPrefsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MyPreferenceFragment()).commit();

        getSupportActionBar().setDisplayShowHomeEnabled(true);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    }

    @Override
    public boolean onSupportNavigateUp(){
        finish();
        return true;
    }

    public static class MyPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }
    }
}

Put the activity in your AndroidManifest.XML:

<activity android:name=".MyPrefsActivity"
    android:label="Preferences"
    android:theme="@style/AppTheme"/>

And now you can start the settings activity using an intent in my Main Activity (or whichever parent activity you have) as normal:

Intent prefsIntent = new Intent(activity, MyPrefsActivity.class);
activity.startActivity(prefsIntent);



回答3:


I needed different action bar menu items in my activities so I created my MainActivity with a singleTop launchMode. That was great for getting my child activity's action bar set up, but it left my preferences activity without an action bar.

In the end, the key was in making sure the MainActivity theme had a parent of Theme.AppCompat.Light.NoActionBar:

       <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:theme="@style/AppTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

and the SettingsActivity theme had the parent Theme.AppCompat.Light.DarkActionBar:

    <activity
        android:name=".SettingsActivity"
        android:label="@string/title_activity_settings"
        android:theme="@style/SettingsTheme"
        android:parentActivityName=".MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value="net.deatrich.app.bodyandminddbt.MainActivity" />
    </activity>

In styles.xml

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>

</style>

<style name="SettingsTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <!-- Customize your theme here. -->
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

There's probably a better way to style it but this works.

For anyone else reading, also remember to derive your SettingsActivity from AppCompatPreferenceActivity:

SettingsActivity.java:

public class SettingsActivity extends AppCompatPreferenceActivity {

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

    // I'm displaying a fragment as the main content.
    getFragmentManager().beginTransaction()
            .replace(android.R.id.content, new GeneralPreferenceFragment())
            .commit();

    setupActionBar();

}


private void setupActionBar() {

    getSupportActionBar().setDisplayShowHomeEnabled(true);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);


}

@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
    int id = item.getItemId();
    if (id == android.R.id.home) {
        if (!super.onMenuItemSelected(featureId, item)) {
            NavUtils.navigateUpFromSameTask(this);
        }
        return true;
    }
    return super.onMenuItemSelected(featureId, item);
}
...



回答4:


okay. now you still trouble then i have unique solution for you which work 100% with just minor changes.

so first of all create one style for only settings activity.

here is my toolbar styles code.

<style name="Toolbar_settings_style" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:colorControlNormal">@color/appTitleTextColor</item>
    </style>

and here is my stlyes.xml looks like

<resources>    
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:colorControlNormal">@color/appTitleTextColor</item>
    </style>

    <style name="AppTheme.NoActionBar">
        <item name="windowActionBar">false</item>
        <item name="windowNoTitle">true</item>
    </style>

    <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />

    <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />

    <style name="Toolbar_settings_style" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:colorControlNormal">@color/appTitleTextColor</item>
    </style>   

</resources>

yes. you noticed i have create duplicate styles(appTheme and Toolbar_settings_style both are same styles attribute) for only settingsActivity. it is very important to create duplicate styles.

Now go to your settingsActivity and paste below code inside onCreate().

 getSupportActionBar().setDisplayHomeAsUpEnabled(true);

After placing above code now my SettingsActivity looks like

import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.preference.EditTextPreference;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import android.view.MenuItem;


import settingspreferences.AppCompatPreferenceActivity;

public class User_Settings extends AppCompatPreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);

        // load settings fragment
        getFragmentManager().beginTransaction().replace(android.R.id.content, new MainPreferenceFragment()).commit();
    }

    public static class MainPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.settings);

            // gallery EditText change listener
            bindPreferenceSummaryToValue(findPreference(getString(R.string.key_gallery_name)));

            // notification preference change listener

        }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if (item.getItemId() == android.R.id.home) {
             //   onBackPressed();
            }
            return super.onOptionsItemSelected(item);
        }

        private static void bindPreferenceSummaryToValue(Preference preference) {
            preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);

            sBindPreferenceSummaryToValueListener.onPreferenceChange(preference,
                    PreferenceManager
                            .getDefaultSharedPreferences(preference.getContext())
                            .getString(preference.getKey(), ""));
        }

        /**
         * A preference value change listener that updates the preference's summary
         * to reflect its new value.
         */
        private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
            @Override
            public boolean onPreferenceChange(Preference preference, Object newValue) {
                String stringValue = newValue.toString();

                if (preference instanceof ListPreference) {
                    // For list preferences, look up the correct display value in
                    // the preference's 'entries' list.
                    ListPreference listPreference = (ListPreference) preference;
                    int index = listPreference.findIndexOfValue(stringValue);

                    // Set the summary to reflect the new value.
                    preference.setSummary(
                            index >= 0
                                    ? listPreference.getEntries()[index]
                                    : null);

                } else if (preference instanceof RingtonePreference) {
                    // For ringtone preferences, look up the correct display value
                    // using RingtoneManager.
                    if (TextUtils.isEmpty(stringValue)) {
                        // Empty values correspond to 'silent' (no ringtone).
                        preference.setSummary(R.string.pref_ringtone_silent);

                    } else {
                        Ringtone ringtone = RingtoneManager.getRingtone(
                                preference.getContext(), Uri.parse(stringValue));

                        if (ringtone == null) {
                            // Clear the summary if there was a lookup error.
                          //  preference.setSummary(R.string.summary_choose_ringtone);
                        } else {
                            // Set the summary to reflect the new ringtone display
                            // name.
                            String name = ringtone.getTitle(preference.getContext());
                            preference.setSummary(name);
                        }
                    }

                } else if (preference instanceof EditTextPreference) {
                    if (preference.getKey().equals("key_gallery_name")) {
                        // update the changed gallery name to summary filed
                        preference.setSummary(stringValue);
                    }
                } else {
                    preference.setSummary(stringValue);
                }
                return true;
            }
        };
    }

}

Now let's come to real important part. go to manifest.xml file and find your settingsActivity and paste below code.

 <activity android:name=".User_Settings"
            android:theme="@style/Toolbar_settings_style"></activity>

so here is my AndroidManifest.xml looks like

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="mypackage">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!--  -->
        <activity
            android:name=".MainActivity"
            android:windowSoftInputMode="adjustPan">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- <intent-filter> -->
            <!-- <action android:name="android.intent.action.SEARCH" /> -->
            <!-- </intent-filter> -->

            <meta-data
                android:name="android.app.searchable"
                android:resource="@xml/searchable" />
        </activity>
        <activity android:name=".Add_Items" />
        <activity android:name=".Product_details_view" />
        <activity
            android:name=".editProducts"
            android:parentActivityName=".Product_details_view" />
        <activity android:name=".User_Settings"
            android:theme="@style/Toolbar_settings_style"></activity>
    </application>

</manifest>

This is all you need to shows Toolbar on settingsActivity.



来源:https://stackoverflow.com/questions/37222879/add-action-bar-with-back-button-in-preference-activity

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!