How to add toolbars to AppCompatPreferenceActivity?
Asked Answered
P

6

16

I'm trying to add toolbars to the AppCompatPreferenceActivity but I don't know how to do so.

Can you tell me how?

Progeny answered 8/5, 2015 at 2:15 Comment(0)
P
17

First copy AppCompatPreferenceActivity to your project.

The use it like this:

public class SettingsActivity extends AppCompatPreferenceActivity {

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

    private void setupActionBar() {
        Toolbar toolbar;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            ViewGroup root = (ViewGroup) findViewById(android.R.id.list).getParent().getParent().getParent();
            toolbar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.view_toolbar, root, false);
            root.addView(toolbar, 0);
        } else {
            ViewGroup root = (ViewGroup) findViewById(android.R.id.content);
            ListView content = (ListView) root.getChildAt(0);
            root.removeAllViews();
            toolbar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.view_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 = toolbar.getHeight();
            }
            content.setPadding(0, height, 0, 0);
            root.addView(content);
            root.addView(toolbar);
        }
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

It's not a very elegant solution but it works. Tested on Gingerbread and Lollipop.

Pekingese answered 16/5, 2015 at 22:0 Comment(3)
How are preferences added in it?Reproval
I didn't have to use any of the setupActionBar() code, just copied the AppCompatPreferenceActivity, extended it and it worked.Safari
Yeah it seems to work if you have proper AppTheme. If application AppTheme extends some Theme . NoActionBar than there is no action bar and it must be added from layout. It works if you want this new custom toolbar with them NoActionBar.Sylviesylvite
P
7

Try this:

public class SettingsActivity extends AppCompatPreferenceActivity {

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

        LinearLayout root = (LinearLayout) findViewById(android.R.id.list).getParent().getParent().getParent();
        Toolbar toolbar = (Toolbar) LayoutInflater.from(this).inflate(R.layout.toolbar_settings, root, false);
        root.addView(toolbar, 0);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }
}

EDIT

AppCompatPreferenceActivity is this demo class for supprt v7:

https://android.googlesource.com/platform/development/+/nougat-release/samples/Support7Demos/src/com/example/android/supportv7/app/AppCompatPreferenceActivity.java

Plumbing answered 13/5, 2015 at 20:19 Comment(1)
This looks like an Android 2.x preference activity. So what's the point of using it?Ternan
S
4

I solved this putting theme to Activity on AndrodManifest

android:theme="@style/Theme.AppCompat.Light"
Shandeigh answered 6/2, 2017 at 7:3 Comment(0)
T
2

Use PreferenceFragment, You can do like this in your activity:

Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

getSupportFragmentManager().beginTransaction().replace(R.id.content_frame, new MyPreferenceFragment()).commit();

And the MyPreferenceFragment like this:

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

Hope this helped!

Transference answered 8/5, 2015 at 12:5 Comment(3)
No, I don't mean PreferenceFragment, I mean AppCompatPreferenceActivity which using the new AppCompatDelegate. You can find it in this link: android.googlesource.com/platform/development/+/master/samples/…Progeny
PreferenceFragment is not in support library, hence you cannot use SupportFragmentManager.Kenaz
You should be using PreferenceFragmentCompatKr
D
1

Here is my toolbar.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="@dimen/appbar_elevation"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
android:popupTheme="@style/ThemeOverlay.AppCompat.Light" />

and adding the following lines of code at the beginning of the setupActionBar() will add the toolbar at runtime.

getLayoutInflater().inflate(R.layout.toolbar, 
(ViewGroup)findViewById(android.R.id.content));
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);

this work for me kindly!

Thanks for galdin.

Doityourself answered 2/5, 2019 at 12:49 Comment(0)
S
0

You can use Android Studio to generate a setting activity, and it may automaticly generate a sample code like this:

import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.preference.ListPreference;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import android.preference.RingtonePreference;
import android.support.v7.app.ActionBar;
import android.text.TextUtils;
import android.view.MenuItem;

import java.util.List;

/**
 * A {@link PreferenceActivity} that presents a set of application settings. On
 * handset devices, settings are presented as a single list. On tablets,
 * settings are split by category, with category headers shown to the left of
 * the list of settings.
 * <p>
 * See <a href="http://developer.android.com/design/patterns/settings.html">
 * Android Design: Settings</a> for design guidelines and the <a
 * href="http://developer.android.com/guide/topics/ui/settings.html">Settings
 * API Guide</a> for more information on developing a Settings UI.
 */
public class SettingsActivity extends AppCompatPreferenceActivity {
    /**
     * 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 value ) {
                    String stringValue = value.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( null );
                            }
                            else {
                                // Set the summary to reflect the new ringtone display
                                // name.
                                String name = ringtone.getTitle( preference.getContext() );
                                preference.setSummary( name );
                            }
                        }

                    }
                    else {
                        // For all other preferences, set the summary to the value's
                        // simple string representation.
                        preference.setSummary( stringValue );
                    }
                    return true;
                }
            };

    /**
     * Helper method to determine if the device has an extra-large screen. For
     * example, 10" tablets are extra-large.
     */
    private static boolean isXLargeTablet ( Context context ) {
        return ( context.getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK ) >=
                Configuration.SCREENLAYOUT_SIZE_XLARGE;
    }

    /**
     * Binds a preference's summary to its value. More specifically, when the
     * preference's value is changed, its summary (line of text below the
     * preference title) is updated to reflect the value. The summary is also
     * immediately updated upon calling this method. The exact display format is
     * dependent on the type of preference.
     *
     * @see #sBindPreferenceSummaryToValueListener
     */
    private static void bindPreferenceSummaryToValue ( Preference preference ) {
        // Set the listener to watch for value changes.
        preference.setOnPreferenceChangeListener( sBindPreferenceSummaryToValueListener );

        // Trigger the listener immediately with the preference's
        // current value.
        sBindPreferenceSummaryToValueListener.onPreferenceChange( preference,
                                                                  PreferenceManager.getDefaultSharedPreferences(
                                                                          preference.getContext() )
                                                                                   .getString( preference.getKey(),
                                                                                               "" ) );
    }

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

    /**
     * Set up the {@link android.app.ActionBar}, if the API is available.
     */
    private void setupActionBar () {
        ActionBar actionBar = getSupportActionBar();
        if ( actionBar != null ) {
            // Show the Up button in the action bar.
            actionBar.setDisplayHomeAsUpEnabled( true );
            actionBar.setHomeButtonEnabled( true );
        }

    }

    @Override
    public boolean onOptionsItemSelected ( MenuItem item ) {
        switch ( item.getItemId() ) {
            case android.R.id.home:
                finish();
        }
        return super.onOptionsItemSelected( item );
    }

    /** {@inheritDoc} */
    @Override
    public boolean onIsMultiPane () {
        return isXLargeTablet( this );
    }

    /** {@inheritDoc} */
    @Override
    @TargetApi ( Build.VERSION_CODES.HONEYCOMB )
    public void onBuildHeaders ( List< Header > target ) {
        loadHeadersFromResource( R.xml.pref_headers, target );
    }

    /**
     * This method stops fragment injection in malicious applications.
     * Make sure to deny any unknown fragments here.
     */
    protected boolean isValidFragment ( String fragmentName ) {
        return PreferenceFragment.class.getName().equals( fragmentName ) ||
                GeneralPreferenceFragment.class.getName().equals( fragmentName ) ||
                DataSyncPreferenceFragment.class.getName().equals( fragmentName ) ||
                NotificationPreferenceFragment.class.getName().equals( fragmentName );
    }

    /**
     * This fragment shows general preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi ( Build.VERSION_CODES.HONEYCOMB )
    public static class GeneralPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate ( Bundle savedInstanceState ) {
            super.onCreate( savedInstanceState );
            addPreferencesFromResource( R.xml.pref_general );
            setHasOptionsMenu( true );

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue( findPreference( "example_text" ) );
            bindPreferenceSummaryToValue( findPreference( "example_list" ) );
        }

        @Override
        public boolean onOptionsItemSelected ( MenuItem item ) {
            int id = item.getItemId();
            if ( id == android.R.id.home ) {
                startActivity( new Intent( getActivity(), SettingsActivity.class ) );
                return true;
            }
            return super.onOptionsItemSelected( item );
        }
    }

    /**
     * This fragment shows notification preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi ( Build.VERSION_CODES.HONEYCOMB )
    public static class NotificationPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate ( Bundle savedInstanceState ) {
            super.onCreate( savedInstanceState );
            addPreferencesFromResource( R.xml.pref_notification );
            setHasOptionsMenu( true );

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue( findPreference( "notifications_new_message_ringtone" ) );
        }

        @Override
        public boolean onOptionsItemSelected ( MenuItem item ) {
            int id = item.getItemId();
            if ( id == android.R.id.home ) {
                startActivity( new Intent( getActivity(), SettingsActivity.class ) );
                return true;
            }
            return super.onOptionsItemSelected( item );
        }
    }

    /**
     * This fragment shows data and sync preferences only. It is used when the
     * activity is showing a two-pane settings UI.
     */
    @TargetApi ( Build.VERSION_CODES.HONEYCOMB )
    public static class DataSyncPreferenceFragment extends PreferenceFragment {
        @Override
        public void onCreate ( Bundle savedInstanceState ) {
            super.onCreate( savedInstanceState );
            addPreferencesFromResource( R.xml.pref_data_sync );
            setHasOptionsMenu( true );

            // Bind the summaries of EditText/List/Dialog/Ringtone preferences
            // to their values. When their values change, their summaries are
            // updated to reflect the new value, per the Android Design
            // guidelines.
            bindPreferenceSummaryToValue( findPreference( "sync_frequency" ) );
        }

        @Override
        public boolean onOptionsItemSelected ( MenuItem item ) {
            int id = item.getItemId();
            if ( id == android.R.id.home ) {
                startActivity( new Intent( getActivity(), SettingsActivity.class ) );
                return true;
            }
            return super.onOptionsItemSelected( item );
        }
    }
}

AppCompatPreferenceActivity.class as we all know:

/** * A {@link android.preference.PreferenceActivity} which implements and proxies the necessary calls * to be used with AppCompat. */

Obviously,AppCompatPreferenceActivity.class supposes to be an sulotion class for compat.

When you come to some compat issues with PreferenceActivity like toolbar or something, you should consider it. Like the anwser given by @David Vávra which is perfect, his code may do the apperence trick.

And you keep asking how to setup this preference activity (which I was seeking ... otherwise I won't get on Stackoverflow)

So I read this page https://developer.android.com/reference/android/preference/PreferenceActivity.html and plus with the two pages given by the javadoc. I think the way to customer the child class of AppCompatPreferenceActivity goes like this:


If you simply want to make your **SettingActivity looks like some PreferenceFragment's appearence, you should not override this method "onBuildHeaders()"

    /** {@inheritDoc} */
    @Override
    @TargetApi ( Build.VERSION_CODES.HONEYCOMB )
    public void onBuildHeaders ( List< Header > target ) {
        loadHeadersFromResource( R.xml.pref_headers, target );
    }

FYI the pref_headers usage is given by the page https://developer.android.com/reference/android/preference/PreferenceActivity.html

And add this line in your onCreate() method.

    addPreferencesFromResource( R.xml.pref_setting );

and go to config your preference XML(Usage also on that page). Run your app, you will find it works.And then you may do something else like decoration/ add menu on toolbar/ add listeners or just add some logical code related to your app.

Sideward answered 13/8, 2016 at 11:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.