Load Preferences Settings in Swipable Tabs with Fragment - android

I have searched the web but didnt find any proper solution.
I am trying to load some preference Settings in Tab Fragments.
In the first Image, When I use menu Inflator, I get those 3 dotted buttons, I dont need those, insted I want the menu to load in my Tab Fragment.
Below is the code of my
SettingPrefActivity.java
public class SettingsPrefActivity extends AppPreferenceActivity {
private static final String TAG = SettingsPrefActivity.class.getSimpleName();
#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.pref_main);
// gallery EditText change listener
bindPreferenceSummaryToValue(findPreference(getString(R.string.key_gallery_name)));
// notification preference change listener
bindPreferenceSummaryToValue(findPreference(getString(R.string.key_notifications_new_message_ringtone)));
// feedback preference click listener
Preference myPref = findPreference(getString(R.string.key_send_feedback));
myPref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
sendFeedback(getActivity());
return true;
}
});
}
}
#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;
}
};
/**
* Email client intent to send support mail
* Appends the necessary device information to email body
* useful when providing support
*/
public static void sendFeedback(Context context) {
String body = null;
try {
body = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
body = "\n\n-----------------------------\nPlease don't remove this information\n Device OS: Android \n Device OS version: " +
Build.VERSION.RELEASE + "\n App Version: " + body + "\n Device Brand: " + Build.BRAND +
"\n Device Model: " + Build.MODEL + "\n Device Manufacturer: " + Build.MANUFACTURER;
} catch (PackageManager.NameNotFoundException e) {
}
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("message/rfc822");
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"contact#androidhive.info"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Query from android app");
intent.putExtra(Intent.EXTRA_TEXT, body);
context.startActivity(Intent.createChooser(intent, context.getString(R.string.choose_email_client)));
}}
SettingsActivity.java
public class SettingsActivity extends Fragment {
private static final String TAG = SettingsPrefActivity.class.getSimpleName();
/*public SettingsActivity() {
// Required empty public constructor
}*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.setting_layout, container, false);
}
/*public boolean onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
// launch settings activity
startActivity(new Intent(SettingsActivity.this, SettingsPrefActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}*/
}
pref_main.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory android:title="General">
<EditTextPreference
android:defaultValue="#string/default_gallery_storage"
android:key="#string/key_gallery_name"
android:summary="#string/default_gallery_storage"
android:title="#string/title_gallery_storage" />
<CheckBoxPreference
android:defaultValue="true"
android:key="#string/key_upload_over_wifi"
android:summary="#string/summary_upload_over_wifi"
android:title="#string/title_auto_upload" />
<ListPreference
android:defaultValue="3"
android:dialogTitle="#string/title_upload_quality"
android:entries="#array/pref_upload_quality_entries"
android:entryValues="#array/pref_upload_quality_values"
android:key="#string/key_upload_quality"
android:summary="#string/summary_upload_video_quality"
android:title="#string/title_upload_quality" />
</PreferenceCategory>
<PreferenceCategory android:title="#string/pref_title_notifications">
<SwitchPreference
android:defaultValue="true"
android:key="#string/notifications_new_message"
android:title="#string/title_new_notification_sound" />
<RingtonePreference
android:defaultValue="content://settings/system/notification_sound"
android:dependency="notifications_new_message"
android:key="#string/key_notifications_new_message_ringtone"
android:ringtoneType="notification"
android:summary="#string/summary_choose_ringtone"
android:title="#string/pref_title_ringtone" />
<SwitchPreference
android:defaultValue="true"
android:key="#string/key_vibrate"
android:summary="#string/summary_vibrate"
android:title="#string/title_vibrate" />
</PreferenceCategory>
<PreferenceCategory android:title="#string/pref_header_about">
<Preference
android:selectable="false"
android:summary="#string/summary_about" />
<Preference
android:summary="#string/app_version"
android:title="#string/title_version" />
<Preference
android:key="#string/key_send_feedback"
android:summary="#string/summary_support"
android:title="#string/title_send_feedback" />
<!-- preference opens url in browser -->
<Preference
android:summary="#string/summary_faq"
android:title="#string/title_faq">
<intent
android:action="android.intent.action.VIEW"
android:data="#string/url_faq" />
</Preference>
<Preference android:title="#string/privacy_policy">
<intent
android:action="android.intent.action.VIEW"
android:data="#string/url_privacy" />
</Preference>
<Preference android:title="#string/title_terms">
<intent
android:action="android.intent.action.VIEW"
android:data="#string/url_terms" />
</Preference>
</PreferenceCategory>
</PreferenceScreen>
menu_main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="settings.MainActivity">
<item
android:id="#+id/action_settings"
android:orderInCategory="100"
android:title="#string/action_settings"
app:showAsAction="never" />
</menu>
settings_layout.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="This is Settings Page!! Coming Soon!"
android:textSize="30dp"
android:textStyle="bold"
android:layout_centerInParent="true"/>
</RelativeLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
private Toolbar toolbar;
private TabLayout tabLayout;
private ViewPager viewPager;
private int[] tabIcons = {R.drawable.ic_action_name};
String[] tabTitle={"","All"};
int[] unreadCount={0,5,3,0,12,3,9,0};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
tabLayout = (TabLayout) findViewById(R.id.tabs);
tabLayout.setupWithViewPager(viewPager);
viewPager.setCurrentItem(1);
setupTabIcons();
}
private View prepareTabView(int pos) {
View view = getLayoutInflater().inflate(R.layout.custom_tab,null);
TextView tv_title = (TextView) view.findViewById(R.id.tv_title);
TextView tv_count = (TextView) view.findViewById(R.id.tv_count);
tv_title.setText(tabTitle[pos]);
if(unreadCount[pos]>0)
{
tv_count.setVisibility(View.VISIBLE);
tv_count.setText(""+unreadCount[pos]);
}
else
tv_count.setVisibility(View.GONE);
return view;
}
private void setupTabIcons() {
tabLayout.getTabAt(0).setIcon(tabIcons[0]);
/*TabLayout.Tab tabitem = tabLayout.newTab();
tabitem.setCustomView(prepareTabView(i));
tabLayout.addTab(tabitem);*/
for(int i = 1; i < unreadCount.length; i++)
{
/*TabLayout.Tab tabitem = tabLayout.newTab();
tabitem.setCustomView(prepareTabView(i));
tabLayout.addTab(tabitem);*/
tabLayout.getTabAt(i).setCustomView(prepareTabView(i));
}
}
private TabLayout.OnTabSelectedListener onTabSelectedListener(final
ViewPager viewPager) {
return new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
private void setupViewPager(ViewPager viewPager) {
ViewPagerAdapter adapter = new
ViewPagerAdapter(getSupportFragmentManager());
adapter.addFragment(new SettingsActivity(), "");
adapter.addFragment(new AllTab(), "All");
viewPager.setAdapter(adapter);
}
class ViewPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitleList = new ArrayList<>();
public ViewPagerAdapter(FragmentManager manager) {
super(manager);
}
#Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
#Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitleList.add(title);
}
#Override
public CharSequence getPageTitle(int position) {
return mFragmentTitleList.get(position);
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="inc.apperz.passmanager.MainActivity">
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="#style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:layout_scrollFlags="scroll|enterAlways"
app:popupTheme="#style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:tabMode="scrollable"
app:tabSelectedTextColor="#color/colorGreen"
app:tabTextColor="#color/colorWhite"
app:tabIndicatorColor="#color/colorWhite"
app:tabGravity="fill"/>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior" />
</android.support.constraint.ConstraintLayout>
Is there any possibility that I can include my main_menu.xml into my setting_layout.xml? such that it will get bind to my SettingsActivity.java?
If its possible, that would be great, but I tried that way and didn't find appropriate way to include it.
Can someone guide me to how to achieve this..

Try adding this to your fragment:
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
MenuItem item= menu.findItem(R.id.action_settings);
item.setVisible(false);
super.onPrepareOptionsMenu(menu);
return true;
}

Related

How to save fragment state

I have SettingActivity. It contains SettingFragment (with ListPreference) and another AudioSamplingSeekBarFragment(with my custom preference in it). When i choose some item in ListPreference, i recreate my AudioSamplingSeekBarFragment with chosen data from ListPreference. like this:
public class SettingsFragment extends PreferenceFragment {
private static Logger log = Logger.getLogger(SettingsFragment.class.getName());
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
ListPreference outputFormatPref = (ListPreference) findPreference(getResources().getString(R.string.key_encoder));
outputFormatPref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
MySharedPreferences.setAudioEncoder(getActivity(), (String) newValue);
**embedSeekBarWithFormat((String) newValue);**
return true;
}
});
}
**public void embedSeekBarWithFormat(String format) {
try {
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
AudioSamplingSeekBarFragment fragment = (AudioSamplingSeekBarFragment) manager.findFragmentByTag(AudioSamplingSeekBarFragment.TAG);
if (manager.findFragmentByTag(AudioSamplingSeekBarFragment.TAG) != null) {
transaction.remove(fragment);
}
AudioSamplingSeekBarFragment newFragment = new AudioSamplingSeekBarFragment();
Bundle bundle = new Bundle();
bundle.putInt(AudioSamplingSeekBarFragment.STATE_FORMAT, Integer.parseInt(format));
newFragment.setArguments(bundle);
transaction.add(R.id.seekBar_container, newFragment, AudioSamplingSeekBarFragment.TAG);
transaction.commit();
} catch (Exception e) {
log.log(Level.SEVERE, "Exception: ", e);
}
}
}**
So when i quite the SettingActivity and go into again my AudioSamplingSeekBarFragment doesn't save state.
I put my fragment in onSaveInstanceState() in SettingsActivity as they say here: topic
public class SettingsActivity extends android.support.v7.app.ActionBarActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_preferences);
if (savedInstanceState != null) {
getFragmentManager()
.beginTransaction()
.add(R.id.seekBar_container, getFragmentManager().getFragment(savedInstanceState, AudioSamplingSeekBarFragment.TAG) , AudioSamplingSeekBarFragment.TAG)
.commit();
} else {
getFragmentManager()
.beginTransaction()
.add(R.id.seekBar_container, new AudioSamplingSeekBarFragment(), AudioSamplingSeekBarFragment.TAG)
.commit();
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getFragmentManager()
.putFragment(outState, AudioSamplingSeekBarFragment.TAG, getFragmentManager().findFragmentByTag(AudioSamplingSeekBarFragment.TAG));
}
And save specific data in onSaveInstanceState() in Fragment:
public class AudioSamplingSeekBarFragment extends Fragment {
public static final String TAG = "SEEK_BAR_FRAGMENT_TAG";
public static final String STATE_FORMAT = "format";
private int format;
private int seekBarInitVal;
**#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt(STATE_FORMAT, format);
}**
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_audio_sampling_seekbar, container,false);
}
And i'm expecting to restore saved data here:
#Override
public void onViewCreated(final View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (savedInstanceState != null) {
**format = savedInstanceState.getInt(STATE_FORMAT);**
} else if (getArguments() != null){
format = getArguments().getInt(STATE_FORMAT);
} else {
format = AAC;
}
SeekBar seekBar = (SeekBar)view.findViewById(R.id.sample_rate_seek_bar);
final TextView textProgress = (TextView) view.findViewById(R.id.progress);
switch (format) {
case AAC:
seekBarInitVal = 8000;
seekBar.setMax(40000);
break;
case AAC_ELD:
seekBarInitVal = 16000;
seekBar.setMax(32000);
break;
case AMR_NB:
seekBarInitVal = 8000;
seekBar.setEnabled(false);
break;
case AMR_WB:
seekBarInitVal = 16000;
seekBar.setEnabled(false);
break;
case HE_AAC:
seekBarInitVal = 8000;
seekBar.setMax(40000);
break;
}
textProgress.setText("" + seekBarInitVal + " Hz");
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
i += seekBarInitVal;
textProgress.setText("" + i + " Hz");
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
}
});
}
}
But it doesn't work.
Just in case layouts:
activity_preference:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"/>
<FrameLayout
android:id="#+id/preferences_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<FrameLayout
android:id="#+id/seekBar_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
fragment_audio_sampling_seekbar:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/seekBar_fragment">
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#dbdbdd" />
<TextView
android:id="#+id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="15dp"
android:layout_marginTop="14dp"
android:text="Set Audio Sampling Rate"
android:textAppearance="#style/TextAppearance.AppCompat" />
<SeekBar
android:id="#+id/sample_rate_seek_bar"
android:layout_width="303dp"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignStart="#+id/summary"
android:layout_marginTop="40dp" />
<TextView
android:id="#+id/progress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignStart="#+id/summary"
android:layout_marginTop="66dp"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginTop="96dp"
android:background="#dbdbdd" />
</RelativeLayout>
As far as I was aware, SavedInstanceState only stores a Bundle of data. Only basic things such as Strings, Integers etc. and does not hold anything like Views.
I think you should really use a ViewModel as it can hold data such as custom classes and views and keep them during orientations changes and are only lost once the Activity is destroyed.
Android View Models
You can then code in a more "permanent" storage option say using SharedPreferences, files, sqlite when the Activity is destroyed. The persisted data can then be fetched and populate the ViewModel in the onAttatch method.
Maybe have a read of this to determine your requirements:
Android - Saving UI states.

EdittextPreference to set custom TextView

I have a TextView on my MainActivity which is a welcome text, it has a condition that if the user of my application has not set a username, it would only display "welcome" and if the user already sets their username, it would display the "welcome" text plus their username which has already assigned.
I am using the EdittextPreference & SharedPreference in this cause
the problem is, even the username has been set, it seems it is has not been set, because it doesn't trigger the if else condition i wrote between MainActivity & Settings, it still display the only "welcome" text.
I need some clue here..
my MainActivity.java >> https://paste.ubuntu.com/p/2n33ZzVkY4/
my Settings.java >> https://paste.ubuntu.com/p/JBWSqJfmG6/
you need to save there data in share preference and check if any data exist in share preference then display welcome + its user name both
You are saving the data on SharedPreferences.
You should use below code to get the data from sharedPreferences.
SharedPreferences sharedPreference = PreferenceManager.getDefaultSharedPreferences(this);
String userName = sharedPreference.getString("username", "");
Try the following complete example:
1) DemoActivity.class--------
public class DemoActivity extends AppCompatActivity{
private TextView tv;
private SharedPreferences demo_preferences;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.demo_activity);
demo_preferences = getSharedPreferences("demo_preference",
0);
tv = (TextView) findViewById(R.id.tv);
if(demo_preferences != null) {
String usn = demo_preferences.getString("username", "");
if (usn.isEmpty()) {
tv.setText("Welcome");
} else {
tv.setText("Welcome " + usn);
}
}else{
tv.setText("Welcome");
}
}
#Override
protected void onResume() {
super.onResume();
if(demo_preferences != null) {
String usn = demo_preferences.getString("username", "");
if (usn.isEmpty()) {
tv.setText("Welcome");
} else {
tv.setText("Welcome " + usn);
}
}else{
tv.setText("Welcome");
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.demo_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()) {
case R.id.menu_settings:
Intent i = new Intent(DemoActivity.this , PrefDemoActivity.class);
startActivity(i);
break;
default:
throw new RuntimeException("unknown menu selection");
}
return true;
}
}
2) PrefDemoActivity:-------
public class PrefDemoActivity extends AppCompatActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FragmentManager mFragmentManager = getFragmentManager();
FragmentTransaction mFragmentTransaction = mFragmentManager
.beginTransaction();
DemoEditPreferences mDemoPrefsFragment = new DemoEditPreferences();
mFragmentTransaction.replace(android.R.id.content, mDemoPrefsFragment);
mFragmentTransaction.commit();
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
3) DemoEditPreferences:---------
public class DemoEditPreferences extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener{
private SharedPreferences demo_preferences;
private int preferencesToEdit;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
demo_preferences = getActivity().getSharedPreferences("demo_preference",
0);
preferencesToEdit = R.xml.demo_preferences;
String preferenceName = getResources().getString(R.string.pref_sensor_key);
PreferenceManager preferenceManager = getPreferenceManager();
preferenceManager.setSharedPreferencesName(preferenceName);
preferenceManager.setSharedPreferencesMode(0);
getActivity().setTitle("Demo Preferences");
addPreferencesFromResource(preferencesToEdit);
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
initSummary(getPreferenceScreen().getPreference(i));
}
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if(findPreference(key) != null) {
if(findPreference(key).getKey().equals("username")) {
if(sharedPreferences.getString("username","").equals("")){
setString("username","");
}else{
setString("username",sharedPreferences.getString("username","----"));
}
}
updatePrefSummary(findPreference(key));
}
}
private void initSummary(Preference p) {
if (p instanceof PreferenceCategory) {
PreferenceCategory pCat = (PreferenceCategory) p;
for (int i = 0; i < pCat.getPreferenceCount(); i++) {
initSummary(pCat.getPreference(i));
}
} else {
updatePrefSummary(p);
}
}
private void updatePrefSummary(Preference p) {
if (p instanceof EditTextPreference) {
EditTextPreference editTextPref = (EditTextPreference) p;
p.setSummary(editTextPref.getText());
}
}
public void setString(String preferenceName, String value)
{
SharedPreferences.Editor editor = demo_preferences.edit();
editor.putString(preferenceName, value);
editor.apply();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
view.setBackgroundColor(getResources().getColor(android.R.color.white));
return view;
}
#Override
public void onResume() {
super.onResume();
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
public void onPause() {
super.onPause();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onDestroy() {
super.onDestroy();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
}
4) demo_activity.xml:------
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Welcome"
android:id="#+id/tv"
android:gravity="center"
android:background="#android:color/holo_blue_light"/>
5) demo_menu.xml---------------
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="#+id/menu_settings"
android:title="Settings"
android:titleCondensed="Settings"
android:orderInCategory="1">
</item>
</menu>
6) demo_preferences:---------
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="Demo">
<EditTextPreference
android:key="username"
android:title="UserName"
android:defaultValue="----"
android:summary="----"
android:selectAllOnFocus="true"
android:singleLine="true">
</EditTextPreference>
</PreferenceCategory>
</PreferenceScreen>
7) Don't forget to add both activities to the manifest.

How to get toolbar in my PreferenceActivity

I've been trying to get a Toolbar to show up in my PreferenceActivity following the answer from Gabor using AppCompatPreferenceActivity shown here: Creating a Preference Screen with support (v21) Toolbar . However I can not get it to work. my code:
Settings.java:
public class Settings extends AppCompatPreferenceActivity{
#Override
public void onBuildHeaders(List<Header> target) {
loadHeadersFromResource(R.xml.preferences, target);
setContentView(R.layout.settings_page);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar bar = getSupportActionBar();
bar.setHomeButtonEnabled(true);
bar.setDisplayHomeAsUpEnabled(true);
bar.setDisplayShowTitleEnabled(true);
bar.setHomeAsUpIndicator(R.drawable.abc_ic_ab_back_mtrl_am_alpha);
bar.setTitle("Test2");
}
#Override
protected boolean isValidFragment(String fragmentName) {
return MyPreferenceFragment.class.getName().equals(fragmentName);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
onBackPressed();
break;
}
return super.onOptionsItemSelected(item);
}
public static class MyPreferenceFragment extends PreferenceFragment
{
#Override
public void onCreate(final Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Preference removeMedalsButton = findPreference("removeMedals");
removeMedalsButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Toast.makeText(getActivity(),"Medailles verwijderd",Toast.LENGTH_SHORT).show();
removeMedals(getActivity());
return true;
}
});
Preference removeWorkoutsButton = findPreference("removeWorkouts");
removeWorkoutsButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Toast.makeText(getActivity(),"Workouts verwijderd",Toast.LENGTH_SHORT).show();
removeWorkouts();
return true;
}
});
Preference removeProfileButton = findPreference("removeProfile");
removeProfileButton.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
Toast.makeText(getActivity(),"Profiel verwijderd",Toast.LENGTH_SHORT).show();
removeProfile();
return true;
}
});
}
}
public static void removeMedals(Context context){
AchievementTracker.removeMedals(context);
}
public static void removeWorkouts(){
}
public static void removeProfile(){
}
}
settings_page.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="0dp"
android:orientation="vertical"
android:padding="0dp">
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="#style/ToolbarTheme"/>
<ListView
android:id="#id/android:list"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
preference.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:title="#string/reminder_preference"
android:defaultValue="false"
android:summary="#string/reminder_preference_summary"
android:key="reminderPreference" />
<Preference android:title="#string/remove_medals"
android:key="removeMedals"
android:summary="#string/remove_medals_summary"/>
<Preference android:title="#string/remove_profile"
android:key="removeProfile"
android:summary="#string/remove_profile_summary"/>
<Preference android:title="#string/remove_workouts"
android:key="removeWorkouts"
android:summary="#string/remove_workouts_summary"/>
</PreferenceScreen>
The error i'm getting is:
XML document must start with <preference-headers> tag; foundPreferenceScreen at Binary XML file line #2
I think it's because i'm calling setContentView(R.Layout.settings_page) but that's how i'm supposed to do this according to Gabor's answer.

Access EditText Preference dialog box

I'm confused on where I should I place this code using sharedPreferences. I'm trying to find out how the dialog box gets created. I want to access the EditTextPreference dialog box and once the user inputs their name I want to save it to a file using this code below
SharedPreferences mySharedPreferences = getSharedPreferences("MyData",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putString("user_name",userName.getText().toString());
editor.commit();
Here is my main activity
public class MainActivity extends AppCompatActivity {
EditText userName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
Button myButton = (Button) findViewById(R.id.show_button_id);
myButton.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View view){
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
Intent i = new Intent(MainActivity.this,UserPreferenceActivity.class);
startActivity(i);
//return true;
}
return super.onOptionsItemSelected(item);
}
}
Here is my UserPreferenceFragment java class
public class UserPreferenceFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
//LOAD THE PRFERENCE FROM AN XML RESOURCE FILE
addPreferencesFromResource(R.xml.preferences);
}//ends OnCreate
}
here is my UserPreferenceActivity java class
public class UserPreferenceActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
/*
setContentView(R.layout.content_main);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
ft.
*/
getFragmentManager().beginTransaction()
.replace(android.R.id.content,new UserPreferenceFragment())
.commit();
}
here is my preferences xml file
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="show_background_pic"
android:title="#string/show_background_pic_title"
android:summary="#string/show_background_pic_summary"
android:defaultValue="true">
</CheckBoxPreference>
<EditTextPreference
android:key="user_name"
android:title="#string/user_acct_name_title"
android:summary="#string/user_acct_name_summary"
android:defaultValue="NONAME">
</EditTextPreference>
Lastly my main content
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:showIn="#layout/activity_main">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="#string/Shared_preferences_label"
android:id="#+id/textView"
android:layout_alignParentTop="true"
android:layout_alignParentStart="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/show_button_label"
android:id="#+id/show_button_id"
android:layout_below="#+id/textView"
android:layout_alignParentStart="true" />
</RelativeLayout>
Using setOnPreferenceChangeListener method of Preference class and Preference.OnPreferenceChangeListener interface. something like this:
pref_general.xml:
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference
android:capitalize="words"
android:defaultValue="#string/pref_default_display_name"
android:inputType="textCapWords"
android:key="#string/key_example_text"
android:maxLines="1"
android:selectAllOnFocus="true"
android:singleLine="true"
android:title="#string/pref_title_display_name" />
</PreferenceScreen>
SettingPreferenceFragment.java:
public class SettingPreferenceFragment extends PreferenceFragment {
public final String TAG = "SettingActivity";
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = super.onCreateView(inflater, container, savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
EditTextPreference location = (EditTextPreference) findPreference("example_text");
location.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
String locstr = newValue.toString();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("example_text", locstr);
editor.commit();
Log.e(TAG, "" + locstr);
return true;
}
});
return view;
}
}

Toolbar is hidden in nested PreferenceScreen

I use PreferenceFragment in ActionBarActivity from support-v7 library.
In the Activity I have Toolbar. Everything goes okay, until I open a nested PreferenceScreen.
In the opened screen the Toolbar is hidden.
Maybe somebody know a workaround for this issue?
Preferences xml-file:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Main category" >
<EditTextPreference
android:defaultValue="defaultValue"
android:key="key_global_setting"
android:title="Global title" />
</PreferenceCategory>
<PreferenceCategory android:title="Nested screens" >
<PreferenceScreen
android:persistent="false"
android:title="#string/settings_facility_title" >
<CheckBoxPreference
android:defaultValue="false"
android:key="nested_screen_1_1"
android:title="Nested screen 1.1 check box" />
<CheckBoxPreference
android:defaultValue="true"
android:key="nested_screen_1_2"
android:title="Nested screen 1.2 check box" />
</PreferenceScreen>
<PreferenceScreen
android:persistent="false"
android:title="#string/settings_menu_screen_title" >
<CheckBoxPreference
android:defaultValue="true"
android:key="nested_screen2"
android:title="Nested screen 2 check box" />
</PreferenceScreen>
</PreferenceCategory>
</PreferenceScreen>
Activity layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SettingsScreen" >
<android.support.v7.widget.Toolbar
android:id="#+id/toolbar"
style="#style/Toolbar" />
<FrameLayout
android:id="#+id/contentSettings"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I found the solution on my own. I used a small work-around of all this nested PreferenceScreen's. I simply made a separation to different xml-preference files, created an additional Fragment which extends PreferenceFragment and there I show an appropriate nested preference screen.
Maybe somebody would found this useful.
Github sources link.
Some code examples below:
main_preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory android:title="Main category" >
<EditTextPreference
android:defaultValue="defaultValue"
android:key="key_global_setting"
android:title="Global title" />
</PreferenceCategory>
<PreferenceCategory android:title="Nested screens" >
<Preference
android:key="NESTED_KEY1"
android:persistent="false"
android:title="Nested screen #1" />
<Preference
android:key="NESTED_KEY2"
android:persistent="false"
android:title="Nested screen #2" />
</PreferenceCategory>
</PreferenceScreen>
nested_screen1_preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Nested screen #1" >
<CheckBoxPreference
android:defaultValue="false"
android:key="nested_screen_1_1"
android:title="Nested screen 1.1 check box" />
<CheckBoxPreference
android:defaultValue="true"
android:key="nested_screen_1_2"
android:title="Nested screen 1.2 check box" />
</PreferenceScreen>
nested_screen2_preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Nested screen #2">
<CheckBoxPreference
android:defaultValue="true"
android:key="nested_screen2"
android:title="Nested screen 2 check box" />
</PreferenceScreen>
SettingsActivity.java
public class SettingsActivity extends ActionBarActivity implements MyPreferenceFragment.Callback {
private static final String TAG_NESTED = "TAG_NESTED";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
if (toolbar != null) {
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.contentSettings, new MyPreferenceFragment())
.commit();
}
}
#Override
public void onBackPressed() {
// this if statement is necessary to navigate through nested and main fragments
if (getFragmentManager().getBackStackEntryCount() == 0) {
super.onBackPressed();
} else {
getFragmentManager().popBackStack();
}
}
#Override
public void onNestedPreferenceSelected(int key) {
getFragmentManager().beginTransaction().replace(R.id.contentSettings, NestedPreferenceFragment.newInstance(key), TAG_NESTED).addToBackStack(TAG_NESTED).commit();
}
}
MyPreferenceFragment.java
// The main preference fragment class
public class MyPreferenceFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener {
private Callback mCallback;
private static final String KEY_1 = "NESTED_KEY1";
private static final String KEY_2 = "NESTED_KEY2";
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (activity instanceof Callback) {
mCallback = (Callback) activity;
} else {
throw new IllegalStateException("Owner must implement Callback interface");
}
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.main_preferences);
// add listeners for non-default actions
Preference preference = findPreference(KEY_1);
preference.setOnPreferenceClickListener(this);
preference = findPreference(KEY_2);
preference.setOnPreferenceClickListener(this);
}
#Override
public boolean onPreferenceClick(Preference preference) {
// here you should use the same keys as you used in the xml-file
if (preference.getKey().equals(KEY_1)) {
mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_1_KEY);
}
if (preference.getKey().equals(KEY_2)) {
mCallback.onNestedPreferenceSelected(NestedPreferenceFragment.NESTED_SCREEN_2_KEY);
}
return false;
}
public interface Callback {
public void onNestedPreferenceSelected(int key);
}
}
NestedPreferencesFragment.java
public class NestedPreferenceFragment extends PreferenceFragment {
public static final int NESTED_SCREEN_1_KEY = 1;
public static final int NESTED_SCREEN_2_KEY = 2;
private static final String TAG_KEY = "NESTED_KEY";
public static NestedPreferenceFragment newInstance(int key) {
NestedPreferenceFragment fragment = new NestedPreferenceFragment();
// supply arguments to bundle.
Bundle args = new Bundle();
args.putInt(TAG_KEY, key);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPreferenceResource();
}
private void checkPreferenceResource() {
int key = getArguments().getInt(TAG_KEY);
// Load the preferences from an XML resource
switch (key) {
case NESTED_SCREEN_1_KEY:
addPreferencesFromResource(R.xml.nested_screen1_preferences);
break;
case NESTED_SCREEN_2_KEY:
addPreferencesFromResource(R.xml.nested_screen2_preferences);
break;
default:
break;
}
}
}
Here comes my solution, which is inspired by the original answer but not that complicated. Maybe it'll help someone...
layout/settings.xml:
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
layout="#layout/toolbar" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content"
android:layout_below="#+id/toolbar"/>
</RelativeLayout>
Classes:
public class SettingsActivity extends ActionBarActivity {
#Override
protected void onCreate( Bundle savedInstanceState ) {
setContentView( R.layout.settings );
super.onCreate( savedInstanceState );
initializeSupportActionBar();
getFragmentManager().beginTransaction().replace( R.id.content, new MainFragment() ).commit();
}
#Override
public void onBackPressed() {
if( !getFragmentManager().popBackStackImmediate() ) super.onBackPressed();
}
}
public class MainFragment extends PreferenceFragment {
public MainFragment() {}
#Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
addPreferencesFromResource( R.xml.pref_main );
// "nested" is the <Preference android:key="nested" android:persistent="false"/>`
findPreference( "nested" ).setOnPreferenceClickListener( new OnPreferenceClickListener() {
#Override public boolean onPreferenceClick( Preference preference ) {
getFragmentManager().beginTransaction().replace( R.id.content, new NestedFragment() ).addToBackStack( NestedFragment.class.getSimpleName() ).commit();
return true;
}
} );
}
public class NestedFragment extends PreferenceFragment {
...
}
I tested it on 4.3 and 5.0.2 and no limitation on nesting levels applies
In my solution you only need one AppCompatActivity and one PreferenceFragement, but several XML files, each having only one level of PreferenceScreens.
XML file list
top level PreferenceScreen
second level PreferenceScreen 0
second level PreferenceScreen 1
second level PreferenceScreen 2
...
This code is for one sub-level (for simplicity and to get the idea), but you can easily extend it to have arbitrary sub-levels of PreferenceScreens.
SettingsFragment.java
public class SettingsFragment extends PreferenceFragment
{
private int xmlId;
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
xmlId = R.xml.preferences;
addPreferencesFromResource(xmlId);
}
public void changePrefScreen(int xmlId, int titleId)
{
this.xmlId = xmlId;
((AppCompatActivity)getActivity()).getSupportActionBar().setTitle(getActivity().getResources().getString(titleId));
getPreferenceScreen().removeAll();
addPreferencesFromResource(xmlId);
}
// will be called by SettingsActivity (Host Activity)
public void onUpButton()
{
if(xmlId == R.xml.preferences) // in top-level
{
// Switch to MainActivity
Intent intent = new Intent(getActivity(), MainActivity.class);
startActivity(intent);
}
else // in sub-level
{
changePrefScreen(R.xml.preferences, R.string.settings);
}
}
#Override
public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference preference)
{
String key = preference.getKey();
//
// Top level PreferenceScreen
//
if(key.equals("top_key_0"))
{
changePrefScreen(R.xml.download_preference_screen, R.string.download_database); // descend into second level
}
// ...
//
// Second level PreferenceScreens
//
if (key.equals("second_level_key_0"))
{
// do something...
}
// ...
}
SettingsActivity.java
public class SettingsActivity extends AppCompatActivity
{
SettingsFragment settingsFragment;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
settingsFragment = new SettingsFragment();
// Display the fragment as the main content.
getFragmentManager().beginTransaction()
.replace(android.R.id.content, settingsFragment)
.commit();
}
//
// Handle what happens on up button
//
#Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
settingsFragment.onUpButton();
return true;
}
return true;
}
// ...
}
Technically it should work for all Android versions for which the PreferenceFragment is available.
As the issue comes from the part that you are still in the same activity/fragment and the nested pref screen is just a dialog you can do the following:
You can set preference click listener
Get the root view from the dialog:
(PreferenceScreen)preference).getDialog().getWindow()
.getDecorView().getRootView());
Recursively search until find a stub view (there is one, unfortunately I do not know the android.R.id.xxxxx) and set what layout you need as title which will look like the toolbar(You can inflate toolbar):
private Toolbar toolbar;
public void findViewStub(ViewGroup viewGroup) {
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View childView = viewGroup.getChildAt(i);
if( childView instanceof ViewStub){
((ViewStub)childView).setLayoutResource(R.layout.your_title_layout);
toolbar = ((ViewStub)childView).inflate();
}
if (childView instanceof ViewGroup) {
findViewStub((ViewGroup) childView);
}
}
}
toolbar.setNavigationIcon();
toolbar.setNavigationOnClickListener();
toolbar.setTitle();
In the layout you can put only a toolbar. And set the back icon. Register for click on it and having reference to the fragment, on click you can dismiss the dialog. You have set title and etc.

Categories

Resources