Switching themes in android - java

My aim is to allow users select from a list of available themes in my app and make it permanent till they wish to change it again, but i have only been able to achieve that partially. For now, when a user changes the app theme it does change and remains even after the app is minimized and resumed but when a user exits the app and reopens it, the theme goes back to default which is not what i want.
My question now is, how can i make the selected theme permanent even when a user exits the app? I have tried to search for some solutions online but haven't found any that helped me
ThemeActivity.java
public class ThemeActivity extends AppCompatActivity {
public Button blackbtn,bluebtn,pinkbtn,redbtn;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
themeUtils.onActivityCreateSetTheme(this);
setContentView(R.layout.activity_theme);
blackbtn = findViewById(R.id.blackbutton);
bluebtn = findViewById(R.id.bluebutton);
pinkbtn = findViewById(R.id.pinkbutton);
redbtn = findViewById(R.id.redbutton);
blackbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.BLACK);
}
});
bluebtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.BLUE);
}
});
pinkbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.PINK);
}
});
redbtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
themeUtils.changeToTheme(ThemeActivity.this, themeUtils.RED);
}
});
}
themeUtils.java
public class themeUtils {
private static int cTheme;
public final static int BLACK = 0;
public final static int BLUE = 1;
public final static int PINK = 2;
public final static int RED = 3;
public static void changeToTheme(Activity activity, int theme) {
cTheme = theme;
activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
}
public static void onActivityCreateSetTheme(Activity activity) {
switch (cTheme)
{
default:
case BLACK:
activity.setTheme(R.style.BlackTheme);
break;
case PINK:
activity.setTheme(R.style.pink);
break;
case RED:
activity.setTheme(R.style.red);
break;
case BLUE:
activity.setTheme(R.style.BlueTheme);
break;
}
}

The simplest solution for this would be to save your selected theme in SharedPreferences. Whenever the app launches, you read the saved value from your SharedPreferences and load the appropriate theme.
To write your selected theme
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(getString(R.string.selected_app_theme), YOUR_APP_THEME);
editor.commit();
To read the saved value
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = getResources().getInteger(R.integer.default_app_theme);
int appTheme = sharedPref.getInt(getString(R.string.selected_app_theme), defaultValue);
EDIT Based on comment
Whenever you change your app theme, you need to save it to SharedPreferences. So, whenever the changeToTheme method is called, after changing the theme, just save it to SharedPrefs. You could create a method which would save the theme like so
void saveThemeToSharedPrefs(int appTheme) {
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("MY_APP_THEME, appTheme);
editor.commit();
}
Next time, when your app starts, you will load this value and use it to change the theme like so
int getAppTheme() {
SharedPreferences sharedPref = getActivity().getPreferences(Context.MODE_PRIVATE);
int defaultValue = 0 //For Black theme. Change it to whatever you want as default
int appTheme = sharedPref.getInt("MY_APP_THEME", defaultValue);
}
//Change the theme in your starting activity
ThemeUtils.changeToTheme(activity, getAppTheme())

Related

image view not being visible based on number of clicks

In my MainActiviy class I want to display image views of smiley faces based on the number of clicks that occur on the buttons jokes, poems and funnystories combined. However my switch statement does not seem to working as no images appear. Also if any of those image views become visible, then they should remain visible even after the user closing the app and reopening it.
I also notice a click count increasing by one when the user opens the app which is not correct. It should increase based on the buttons mentioned previously being clicked.
public class MainActivity extends AppCompatActivity {
SharedPreferencesManager prefManager = SharedPreferencesManager.getInstance(this);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button jokesButton = findViewById(R.id.button_jokes);
Button poemsButton = findViewById(R.id.button_poems);
Button funnyStoriesButton = findViewById(R.id.button_funny_stories);
ImageView yellowSmileyFace = findViewById(R.id.yellow_happy);
ImageView greenSmileyFace = findViewById(R.id.green_happy);
ImageView redSmileyFace = findViewById(R.id.red_happy);
jokesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("jokes");
}
});
poemsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("poems");
}
});
funnyStoriesButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
prefManager.increaseClickCount();
openContentPage("funnystories");
}
});
TextView clickCountText = findViewById(R.id.click_count);
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
switch (prefManager.increaseClickCount()){
case 4 :
yellowSmileyFace.setVisibility(View.VISIBLE);
break;
case 8 :
greenSmileyFace.setVisibility(View.VISIBLE);
break;
case 12 :
redSmileyFace.setVisibility(View.VISIBLE);
break;
default :
yellowSmileyFace.setVisibility(View.INVISIBLE);
greenSmileyFace.setVisibility(View.INVISIBLE);
redsmileyFace.setVisibility(View.INVISIBLE);
}
}
private void openContentPage(String v) {
Intent intentContentPage = new Intent(MainActivity.this, Content.class);
intentContentPage.putExtra("keyPage", v);
startActivity(intentContentPage);
}
}
below is the Shared preferences class
public class SharedPreferencesManager {
private static final String APP_PREFS = "AppPrefsFile";
private static final String NUMBER_OF_CLICKS = "numberOfClicks";
private SharedPreferences sharedPrefs;
private static SharedPreferencesManager instance;
private SharedPreferencesManager(Context context) {
sharedPrefs = context.getApplicationContext().getSharedPreferences(APP_PREFS, MODE_PRIVATE);
}
public static synchronized SharedPreferencesManager getInstance(Context context){
if(instance == null)
instance = new SharedPreferencesManager(context);
return instance;
}
public int increaseClickCount() {
int clickCount = sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
clickCount++;
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putInt(NUMBER_OF_CLICKS, clickCount);
editor.apply();
return clickCount;
}
}
You need to add a getter for your clicks
public int getClicks(){
return sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
}
Whenever you want to get your clicks currently you are calling increaseClickCount() which causes your clicks to increment before returning them. That is why it gains clicks every time you open the stage and why your switch isn't working correctly
so add the above getter to your SharedPrefrenceManager and change these two lines
switch (prefManager.increaseClickCount()){
to
switch (prefManager.getClicks()){
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
to
clickCountText.setText(Integer.toString(prefManager.getClicks()));
Tell me if that fixes your problem
The reason for counts' increase is you use increaseClickCount() to receive click count.You have to create another method to receive current clickCount. Your switch statement works only when they equal to 4,8 or 12. Maybe you should use if instead.
I also notice a click count increasing by one when the user opens the app which is not correct
It looks to me like this line of code, in MainActivity.onCreate() method will pass a text String of count 1 to clickCountText.
clickCountText.setText(Integer.toString(prefManager.increaseClickCount()));
Also, every time you call SharedPreferencesManager.increaseClickCount, you are assigning a value to clickCount, and whatever was there gets overwritten.
int clickCount = sharedPrefs.getInt(NUMBER_OF_CLICKS, 0);
What is that value?
System.out.println is your friend.
I use this pattern
System.out.println("MyClass, MyMethod, MyVariable:" + myVariable);
I always include the class and method because it can be annoying trying to figure out where println are coming from if you leave several in for debugging purposes and want to get rid of them later.

How to make intro slider only appear once after installation?

I have made an intro slider with this library . I want the slider to appear only once after the app installation. How to do this?
This is my code
public class SliderActivity extends TutorialActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addFragment(new Step.Builder().setTitle("This is header")
.setContent("This is content")
.setBackgroundColor(Color.parseColor("#3F51B5")) // int background color
.setDrawable(R.drawable.image_1) // int top drawable
.setSummary("This is summary")
.build());
addFragment(new Step.Builder().setTitle("This is header")
.setContent("This is content")
.setBackgroundColor(Color.parseColor("#FF4081")) // int background color
.setDrawable(R.drawable.image_3) // int top drawable
.setSummary("This is summary")
.build());
addFragment(new Step.Builder().setTitle("This is header")
.setContent("This is content")
.setBackgroundColor(Color.parseColor("#f816a463")) // int background color
.setDrawable(R.drawable.image_4) // int top drawable
.setSummary("This is summary")
.build());
}
#Override
public void finishTutorial() {
Intent intent = new Intent(SliderActivity.this, WelcomeActivity.class);
startActivity(intent);
}
}
I used the SharedPreferences class to accomplish this. Put this code in your welcome activity in your onCreate() method.
private SharedPreferences sharedPreferences;
sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(this);
// Check if we need to display our OnboardingFragment
if (!sharedPreferences.getBoolean(
SliderActivity.COMPLETED_ONBOARDING_PREF_NAME, false)) {
startActivity(new Intent(this, SliderActivity.class));
}
Create a global variable in your SliderActivity class.
public static final String COMPLETED_ONBOARDING_PREF_NAME = "Onboarding Completed";
And place this code in your finishTutorial() method.
#Override
public void finishTutorial(){
SharedPreferences.Editor sharedPreferencesEditor =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit();
sharedPreferencesEditor.putBoolean(
COMPLETED_ONBOARDING_PREF_NAME, true);
sharedPreferencesEditor.apply();
finish();
}
This code stores weather or not the user has completed the tutorial in app preferences and can't be changed by the user unless they uninstall the app or clear app data. Let me know if you have any other questions.

How can I display info from sharedPreferences after the activity or app gets closed?

I have put some information that I want to be displayed even after my app or activity gets closed. I have a function display and if I call it in onCreate() or onStart() my app crashes.
public void display() {
SharedPreferences sharedPref = getSharedPreferences("MedInfo",
Context.MODE_PRIVATE);
mText1.setText(sharedPref.getString("mText1", ""));
}
Here's how the data gets saved
public void savemMed1() {
SharedPreferences sharedPref = getSharedPreferences("MedInfo",
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("mText1", addMed.getText().toString());
editor.apply();
Toast.makeText(this, "Added", Toast.LENGTH_LONG).show();
}
This is the line that does not fit in the picture:
java.lang.RuntimeException: Unable to start activity ComponentInfo{corina_holom.com.medplannerapp/corina_holom.com.medplannerapp.Reminder}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
This is my first time programming in java and android studio and I'm having trouble finding tutorials that help. I'm not sure how I should change this or if I should use onStart()
This is the Code from the activity in which I want the info displayed:
public class Reminder extends AppCompatActivity {
public TextView mText1, mText2, mText3;
private EditText addMed;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reminder);
defineButtons();
}
public void defineButtons() {
findViewById(R.id.mB1).setOnClickListener(buttonClickListener);
findViewById(R.id.mB2).setOnClickListener(buttonClickListener);
//findViewById(R.id.mB3).setOnClickListener(buttonClickListener);
}
private View.OnClickListener buttonClickListener = new View.OnClickListener() {
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.mB1:
addMed = (EditText) findViewById(R.id.addMed);
mText1 = (TextView) findViewById(R.id.mText1);
mText1.setText(addMed.getText());
savemMed1();
break;
case R.id.mB2:
addMed = (EditText) findViewById(R.id.addMed);
mText2 = (TextView) findViewById(R.id.mText2);
mText2.setText(addMed.getText());
break;
}
}
};
public void savemMed1() {
SharedPreferences sharedPref = getSharedPreferences("MedInfo", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("mText1", addMed.getText().toString());
editor.apply();
Toast.makeText(this, "Added", Toast.LENGTH_LONG).show();
}
}
The problem is that by the time you use setText your textview is not initialised. Make sure you do findViewById before you do setText. The best way is to do it first thing in onCreate. And of course make sure that the id is the same as in the layout.

How SharedPreferences with UpdateUI?

I am a noob on developing android apps. I want to ask. How my PreferenceActivity want to Update without back to MainActivity and goto PreferenceActivity again. In this, i give some feature to change the Theme of PreferenceActivity. This is my PreferenceActivity:
public class SettingsPreference extends PreferenceActivity
{
SwitchPreference themeSwitch;
String myPref = "preferences";
SharedPreferences.Editor editor;
String summary;
int theme;
#Override
public void onCreate(Bundle savedInstanceState)
{
// TODO: Implement this method
final SharedPreferences.Editor editor = getSharedPreferences(myPref, MODE_PRIVATE).edit();
final SharedPreferences prefs = getSharedPreferences(myPref, MODE_PRIVATE);
final String summary = prefs.getString("stringSummary", "Default theme");
final int theme = prefs.getInt("intTheme", (android.R.style.Theme_DeviceDefault_Light));
setTheme(theme);
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings_preference);
themeSwitch = (SwitchPreference) findPreference("switchTheme");
themeSwitch.setSummary(summary);
if (themeSwitch != null) {
themeSwitch.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference arg0, Object isOnObject) {
boolean isThemeOn = (Boolean) isOnObject;
if (isThemeOn) {
Toast.makeText(SettingsPreference.this, "Theme Dark ON", Toast.LENGTH_SHORT).show();
editor.putString("stringSummary", "Theme Dark ON");
editor.putInt("intTheme", (android.R.style.Theme_DeviceDefault));
editor.apply();
themeSwitch.setSummary(summary);
} else {
Toast.makeText(SettingsPreference.this, "Theme Dark OFF", Toast.LENGTH_SHORT).show();
editor.putString("stringSummary", "Theme Dark OFF");
editor.putInt("intTheme", (android.R.style.Theme_DeviceDefault_Light));
editor.apply();
themeSwitch.setSummary(summary);
}
return true;
}
});
}
}
}
If you change the Activity layout you just have to restart it.
Try to add this at the end of onPreferenceChange().
if you're in API11+, call in an Activity.
this.recreate();
Otherwise, we just have to finish the activity and start it again with the same intent.
Intent intent = getIntent();
finish();
startActivity(intent);
If you have update every 20 seconds for example , This is code :
import android.os.Handler;
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
//update UI
}
},2000);
Put this in a function and re-call in run .

It is possible to use SharedPreferences to set Newgame and Continue to latest activity

i have a question here that is possible to make sharedpreference set Newgame and Continue to latest activity?
i had 4 activity, menu.class, levelone.class, leveltwo.class, levelthree.class
i will explain with my menu.class code
public class menu extends Activity {
public static final String PREF_LEVEL = "Level";
public static final String PREF_IS_SET ="isSet";
public static final String PREF_LIFES = "Lifes";
int level;
Button newgame, continues, continuelocked;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.menu);
SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE);
// Check wether the pref is set or not.
if (pref.getBoolean(PREF_IS_SET, false)) {
// The prefs is set. Do some game logic here. Like checking for level.
if (pref.getInt(PREF_LEVEL,0) == 0) {
// Reset the level
resetPrefs(pref);
}
else {
//Do nothing at all.
}
}
else {
// if it's not set, just create it.
resetPrefs(pref);
}
//i got error on this newgame line
newgame=(Button)findViewById(R.id.buttonnewgame);
newgame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
pref.putInt(PREF_LEVEL,0);
}
});
}
private void resetPrefs(SharedPreferences pref) {
SharedPreferences.Editor editor = pref.edit();
editor.putInt(PREF_LIFES, 6);
editor.putInt(PREF_LEVEL, 0);
editor.putBoolean(PREF_IS_SET,true);
editor.commit();
}
//to saved the current level and if button continue clicked it will open the latest activity, but i dont know the complete code so i use this
public void onResume() {
super.onResume();
SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE);
level = pref.getInt("Level", 0);
if(level == 0)
{
Intent i =new Intent(menu.this, levelone.class);
startActivity(i);
}
if(level == 1)
{
Intent i =new Intent(menu.this, leveltwo.class);
startActivity(i);
}
if(level == 2)
{
Intent i =new Intent(menu.this, levelthree.class);
startActivity(i);
}
SharedPreferences.Editor editor = pref.edit();
editor.putInt("Level", level);
editor.commit();
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
in code line of i got 2 error
newgame=(Button)findViewById(R.id.buttonnewgame);
newgame.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
pref.putInt(PREF_LEVEL,0);
}
});
and this is,
Multiple markers at this line
- The method putInt(String, int) is undefined for the type
SharedPreferences
- Cannot refer to the non-final local variable pref defined in an
enclosing scope
- Line breakpoint:aselectmenu [line: 63] - resetPrefs(SharedPreferences)
can anyone help me to fix this code problem?
and how to set continues button when clicked, will continue to latest activity that i had play?
Change this line
SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE);
to this
final SharedPreferences pref = getSharedPreferences("SavedGame", MODE_PRIVATE);
Then you will need to access the SharedPreference.Editor to actually put the integer you want
SharedPreferences.Editor editor = pref.edit();
editor.putBoolean("PrefName", VALUE).commit();

Categories

Resources