0
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    switch (item.getItemId()) {
        case R.id.action_create: //run NoteActivity in new note mode
            startActivity(new Intent(this, NoteActivity.class));
            break;
        case R.id.action_theme:
            setTheme(R.style.Theme2);
            setContentView(R.layout.activity_main);
            Intent i = getIntent();
            i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            startActivity(i);

            // TODO: show settings activity

            break;
    }

    return super.onOptionsItemSelected(item);
}

I have a menu item at the top of my activity. I would like to use it to change the theme when pressed. I want to do this after the user has started the program and it will be eventually used to cycle through a bunch of different themes! Right now I just want to get it to work with one. How can I do this?

My Answer

Main Activity

SharedPreferences pref;
SharedPreferences.Editor editor;
int check;
int newcheck;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    pref = getApplicationContext().getSharedPreferences("test", Context.MODE_PRIVATE);
    check = pref.getInt("x", 0);
    if(check == 0){
        setTheme(R.style.AppTheme);
    }else{
        setTheme(R.style.Theme2);
    }

    setContentView(R.layout.activity_main);
    noteActivity = new NoteActivity();
    mListNotes = (ListView) findViewById(R.id.main_listview);
}

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {
            case R.id.action_create: //run NoteActivity in new note mode
                startActivity(new Intent(this, NoteActivity.class));
                break;
            case R.id.action_theme:
                pref = getApplicationContext().getSharedPreferences("test", Context.MODE_PRIVATE);
                editor = pref.edit();
                newcheck = pref.getInt("x",0);
                if(newcheck == 0) {
                    newcheck = 1;
                }else if(newcheck == 1){
                    newcheck = 0;
                }
                editor.clear();//clears the editor to avoid errors
                editor.putInt("x",newcheck);//add in new int
                editor.commit();//commit 

                //restart the activity
                Intent i = getIntent();
                i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                finish();//close activity - avoid crash
                startActivity(i);//start activity

                //TODO show settings activity
                break;
        }
        return super.onOptionsItemSelected(item);
    }
Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98
pewpew
  • 700
  • 2
  • 9
  • 32
  • So what's the problem you're facing right now? The theme is not set properly? – Reaz Murshed Oct 18 '17 at 18:59
  • When I press the button it doesn't change the theme. I tested it in the onCreate() method, so the theme is set up properly. – pewpew Oct 18 '17 at 18:59
  • Why you're starting the `Activity` again then? You should just use the `setTheme` function and that's it. – Reaz Murshed Oct 18 '17 at 19:01
  • `Set the base theme for this context. Note that this should be called before any views are instantiated in the Context (for example before calling android.app.Activity.setContentView or android.view.LayoutInflater.inflate)...` Because of this. I figured if I recalled the activity... hmm maybe I could just call it in onCreate, and use shared preferences to change layout when button is pressed? But then that wouldn't change it because how can you recreate the activity with the new theme(if you have multiple choices)... – pewpew Oct 18 '17 at 19:06

1 Answers1

1

So as far as I've understood your problem, you might consider thinking of taking a parent Activity and set a Fragment in there so that you can change the theme of your Fragment where the control of changing the theme is from your parent Activity. So here's how you can achieve this behaviour.

  • Get a fragment container in your Activity and launch your Fragment in that container in the onCreate function of your Activity.
  • As you're having a menu option button to decide which theme to be deployed in the Fragment you might consider replacing your Fragment again by doing another fragment transaction when your menu option is clicked.
  • You might consider saving the selected theme in SharedPreferences so that each time your Fragment launches, you can set the theme properly by setting it in your onCreateView function of your Fragment after reading the selected theme from your SharedPreferences.

Now if you're thinking of how you can set a theme in your Fragment then this post might help you in this regard. I'm copying the code from there for your convenience.

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // create ContextThemeWrapper from the original Activity Context with the custom theme
    final Context contextThemeWrapper = new ContextThemeWrapper(getActivity(), R.style.yourCustomTheme);

    // clone the inflater using the ContextThemeWrapper
    LayoutInflater localInflater = inflater.cloneInContext(contextThemeWrapper);

    // inflate the layout using the cloned inflater, not default inflater
    return localInflater.inflate(R.layout.yourLayout, container, false);
}

I hope you get the idea already. Please let me know if there's anything else you need clarification about.

Reaz Murshed
  • 23,691
  • 13
  • 78
  • 98