I decoupled view from my Activity and I have a separate class for all UI related operations. One operation I want to implement there is to inflate menu for Action Bar. I try doing things like these, but none of it works.
fun displayMenu() {
rootView.toolbar.inflateMenu(R.menu.my_menu)
rootView.toolbar.setOnMenuItemClickListener { item ->
if (item.itemId == R.id.action_one) {
listener.onActionOne()
}
true
}
}
I tried this:
activity.menuInflater.inflate(R.menu.my_menu, rootView.toolbar.menu)
and this:
rootView.toolbar.inflateMenu(R.menu.my_menu)
But none of these gets the job done. How can I inflate this menu?
It was all my silly mistake.
activity.menuInflater.inflate(R.menu.my_menu, rootView.toolbar.menu)
Works perfectly fine. Just remember to call it during or after Activity.onCreateOptionMenu. Complete example to make it works is something like:
public class MyActivity extends AppCompatActivity {
#Inject
MyView myView;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(myView.getRootView());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
myView.displayMenu();
return super.onCreateOptionsMenu(menu);
}
}
public class MyViewImpl implements MyView {
#Override
public void displayMenu() {
activity.getMenuInflater().inflate(
R.menu.categories_modification_menu,
rootView.findViewById(R.id.toolbar).getMenu()
)
}
}
I used displayMenu() from Activity.onCreate before... Sorry for wasting your time, especially I did not post this part as I thought it is irrelevant to the question...
I don't know how to code in Kotlin.
This is how I do in Java. Just Override onCreateOptionsMenu() method in your Activity class.
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.my_menu, menu);
}
Related
I have been trying to find the source of ActionMode memory leak for days now without luck. I have an activity with several fragments and when I leave the fragment having ActionMode (while auto cancelling it), LeakCanary detects a memory leak.
I have nulled both ActionMode and ActionMode.Callback on destroy() and even tried doing it on onDestroyActionMode().
Here is my LeakCanary screenshot:
https://i.imgur.com/RUbdqj3.png
I hope someone points me in the right direction.
P.S. I have suspected it has something to do with ActionMode.Callback. Though, I could not find any methods for the CallBack that destroys it. I start the ActionMode using startSupportActionMode(mActionModeCallback). I have tried to find a method to remove the mActionModeCallback from that, too, but no methods.
Here is my full ActionMode code:
private ActionMode mActionMode;
private ActionMode.Callback mActionModeCallback;
public void startCAB()
{
if (mActionMode == null)
mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(mActionModeCallback);
}
private void buildActionModeCallBack()
{
mActionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_cab, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
... Some Code ...
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
mActionModeCallback = null; // Tried with and without this.
}
};
}
public void finishActionMode()
{
mActionMode.finish();
}
#Override
public void onDestroy()
{
super.onDestroy();
mActionMode = null;
mActionModeCallback = null;
}
Parent Activity containing fragments:
#Override
public void onTabUnselected(TabLayout.Tab tab)
{
clearCAB();
}
private void clearCAB()
{
int index = mPagerAdapter.getCurrentFragmentIndex();
FragmentOne fragmentOne = (FragmentOne) mPagerAdapter.instantiateItem(mViewPager, index);
fragmentOne.finishActionMode();
}
According to my experience, if your ActionMode.Callback object use the Anonymous inner class it may cause your fragment memory leak.
Maybe you can create a new class and implements ActionMode.Callback then use it to put in startSupportActionMode() parameter:
public class YourFragment extends skip implements skip, ActionMode.Callback {
private ActionMode mActionMode;
public void startCAB()
{
if (mActionMode == null)
mActionMode = ((AppCompatActivity) getActivity()).startSupportActionMode(new SafeActionModeCallback(this));
}
public void finishActionMode()
{
mActionMode.finish();
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.menu_cab, menu);
return true;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
// ... Some Code ...
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
}
SafeActionModeCallback:
public class SafeActionModeCallback implements ActionMode.Callback {
// you can also use the WeakReference
private ActionMode.Callback callback;
public SafeActionModeCallback(ActionMode.Callback callback) {
this.callback = callback;
}
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
return callback.onCreateActionMode(mode, menu);
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return callback.onPrepareActionMode(mode, menu);
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
return callback.onActionItemClicked(mode, item);
}
#Override
public void onDestroyActionMode(ActionMode mode) {
callback.onDestroyActionMode(mode);
callback = null;
}
}
It seems the ActionMode in the activity has a reference to the fragment's layout which is causing the memory leak and preventing the fragment from getting GC'ed. I couldn't find a way to remove the reference.
In my use case, I'm using a ListView inside the fragment that was activating the activity's ActionMode (via listener.setMultiChoiceModeListener).
My hacky solution: In the fragment's onDestroyView, remove the listView (or whichever view activated the ActionMode) from the layout and remove all listeners for the list view. I made a kotlin extension method for it:
fun ListView.removeViewAndClearListeners() {
setMultiChoiceModeListener(null)
setOnScrollListener(null)
onItemClickListener = null
(parent as? ViewGroup)?.removeView(this)
}
After doing this, the leak is gone.
I am still wondering why you are relying on ActionMode.Callback. I had an application where I was supposed to create a Custom Menu on long press and I wasted almost 2 months on this issue :
ActionModeCallback does not work
I am not sure If you are aware of this or not, The ActionMode Callback barely works on all devices. After a lot of research, I came to know that devices who are focusing too much on battery consumption and optimization will not let your background services and some callbacks work as expected.
Try testing your code on MI or Oppo/Vivo devices. It will jump directly to onDestroyActionMode instead of calling onActionItemClicked
This question already has answers here:
Android: Best way to share code between activities? [closed]
(2 answers)
Closed 4 years ago.
I have multiple activities sharing the same options menu so in my every activity, I am doing
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent opensettings = new Intent(this, SettingsActivity.class);
startActivity(opensettings);
return true;
case R.id.help:
...others
default:
return super.onOptionsItemSelected(item);
}
}
Is there a way to share the above code amongst different activities?
I have tried adding a class
class MenuHelper{
Context ctx;
public MenuHelper(Context context){
ctx=context
}
public boolean openMenuItems(Menu item){
switch(item.getItemId()) //here .getItemId() doesnt work{
case R.id.settings: //R.id.settings not found
}
}
}
But am stuck in my helper class. How do I proceed so that in my different activities I only have to
MenuHelper menuitems = new MenuHelper(this);
menuitems.openMenuItems(menu)
You can have a BaseActivity where you can put the common implementation across your activities and then have other activities extend the BaseActivity
public class BaseActivity extends AppCompatActivity {
// Any other common methods
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
case R.id.settings:
Intent opensettings = new Intent(this, SettingsActivity.class);
startActivity(opensettings);
return true;
case R.id.help:
...others
default:
return super.onOptionsItemSelected(item);
}
}
}
You can now create your activities extending BaseActivity:
public class MainActivity extends BaseActivity {
}
Why not just create a super class for your common Activities? If you create a super class, like so:
public class MySharedMenuActivity extends Activity {
#Override
public boolean onOptionsItemSelected(MenuItem item) { ... }
}
Then, if you extend that class for the activities you want, you will be able to access the shared menu.
Inheritance
As the other responses suggest, you could use inheritance to provide this sort of functionality. That does break the "favor composition over inheritance rule", but may be the practical solution for simple applications.
Composition
I think you are on the right path with creating a "menu helper" of sorts. I'd prefer a name such as OptionsMenuHandler and would probably write it like this:
public class OptionsMenuHandler {
private final Activity activity;
public OptionsMenuHandler(Activity activity) {
this.activity = activity;
}
public boolean onCreateOptionsMenu(Menu menu) {
// do menu inflation here.
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent openSettings = new Intent(activity, SettingsActivity.class);
activity.startActivity(openSettings);
return true;
case R.id.help:
// others
default:
return false;
}
}
public boolean onPrepareOptionsMenu(Menu menu) {
// do menu preparation here.
}
}
and use it like this:
public class TestActivity extends AppCompatActivity {
private final OptionsMenuHandler optionsMenuHandler = new OptionsMenuHandler(this);
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return optionsMenuHandler.onCreateOptionsMenu(menu) ||
super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return optionsMenuHandler.onPrepareOptionsMenu(menu) ||
super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return optionsMenuHandler.onOptionsItemSelected(item) ||
super.onOptionsItemSelected(item);
}
}
This does require extra boiler plate in each Activity. It also creates abstraction. The abstraction is justified because it keeps the code DRY. I also like the fact that business logic isn't tucked away and invisible inside a parent class somewhere... the composition makes the location of the business logic a lot more obvious.
Base Activity that Supports Composition
Another option would be to support composition in a base Activity as follows...
Create a well defined abstraction:
public interface OptionsMenuHandler {
boolean onCreateOptionsMenu(Menu menu);
boolean onOptionsItemSelected(MenuItem item);
boolean onPrepareOptionsMenu(Menu menu);
}
Create an implementation for the abstraction:
public class DefaultOptionsMenuHandler implements OptionsMenuHandler {
private final Activity activity;
public DefaultOptionsMenuHandler(Activity activity) {
this.activity = activity;
}
public boolean onCreateOptionsMenu(Menu menu) {
// do menu inflation here.
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent openSettings = new Intent(activity, SettingsActivity.class);
activity.startActivity(openSettings);
return true;
case R.id.help:
// others
default:
return false;
}
}
public boolean onPrepareOptionsMenu(Menu menu) {
// do menu preparation here.
}
}
Support composition in the base class (ie base class has a setter):
public class BaseActivity extends AppCompatActivity {
#Nullable
private OptionsMenuHandler optionsMenuHandler;
protected void setOptionsMenuHandler(OptionsMenuHandler optionsMenuHandler) {
this.optionsMenuHandler = optionsMenuHandler;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return optionsMenuHandler != null
? optionsMenuHandler.onCreateOptionsMenu(menu)
: super.onCreateOptionsMenu(menu);
}
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
return optionsMenuHandler != null
? optionsMenuHandler.onPrepareOptionsMenu(menu)
: super.onPrepareOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
return optionsMenuHandler != null
? optionsMenuHandler.onOptionsItemSelected(item)
: super.onOptionsItemSelected(item);
}
}
Set the implementation in the Activity that needs the functionality.
public class TestActivity extends BaseActivity {
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setOptionsMenuHandler(new DefaultOptionsMenuHandler(this));
}
}
The net benefit here is that you write the main boilerplate once and support it through all of your activities. You can also continue to keep your business logic defined in the top level activity - where it goes with the other various logic for that particular activity.
Most non-trivial apps would benefit from something along these lines. I typically do something even more robust that supports zero or more OptionsMenuHandlers being set in any given activity where each handler supports a specific type of functionality. The code for this is fairly long and many considerations are needed, so I won't produce it here.
I've searched for a solution for my question all over the internet but I haven't been able to find one and I hope you can help me out
I am trying to create a master detail flow application in android with 2 activities and the second activity contains a fragment. Can anyone please tell me how I can simultaneously update the value in the MainActivity() when I make a change in the fragment's EditText field? I have tried using an Intent but when the 2 activities are side by side that doesnt seem to work well.
Screenshot of Emulator
Any suggestions?
It seems you are in a context as follows:
When A happens, it triggers B
As a result, I suggest you to use EventBus library in your project.
The installation is easy. First, add the following code in your build.gradle file:
compile 'org.greenrobot:eventbus:3.0.0'
Second, let's see what we are going to add in our codes.
In the Fragment which you wanted to make changes:
/* When A happens */
myButton.setOnClickListener(new View.OnClickListener() { // complete entering the content, update it
EventBus.getDefault.post(MyUpdateEvent(myContent));
});
Create your custom class MyUpdateEven:
public class MyUpdateEvent{
private String myContent;
public MyUpdateEvent(String myContent) {
this.myContent = myContent;
}
public String getUpdateContent() {
return myContent;
}
}
In the Activity you wanted to update:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
EventBus.getDefault.register(this); // add this code to monitor the update
}
/* It triggers B */
#Subscribe // don't forget to add #Subscribe
public void onEvent(MyUpdateEvent event){
// this is your custom method
myTextView.setText(event.getUpdateContent()); // do your update
}
#Override
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault.unregister(this); // when you leave this lifecycle, cancel the monitoring
}
}
EventBus is a good library that I've been used a lot in my projects.
I think it can solve your problem.
Try to define a interface.
public interface OnEditActivity {
public void onEdit(ActivityObject activityObject, boolean isEditing);
}
And on your another class for example DetailActivity, then you have to override the method onEdit that you created in your interface:
public class DetailActivity extends AppCompatActivity implements OnEditActivity{
//IN HERE --- Create method.
#Override
public void onEdit(ActivityObject activityObject, boolean isEditing) {
if(isEditing){
displayView(activityObject,true);
}else{
displayView(activityObject,false);
}
}
}
And in your EditFragment for example will look like this:
public class EditFragment extends Fragment{
//Define your interface in your fragment
private OnEditActivity onEditActivity;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_edit_activity, container, false);
return v;
}
public void onAttach(Activity a) {
super.onAttach(a);
onEditActivity =(OnEditActivity) a;
}
}
And if you want to call onEdit method just call:
onEditActivity.onEdit(activityObjectNew,false)
I hope this help you !
I have an Activity named PhotoSelectorActivity. It inherits from a BaseActivity that looks like this:
public class BaseActivity
extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(this.getClass().getSimpleName(),
"onCreate("+Integer.toHexString(System.identityHashCode(this))+")");
}
#Override
protected void onDestroy() {
super.onDestroy();
getSupportActionBar().setCustomView(null);
Log.d(this.getClass().getSimpleName(),
"onDestroy("+Integer.toHexString(System.identityHashCode(this))+")");
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
return onNavigateUp(item);
case R.id.menu_item_settings:
startActivity(new Intent(this, PreferencesActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
protected ActionBar setupActionBar(boolean enableBackButton) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getSupportActionBar().setDisplayHomeAsUpEnabled(enableBackButton);
}
ActionBar actionBar = getSupportActionBar();
actionBar.setCustomView(R.layout.action_bar);
actionBar.setDisplayShowTitleEnabled(false);
actionBar.setDisplayShowCustomEnabled(true);
return null;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
The purpose of this BaseActivity is to provide the same menu and actionbar to each one of my activities. You'll notice the getSupportActionBar().setCustomView(null) in the onDestroy() method, that's there to try and combat the problem that I may be having.
When i get an orientation change event, i notice in DDMS that i end up with 2 instances of my activity. One of them may be leaking, but I'm not certain. Here's a screen shot from DDMS:
So the object at the top is the Activity in question: PhotoSelectorActivity. The instance shown here is the previous instance (onDestroy() has already been called on it). Yet it remains in memory even after a forced GC via DDMS.
Another bit of information is that this only seems to happen after using a dialog. That is, when the Activity is initially displayed and before the user performs and action I can do back to back orientation changes without the # of activities climbing above 1. After I've used the following dialog i seem to get the extra Activity in memory:
public class PhotoSourceDialog
extends DialogFragment
implements DialogInterface.OnClickListener {
public static interface PhotoSourceDialogListener {
void onPhotoSourceSelected(String result);
}
private PhotoSourceDialogListener listener;
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
if (!PhotoSourceDialogListener.class.isInstance(activity)) {
throw new IllegalStateException(
"Activity must implement PhotoSourceDialogListener");
}
listener = PhotoSourceDialogListener.class.cast(activity);
}
#Override
public void onDetach() {
super.onDetach();
listener = null;
}
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return new AlertDialog.Builder(getActivity())
.setTitle(R.string.photo_source)
.setItems(R.array.photo_sources, this).create();
}
#Override
public void onClick(DialogInterface dialog, int which) {
String choice = getResources().getStringArray(
R.array.photo_sources)[which];
if (listener!=null) {
listener.onPhotoSourceSelected(choice);
}
}
}
and to invoke it i do this in my activity:
PhotoSourceDialog dialog = new PhotoSourceDialog();
dialog.show(getSupportFragmentManager(), PhotoSourceDialog.class.getName());
So my question is this: Should I be worried? Is this just something that is hanging around for a bit but will eventually be GCd? I would think that if there was a leak it would grow higher than 2.
I'm closing this question. Someone at google has responded with the following:
OK, in that case then it's not an AppCompat bug since the standard
Action Bar implementation is used on ICS+.
Looking at that MAT screenshot, the framework's ActionMenuItemView is
being referenced from a clipboard event which is being finalized,
hence about to be GC'd. The LayoutInflater is probably the
LayoutInflater that the Activity keeps itself (getLayoutInflater()).
I have this preferences class (below) that saves two ListPreferences, but if the ListPreferences are changed and the back button is pressed, the changes don't take affect unless the application is restarted. Did I miss something? Have been looking everywhere, but just can't seem to find an answer the fits or works. Please help.
public class Preferences extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
#Override
public void onPause() {
super.onPause();
}
#Override
public void onResume() {
super.onResume();
}
}
Application Code
public class Quotes extends Activity implements OnClickListener {
ProgressDialog dialog;
private WebView webview;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
String q = SP.getString("appViewType","http://www.google.com");
String c = SP.getString("appRefreshRate","20");
webview = (WebView) findViewById(R.id.scroll);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new QuotesWebView(this));
webview.loadUrl(q);
ScheduledExecutorService timer = Executors.newSingleThreadScheduledExecutor();
timer.scheduleAtFixedRate(new Runnable() {
#Override
public void run() {
webview.reload();
}
}, 10, Long.parseLong(c),TimeUnit.SECONDS);
findViewById(R.id.refresh).setOnClickListener(this);
}
#Override
public void onPause(){
super.onPause();
}
#Override
public void onResume(){
super.onResume();
}
public void onClick(View v){
switch(v.getId()){
case R.id.refresh:
webview.reload();
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
MenuItem about = menu.getItem(0);
about.setIntent(new Intent(this, About.class));
MenuItem preferences = menu.getItem(1);
preferences.setIntent(new Intent(this, Preferences.class));
return true;
}
}
You need to somehow reload your preferences when the preferences activity finishes. I thought Dirol's suggestion of loading them in onResume() instead of onCreate() was excellent; have you tried it? Or am I misunderstanding the problem as well.
In my own case, I launched the preferences activity with startActivityForResult() and then on the activity result callback, I reloaded the preferences.
Code snippets:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case MENU_PREFERENCES:
Intent intent = new Intent().setClass(this, CalcPreferences.class);
startActivityForResult(intent, MENU_PREFERENCES);
break;
default: return super.onOptionsItemSelected(item);
}
return true;
}
#Override
protected void onActivityResult(int req, int result, Intent data) {
switch( req ) {
case MENU_PREFERENCES:
SharedPreferences sp =
PreferenceManager.getDefaultSharedPreferences(this);
updatePreferences(sp);
break;
default:
super.onActivityResult(req, result, data);
break;
}
}
#Override
protected void updatePreferences(SharedPreferences sp) {
super.updatePreferences(sp);
keyclick = sp.getBoolean("keyclick", keyclick);
}
Anyway, this is what works for me. I may try moving my updatePreferences() call to onResume() myself to see if that works too.
Try overriding the onBackPressed() method.
If your "Up" button (top left <-) provides the correct result, then you can set the Back button to behave like the Up button.
#Override
public void onBackPressed() {
super.onBackPressed();
NavUtils.navigateUpFromSameTask(this);
}
You load preferences only on onCreate() method. That method called only when a fresh activity starts up. The addPreferencesFromResource inflates the xml file into the preferences, so you only get the info, which is already has been stored in the xml at the moment addPreferencesFromResource was called, not after.
Try to move that method to onResume. But watch for the memory leak. I don't know exactly what the addPreferencesFromResource do, but from the documentation - I would be very suspicious about that method activity.
I had the same problem and solved it as follows:
The main activity class implements OnSharedPreferenceChangeListener:
public class Activity_name extends Activity implements OnSharedPreferenceChangeListener {
...
}
Inside the main activity class the onSharedPreferenceChanged is run whenever a preference entry changes. I simply update all my variables from the preferences as i did in onCreate:
#Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
<read all preferences as you did in onCreate()>
}
This does the trick and I hope it saves you some time in searching for a solution.
I've had the same problem...
Try to create preference instance and load its data in every class and every activity where you need it.
It worked for me...Hope it helps.
You will need to reload your view or whatever object which uses those preferences, preferably when preference activity closes.
Preference activities do not change nothing but an internal file with your preferences(key=value list). When it is changed, preferenceActivity calls onPreferenceChaged() and nothing more. It doesn't refresh your stuff by itself. You need to reload prefs and to reuse them in onResume() method or equivalent.