Как менять кастомные темы в настройках Android приложений

262
29 июля 2017, 04:24

Делаю свое первое приложение на Android. Хотелось бы реализовать функционал настроек (смена стиля). Стили сделал, реализовал спиннер, установил ArrayAdapter. Вот что есть:

package com.churkin.myprojectfirst;
import android.content.SharedPreferences;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;
public class Settings extends AppCompatActivity {
Spinner spinnercolor;
SharedPreferences colorPref;
final String COLOR_PREF = "COLOR_PREF";
@Override
protected void onCreate(Bundle savedInstanceState) {
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    setContentView(R.layout.settings);
    setTheme(R.style.FireBrickTheme);
    setTitle("Настройки");
    spinnercolor = (Spinner) findViewById(R.id.spinnercolor);
    ArrayAdapter<?> adapter = ArrayAdapter.createFromResource(this, R.array.spinnersettings, android.R.layout.simple_spinner_item);
    adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
    spinnercolor.setAdapter(adapter);
    spinnercolor.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
        @Override
        public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
            String[] choose = getResources().getStringArray(R.array.spinnersettings);
            String item = (String)adapterView.getItemAtPosition(i);
            setColor(item);
            if(!item.equals("Стандарт")){
            Toast toast = Toast.makeText(getApplicationContext(), "Установлена тема: " + item, Toast.LENGTH_SHORT);
            toast.show();}
        }
        @Override
        public void onNothingSelected(AdapterView<?> parent) {
        }
    });
    super.onCreate(savedInstanceState);
}
private void setColor (String color){
switch(color){
    case "Стандарт":
        pref(color);
        setTheme(R.style.AppTheme);
        break;
    case "DodgerBlue":
        pref(color);
        setTheme(R.style.DodgerBlueTheme);
        break;
    case "ForestGreen":
        pref(color);
        setTheme(R.style.ForestGreenTheme);
        break;
    case "FireBrick":
        pref(color);
        setTheme(R.style.FireBrickTheme);
        break;
    case "DarkOrange":
        pref(color);
        setTheme(R.style.DarkOrangeTheme);
        break;   }
}
private void pref(String color){
    colorPref = getPreferences(MODE_PRIVATE);
    SharedPreferences.Editor ed = colorPref.edit();
    ed.putString(COLOR_PREF, color);
    ed.apply();
}

Как нужно сделать, чтобы при выборе какого-либо пункта Spinner тема менялась на соответствующий цвет в других Activity, а также в текущем?

Answer 1

Можно много разных способов придумать, например, можно сделать так:

  1. Создаем класс ThemeUtils. Так как мы динамически меняем тему из spinner'a мы должны сделать это программно. Это делается путем вызова метода setTheme() в методе активности onCreate(), перед любым вызовом setContentView(). Чтобы изменить тему, вам нужно просто перезагрузить activity.

    public class ThemeUtils{
    private static int sTheme;
    public final static int FIRE_BRICK = 0;
    public final static int DODGER_BLUE = 1;
    public static void changeToTheme(Activity activity, int theme) {
        sTheme = theme;
        activity.finish();
        activity.startActivity(new Intent(activity, activity.getClass()));
        activity.overridePendingTransition(android.R.anim.fade_in,
                android.R.anim.fade_out);
        }
    public static void onActivityCreateSetTheme(Activity activity) {
        switch (sTheme) {
        default:
            activity.setTheme(R.style.AppTheme);
            break;
        case FIRE_BRICK:
            activity.setTheme(R.style.FireBrickTheme);
            break;
        case DODGER_BLUE:
            activity.setTheme(R.style.DodgerBlueTheme);
            break;
        }
    }
    }
  2. Далее можно оформить выбор темы в отдельном activity, ну или вставите код в свое, просто как пример использования.

    public class ThemeActivity extends AppCompatActivity {
    private Spinner spThemes;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // Обязательно делаем вызов метода по установке темы до setContentView
        ThemeUtils.onActivityCreateSetTheme(this);
        // и только после установки делаем сам setContentView
        setContentView(R.layout.activity_theme);
        setupSpinnerItemSelection();
    }
    private void setupSpinnerItemSelection() {
        spThemes = (Spinner) findViewById(R.id.spinnercolor);
        spThemes.setSelection(ThemeApplication.currentPosition);
        spThemes.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
            @Override
            public void onItemSelected(AdapterView<?> parent, View view,
                    int position, long id) {
                if (ThemeApplication.currentPosition != position) {
                    ThemeUtils.changeToTheme(ThemeActivity.this, position);
                }
                ThemeApplication.currentPosition = position;
            }
            @Override
            public void onNothingSelected(AdapterView<?> parent) {
            }
        });
    }
    }
  3. Чтобы запомнить какая у нас тема сейчас установлена, создадим параметр на уровне Application:

    public class ThemeApplication extends Application {
          // Храним текущее положение спинера
          public static int currentPosition;
    }
READ ALSO
Spring MVC и потоки

Spring MVC и потоки

И такЕсть проект

269
Создание программы со встроенной JVM

Создание программы со встроенной JVM

Здравствуйте, как создать программу со встроенной JVM и нужными библиотеками? Объясните по-подробней или киньте ссылки, где можно посмотретьМожно...

244