I have a EditText in a preference menu that allows me to edit a URL address. The problem is when I get the preference value in the mainActivity is not getting updated right away after I click OK in the Preference Menu. Not sure how to fix this problem. I tried a bunch of ideas and finally decided to ask.
public class PreferencesActivityTest extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.radio_preferences);
PreferenceManager.setDefaultValues(PreferencesActivityTest.this,
R.xml.radio_preferences, false);
EditTextPreference editPref =(EditTextPreference)findPreference("MyText");
editPref.setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
if (newValue.toString().length() > 0) {
return true;
}
// If now create a message to the user
Toast.makeText(PreferencesActivityTest.this,
"Invalid Input", Toast.LENGTH_SHORT).show();
return false;
}
});
}
}
PS: This code updates the newValue to what I enter in the EditTextPreference, doesn't carry the new value to the MainActivity until I modify it again...
UPDATE:
In OnResume() I can see that the value is updated with the one that I modified in the PreferenceActivityTest from EditTextPreference. What I'm trying to do is to pass this newValue into the SetDataSource("").
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_radio);
initializeMediaPlayer();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_edit:
editURL();
// make a Dialog or show an Activity
return true;
}
}
private void initializeMediaPlayer() {
PreferenceManager.setDefaultValues(this, R.xml.radio_preferences, false);
SharedPreferences pref =PreferenceManager.getDefaultSharedPreferences(this);
String radioPath = pref.getString("MyText", "default value");
// Toast.makeText(this, radioPath, Toast.LENGTH_SHORT).show();
try {
radioPlayer.reset();
// radioPlayer.setDataSource("http://31.xx.xxx");
// Toast.makeText(this, radioPath, Toast.LENGTH_SHORT).show();
radioPlayer.setDataSource(radioPath);
} catch {
}
}
public void editURL() {
stopPlaying();
startActivity(new Intent(getBaseContext(), PreferencesActivityTest.class));
}
I am doing something fundamentally wrong but I need help. Thank you in advance !
how are you calling the preference activity? If you are calling it directly, you probably need to change the call to startActivityForResult so you refresh your data once you return from the Activity
Related
I want to change the theme of my app by a switch button. There is no problem and the theme changes into dark or light as I hit the button. on the other hand, I want to change the background image as the theme changes in different activities. I mean the MainActivity has an image background and other activities have their own background image. I would be very grateful if there is a guy to help me.
this is my code:
private Switch mySwitch;
#Override
protected void onCreate(Bundle savedInstanceState) {
if(AppCompatDelegate.getDefaultNightMode() ==
AppCompatDelegate.MODE_NIGHT_YES){
setTheme(R.style.darkTheme);
}
else {setTheme(R.style.AppTheme);
}
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySwitch = (Switch) findViewById(R.id.my_switch);
if(AppCompatDelegate.getDefaultNightMode() ==
AppCompatDelegate.MODE_NIGHT_YES){
mySwitch.setChecked(true);
}else {
}
mySwitch.setOnCheckedChangeListener(new
CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b)
{
if(b){AppCompatDelegate.setDefaultNightMode
(AppCompatDelegate.MODE_NIGHT_YES);
restartApp();
}
else {
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
restartApp();
}
}
});
}
public void restartApp(){
Intent i = new Intent(getApplicationContext(), MainActivity.class);
startActivity(i);
finish();
}
}
Saving content in sharedPref
private SharedPreferences mSharedPreferences;
public SharedCache(SharedPreferences sharedPreferences) {
mSharedPreferences = sharedPreferences;
}
public String getThemeName() {
return mSharedPreferences.getString(THEME_NAME, APP_DARK);
}
public void setThemeName(#NonNull String theme) {
mSharedPreferences.edit().putString(THEME_NAME, theme).apply();
}
Here AppDark is my current theme name , you can set your theme name onChange of your theme .
In Activity onCreate method , get the theme from sharedPref . Or you can follow the below link for better understanding on sharedPreference . https://medium.com/android-grid/android-sharedpreferences-example-writing-and-reading-values-7a677f4448c3
I have a simple program that changes the background of activity A from activity B.
When you change the background you need to refresh activity A in order for the background to change, after looking around stackoverflow the easiest way was just to call recreate().
I'm not sure if im calling it wrong or in the wrong area but what ends up happening is it will loop the following error when the app is run and eventually crash-
02-01 13:23:53.358 17302-17302/com.package.www.randomapp E/ViewRootImpl: sendUserActionEvent() mView == null
Here's the code for activity A
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mainmenu);
backgroundChanger();
recreate();
}
public void backgroundChanger(){
SharedPreferences sharedGradients = getSharedPreferences("gradientInfo", Context.MODE_PRIVATE);
int backgroundGrad = sharedGradients.getInt("backgroundGradient", 0);
if (backgroundGrad == 0){
MMBackground.setBackgroundResource(R.drawable.blackgreengradiant);
}
if (backgroundGrad == 1){
MMBackground.setBackgroundResource(R.drawable.blueblackgradiant);
}
if (backgroundGrad == 2){
MMBackground.setBackgroundResource(R.drawable.goldblackgradiant);
}
and for Activity B
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_options_menu);
variableHandler();
}
public void variableHandler() {
MainMenuBackgroundBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
final SharedPreferences[] sharedGradients = {getSharedPreferences("gradientInfo", Context.MODE_PRIVATE)};
final SharedPreferences.Editor[] editor1 = {sharedGradients[0].edit()};
final SharedPreferences[] sharedBoolean = {getSharedPreferences("binaryPoint", Context.MODE_PRIVATE)};
final SharedPreferences.Editor[] editorBinary = {sharedBoolean[0].edit()};
final PopupMenu popup = new PopupMenu(getApplicationContext(), v);
popup.inflate(R.menu.menu_background_gradiant_setter);
popup.show();
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.item1:
Toast.makeText(OptionsMenu.this, "Blue and black gradient", Toast.LENGTH_SHORT).show();
editorBinary[0] = sharedBoolean[0].edit();
editorBinary[0].putInt("binaryPoint", 1);
editor1[0] = sharedGradients[0].edit();
editor1[0].putInt("backgroundGradient", 1);
editor1[0].apply();
return true;
case R.id.item2:
Toast.makeText(OptionsMenu.this, "Gold and black gradient", Toast.LENGTH_SHORT).show();
editorBinary[0] = sharedBoolean[0].edit();
editorBinary[0].putInt("binaryPoint", 1);
editor1[0] = sharedGradients[0].edit();
editor1[0].putInt("backgroundGradient", 2);
editor1[0].apply();
return true;
}
}
The problem is that you are calling recreate() in the onCreate() method of the Activity without any condition which will create an infinite loop. Keep a variable to track whether the activity is recreated or not.
private static boolean alreadyRecreated = false;
//You can add some extra conditions here if you want.
if(!alreadyRecreated){
recreate();
alreadyRecreated = true;
}
recreate(); will cause your activity to be recreated.
i.e, onCreate gets called. Since, you added recreate(); in onCreate method, it is running into infinite loop and crashing.
I have two activities. In the second activity I have a spinner. what I would like to happen is after the user selects an item from the spinner it will save via actionbar press and on back press which will load the previous activity. Based on my research my activity is supposed to look something like the following below but it's not working what am I doing wrong??
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit);
getActionBar().setDisplayHomeAsUpEnabled(true);
spin = (Spinner)findViewById(R.id.editspin);
Intent i = this.getIntent();
note = new ArgueItem();
note.setKey(i.getStringExtra("key"));
note.setText(i.getStringExtra("text"));
EditText et = (EditText)findViewById(R.id.argueEdit);
et.setText(note.getText());
et.setSelection(note.getText().length());
}private boolean saveState() {
prefs = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor prefEditor = prefs.edit();
int daddy = spin.getSelectedItemPosition();
prefEditor.putInt("savedValue",daddy);
prefEditor.commit();
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
EditText et = (EditText)findViewById(R.id.argueEdit);
String argueText = et.getText().toString();
if(argueText.equals("")){
Toast.makeText(this, "Please Enter A New ", Toast.LENGTH_SHORT).show();
return false;
}
if (item.getItemId() == android.R.id.home) {
saveAndFinish();
}
return false;
}
#Override
public void onBackPressed() {
EditText et = (EditText)findViewById(R.id.argueEdit);
String argueText = et.getText().toString();
if(argueText.equals("")){
Toast.makeText(this, "Please Enter A New ", Toast.LENGTH_SHORT).show();
return;
}else{
saveAndFinish();
}
In your second activity, you have to override the onPause() and. Inside it write the saving process.
protected void onPause(){
super.onPause();
//Include the code which, save the data.
}
You should use a FragmentActivity and add/remove fragments within the same activity.
check these resources:
http://developer.android.com/guide/components/fragments.html
http://www.vogella.com/articles/AndroidFragments/article.html
This is how i'm initializing my spinner which is in the ActionBar. I'm not adding it as a custom view, but I'm using the drop down menu feature.
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
actionBar.setListNavigationCallbacks(adapter, new ActionBar.OnNavigationListener() {
#Override
public boolean onNavigationItemSelected(int itemPosition, long itemId) {
//save in preferences
PreferenceManager.getDefaultSharedPreferences(MainActivity.this).edit().
putInt(SELECTED_DIARY_PREF, itemPosition).commit();
return true;
}
});
int selPosition = PreferenceManager.getDefaultSharedPreferences(this).getInt(SELECTED_DIARY_PREF, 0);
actionBar.setSelectedNavigationItem(selPosition);
What this code does is: saving the preference when an item of the menu is clicked, and restoring that preference when the activity is launched. Hope it helps.
I want to detect when the value from the NumberPicker is changed. I have this code on my PreferenceActivity:
public class MainPrefs extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.addPreferencesFromResource(R.xml.main_preferences);
this.findPreference("SMSSentLimit").setOnPreferenceChangeListener(
new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
TrackerService.updateStats(Long.decode(newValue.toString()));
return true;
}
});
this.findPreference("NumberPickerLimit").setOnPreferenceChangeListener(
new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference,
Object newValue) {
Log.i("onPreferenceChange", "NumberPicker Changed");
Toast.makeText(getBaseContext(), "CHANGEEEED !!!",
Toast.LENGTH_SHORT).show();
return true;
}
});
}
}
The second one (findPreference("NumberPickerLimit")) is the NumberPicker and it is never called, if I change it to onPreferenceClickListener it works but I detect when I click the preference instead when I change the value.
Acording to source code it should be called:
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case DialogInterface.BUTTON_POSITIVE:
saveValue(mPicker.getCurrent());
break;
default:
break;
}
}
private void saveValue(int val) {
getEditor().putInt(getKey(), val).commit();
notifyChanged();
}
What´s happening? Is it a bug?
EDIT
Here is my XML:
<com.michaelnovakjr.numberpicker.NumberPickerPreference
android:key="NumberPickerLimit"
android:title="#string/NumberPickerTitle"
android:summary="#string/NumberPickerSummary"
picker:defaultValue="1"
picker:startRange="1"
picker:endRange="31" />
Just looked at your xml file listed here, looks like you have android:key="demo.preference" there. Whereas in the code here, you're using findPreference("NumberPickerLimit").
You have to call the listener yourself. Instead of notifyChanged(), try callChangeListener(val) as seen here:
NumberPickerPreference
I have four checkboxpreferences in my preferencescreen that I would like to interact like a radiobuttongroup, meaning that you can only check one of them! If lets say the first is checked, and you like to check another one, its just the desired one checked, and the other ones is unchecked.
I did like this :
public class PreferenceActivity extends PreferenceActivity {
private SharedPreferences prefs;
private Editor editor;
private int keyItemChecked;
private CheckBoxPreference item1CheckBox, item2CheckBox, ..., itemICheckBox;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
addPreferencesFromResource(R.xml.prefs);
item1CheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("item1");
item2CheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("item2");
...
itemICheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("itemI");
item1CheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
manageItem(1, item1CheckBox);
return true;
}
});
....
itemICheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
manageItem(I, itemICheckBox);
return true;
}
});
}
private void manageItem(int i ,CheckBoxPreference pref) {
keyItemChecked = prefs.getInt("keyItemChecked",1); // 1 is your default checked item
if (! pref.isChecked() && keyItemChecked == i)
// If you click on the checked item, you don't want it to be unchecked :
pref.setChecked(true);
if (pref.isChecked() && keyItemChecked != i) {
editor = prefs.edit();
editor.putInt("keyItemChecked", i);
editor.commit(); // or editor.apply() if you use API > 9
unckeckOldItem(keyItemChecked);
}
}
private void unckeckOldItem(int item) {
switch (item) {
case 1:
item1CheckBox.setChecked(false);
break;
...
case I:
itemICheckBox.setChecked(false);
break;
}
}
You don't need to declare "keyItemChecked" on your prefs.xml.
The first time you call the activity, the data doesn't exist and
keyItemChecked = prefs.getInt("keyItemChecked",1);
will return 1.
Once you click on an other item than the default, the data will exist.
Looks like you can use http://developer.android.com/reference/android/preference/CheckBoxPreference.html#setDisableDependentsState%28boolean%29 to create that functionality. I think setting dependency of preferences can be done in xml.