Access SharedPreferences that are edited in a PreferenceFragment under another Activity - android

I have one main activity with multiple Fragments. From the menu, the user can go to a new activity which contains the PreferenceFragment:
Preference Activity and Fragment:
public class SettingsActivity extends FragmentActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.options_screen);
}
/**
* This fragment shows the preferences for the first header.
*/
public static class Prefs1Fragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.pref_options);
}
}
}
Preferences xml file:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="#string/pref_cat_display">
<ListPreference
android:key="pref_key_display_units"
android:title="#string/pref_title_units"
android:summary="#string/pref_summary_units"
android:entries="#array/entries_list_units"
android:entryValues="#array/entryvalues_list_units"
android:dialogTitle="#string/pref_dialog_title_list_units"
android:defaultValue="0"/>
</PreferenceCategory>
</PreferenceScreen>
Layout:
<?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"
android:id="#+id/settings_content"
android:paddingTop="?android:attr/actionBarSize">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.cs.biodyapp.usl.activity.SettingsActivity$Prefs1Fragment"
android:id="#+id/fragment" />
</LinearLayout>
Once the option has been initialized, I try to access to this preference from the original Activity but I always get an empty Map in the SharedPreferences object.
I tried many ways that supposely let you access preferences form a different activity or directly from the file but no chance:
//SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
SharedPreferences sharedPref = getActivity().getApplication().getSharedPreferences("pref_options", Context.MODE_PRIVATE);
int units = sharedPref.getInt("pref_key_display_units", 0);

SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
Is the correct line to use ( getting the application context and not the base context ).
I also detected a problem in using ListPreference with integer arrays in a PreferenceFragment. Finally I had to use string arrays and sharedPrefs.getString() to then cast it to an integer.

Related

Preference.setLayoutResource(R.layout.my_custom_layout) don't accept OnClickListener

I am trying to set up a simple SettingsFragment with one of the Preference customized with an layout xml and set OnClickListener on this customised Preference. For this moment none of the way work.
What I miss please ?
I have tryed implements of OnPreferenceClickListener and OnPreferenceTreeClickListener but without succes.
This is my delete_btn_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:id="#+id/delete_account_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context="com.example.package.SettingsActivity">
<Button
android:id="#+id/delete_account_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="#dimen/size_b"
android:text="#string/delete_account"
android:textColor="#android:color/white"
android:background="#drawable/background_btn"
android:layout_margin="#dimen/size_s" />
</LinearLayout>
And this is my Preference element in <PreferenceScreen .../>
...
<PreferenceCategory app:title="#string/account_category">
<Preference
app:icon="#drawable/ic_delete_primary_dark_24"
app:key="delete_account"
app:title="#string/delete_account"/>
</PreferenceCategory>
...
And this is my SettingsFragment whit one "...ClickListener" witch don't work
public static class SettingsFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.root_preferences, rootKey);
Preference test = SettingsFragment.this.findPreference("delete_account");
if (test != null) {
test.setLayoutResource(R.layout.delete_btn_layout);
test.setOnPreferenceClickListener(preference -> {
ViewWidgets.showSnackBar(1,getView(),"delete ?");
// do some action
return true;
});
} else {
ViewWidgets.showSnackBar(1,getView(),"Error, Please retray.");
}
}
Any help please.
For those who may encounter a similar problem, I describe the solution that I applied.
The event detection of the click, I inserted in the activity (class SettingsActivity) that holds the SettingsFragment. With the "deleteUserAccount" method which initializes the process:
public void deleteUserAccount(View view) {
openDialog();
}
The referance for this event I inserted in the button in the old way with the "onClick" method:
<Button
android:id="#+id/delete_account_btn"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="#dimen/size_b"
android:text="#string/delete_account"
android:textColor="#android:color/white"
android:background="#drawable/background_google_btn"
android:layout_margin="#dimen/size_s"
android:onClick="deleteUserAccount"/>

Multine line label on settings

I would like to crate a settings Activity with items with Title and subtitle.
I've checked a lot in documentation and even other posts here and people say it's not possible... android default settings page has a lot of it:
sorry for the picture in portuguese, but what is written there doesn't matter, the point is the settings page built on android has plenty of titile/subtitle items (and it happens in many other screens)
I would like to achieve it using android default Preference api. is that possible?
Yes it is possible. One fast solution is the following (that might be improvied and tuned according your needs):
public class SettingsActivity extends Activity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.settings_fragment, new PrefsFragment()).commit();
}
}
public static class PrefsFragment extends PreferenceFragment {
public PrefsFragment(){}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.settings);
}
}
}
activity_settings.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="#+id/settings_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.vb.myapplication.SettingsActivity$PrefsFragment" />
</LinearLayout>
settings.xml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:key="keyCategory"
android:title="titleCategory">
<CheckBoxPreference
android:key="keyCheckPreference"
android:title="titlePreference"
android:summary="summaryPreference"
android:defaultValue="false"/>
</PreferenceCategory>
</PreferenceScreen>

Android PreferenceActivity checkbox

I am trying to get a checkbox to default to True when the app is launched.
I used this answer Android CheckBoxPreference Default Value but it still defaults to false and prints False in LogCat.
Any ideas where I have messed up? I've been looking at this for hours... thanks in advance!
public class Preferences extends PreferenceActivity{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.preferences);
PreferenceManager.setDefaultValues(this, R.layout.preferences, true);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
boolean autoStart = prefs.getBoolean("checkBox1", true);
System.out.println(autoStart);
}
}
XML class:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<PreferenceCategory
android:summary="Username and password information"
android:title="User request" >
<CheckBoxPreference
android:key="checkBox1"
android:title="request details"
android:defaultValue="true"/>
</PreferenceCategory>
</PreferenceScreen>
In Your main activity you could do following:
SharedPreferences prefs = getSharedPreferences("YOUR_PREFERENCES_KEY",false);
boolean isSetToTrue = prefs.getBoolean("YOUR_BOOLEAN_KEY",false);
if(isSetToTrue==false){
//here set your checkBox to true
}
main Activity means the activity that starts first with starting app.

Android Preferenceactivity getView

I have such piece of code :)
And i want to edit text property of my custom preference layout.
But any changes made on object from getView function does not affect actual list in preference screen. any ideas? I know that i cant extend PreferenceScreen, and i cant use any other type of preference in this case, i only want to be able to edit my custom textview from my layout in code.
PreferenceScreen settings = getPreferenceManager().createPreferenceScreen(this);
settings.setLayoutResource(R.layout.mypreference);
View test = (View) settings.getView(null,getListView());
TextView text = (TextView)test.findViewById(R.id.text);
text.setText("BLA BLA");
We should be using getView(convertView, parent) but from countless unanswered questions on StackOverflow, it's obvious no one knows how to use it. So our only option is to create a custom Preference:
Create a new Class:
public class CustomPreference extends Preference {
public CustomPreference(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
protected void onBindView(View rootView) {
super.onBindView(rootView);
View myView = rootView.findViewById(R.id.myViewId);
// do something with myView
}
}
In your xml/preferences.xml, add your custom preference:
<your.package.name.CustomPreference
android:key="custom_preference"
android:layout="#layout/custom_layout" />
Using the custom layout below:
custom_preferences_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<Button
android:id="#+id/preview_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:text="#string/notification_preview" />
<ListView
android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Using the file above with your user preferences xml file, you can do this to access the items in your custom layout:
public class CustomPreferenceActivity extends PreferenceActivity {
#Override
protected void onCreate(Bundle bundle){
super.onCreate(bundle);
addPreferencesFromResource(R.xml.custom_preferences);
setContentView(R.layout.custom_preferences_layout);
}
private void initCustomizePreferences(){
//Button
Button button = (Button)findViewById(R.id.preview_button);
//Do something with the button.
}
}
I hope this helps :)
You need to override onBindView in your custom Preference class.
More details -
Get view of preference with custom layout
I never actually messed with the views of a PreferenceActivity, but here's something I do (usually for ListPreferences)
ListPreference listPref;
CheckBoxPreference cbPref;
// Set the summary as the current listpref value
listPref = (ListPreference) findPreference("list_pref_key");
listPref.setSummary(listPref.getEntry());
// change the title / summary / ??? of any preference
findPreference("anothe_pref_key").setTitle("New Title");
findPreference("anothe_pref_key").setSummary("New subtext for the view");
This way, even if the layout used by PreferenceActivity / PreferenceFragment change in a future version, you wont have to change anything in your code.

how to change the string values of sting.xml file

i hava a layout file like
test.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="#+id/test_string" />
</RelativeLayout>
and java file like this.
test1.java
public class test1 extends Activity {
String temp="This is String"; //which change dynamically
TextView tempview;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
tempview=(TextView)findViewById(R.id.test_string);
tempview.setText(temp);
setContentView(R.layout.test);
}
}
what i am trying to do is show the value of temp in activity as above code. but it throws an NullPointerException. so how to do. how to set the values of sting.xml???
thanks in advance..
setContentView(R.layout.test); should come before (TextView)findViewById(R.id.test_string);

Categories

Resources