I'm trying to implement a basic settings activity in an Android app and either get a blank white screen or a crash. The documentation and samples I've seen aren't helping because they're either old or inconsistent. For example, depending on where you look, the settings activity should either extend Activity, PreferenceActivity, or AppCompatPreferenceActivity (part of the File>New>Activity>Settings Activity).
developer.android.com says you should implement the following:
public class SettingsActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment())
.commit();
}
}
Yet, the Settings Activity generated in Android Studio uses does not make this call for any of the three fragments it creates. It uses preference headers.
So here are my questions:
getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit()
in SettingsActivity.onCreate()?Let's say we want to have a settings screen with one checkbox preference fragment as shown below:
Here is a step by step guide on how to build a settings activity where you can add some preferences to toggle or change the configurations for your Android app:
Add a dependency for support of preference fragment in build.gradle
file for app
module:
dependencies {
compile 'com.android.support:preference-v7:25.1.0'
}
Add xml
Android resource directory inside res
directory.
Inside xml
directory, add a new XML resource file
named pref_visualizer.xml
as below. We're going to add one check-box preference fragment inside it.
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:defaultValue="true"
android:key="show_base"
android:summaryOff="Bass will not be shown currently."
android:summaryOn="Bass will be shown currently."
android:title="Show Bass"
/>
</PreferenceScreen>
PreferenceScreen
is the root tag which can hold as many preference fragments as you want. If you want to add more configurations of type list or text box then you need to add it here as a child of PreferenceScreen
tag.
Add a new Java class named SettingsFragment
which will host PreferenceScreen
. It should extend PreferenceFragmentCompat
class as shown below:
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.support.v7.preference.CheckBoxPreference;
import android.support.v7.preference.EditTextPreference;
import android.support.v7.preference.ListPreference;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.widget.Toast;
public class SettingsFragment extends PreferenceFragmentCompat {
@Override
public void onCreatePreferences(Bundle bundle, String s) {
addPreferencesFromResource(R.xml.pref_visualizer);
}
}
Now comes the final part where we build the association between an activity in the app and SettingsFragment
class which hosts PreferenceScreen
. Add a new activity named SettingsActivity
which inherits from AppCompatActivity
class. SettingsActivity
class will act as the container for PreferenceScreen
.
Java file for SettingsActivity
:
import android.support.v4.app.NavUtils;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.MenuItem;
public class SettingsActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
}
}
Layout file for SettingsActivity
is shown below (activity_settings.xml
). Here android.name
property is the crux. It connects this activity to any of the classes present in your entire project which are inheriting from PreferenceFragmentCompat
class. I had only one such class named SettingsFragment
. You might have more than one class inheriting from PreferenceFragmentCompat
class if you app has multiple settings screen.
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_settings"
android:name="android.example.com.visualizerpreferences.SettingsFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
You're all set!