I am using shared preferences to keep track of a Admin code that is saved on the device, I have noticed that when I go this particular fragment that has a landscape orientation the preference gets called twice and on the second time it resets to its initial null value. this is the only fragment it happens on and i have been able to narrow it down to the line
activity.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
is there a particular correct method to have shared preferences working with a landscape orientation
Here is the Code
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final Activity activity = getActivity();
SharedPreferences sharedpreferences = activity.getSharedPreferences(MyPREFERENCES, Context.MODE_PRIVATE);
Boolean Admin_Mode = sharedpreferences.getBoolean("AdminCode", false);
String IPaddress = sharedpreferences.getString("IP Address", "");
System.out.println(IPaddress);
System.out.println(Admin_Mode);
View rootView = inflater.inflate(R.layout.augmented_reality_view, container, false);
ActionBar actionBar = ((ActionBarActivity)activity).getSupportActionBar();
actionBar.hide();
System.out.println("here");
activity.setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
mSensorManager = (SensorManager)getActivity().getSystemService(Context.SENSOR_SERVICE);
mRotationVectorSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
mMagneticSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, mRotationVectorSensor, 10000);
mSensorManager.registerListener(this, mMagneticSensor, 10000);
HeadTracker = (ToggleButton) rootView.findViewById(R.id.HeadTracker);
return rootView;
}
#Override
public void onSensorChanged(SensorEvent event) {
if (HeadTracker.isChecked() == true) {
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) {
SensorManager.getRotationMatrixFromVector(
mRotationMatrix, event.values);
if (mRotationMatrix[2] >= 0.6 && mRotationMatrix[0] >= -0.1 && mRotationMatrix[0] <= 0.2){
Left = true;
Right = false;
}
else if (mRotationMatrix[2] <= -0.8 && mRotationMatrix[0] >= -0.1 && mRotationMatrix[0] <= 0.2){
Left = false;
Right = true;
}
else{
Left = false;
Right = false;;
}
}
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
if(event.values[2] >= 390){
MagnetButtonPressed = true;
}
else{
MagnetButtonPressed = false;
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onPause()
{
super.onPause();
mSensorManager.unregisterListener(this);
}
Any Advice would be Epic :)
Cheers
Steve
///...... EDIT .........\\\
added in settings fragment code
public class Settings extends PreferenceFragment {
public SharedPreferences sharedpreferences;
public static final String MyPREFERENCES = "MyPrefs" ;
String IPaddress;
int PortNumber;
Boolean Admin_Mode;
public Settings() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
View rootView = inflater.inflate(R.layout.settings, container, false);
getActivity().setRequestedOrientation(
ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
final SharedPreferences sharedpreferences = getActivity().getSharedPreferences(MyPREFERENCES,Context.MODE_PRIVATE);
IPaddress = sharedpreferences.getString("IP Address","");
PortNumber = sharedpreferences.getInt("Port Numner", 1);
Admin_Mode = sharedpreferences.getBoolean("AdminCode", false);
final EditText mEdit = (EditText)rootView.findViewById(R.id.ipaddress);
final EditText mEdit2 = (EditText)rootView.findViewById(R.id.portnumber);
final EditText AdminCommandBox = (EditText)rootView.findViewById(R.id.AdminCommandBox);
mEdit.setText(IPaddress);
String strI = Integer.toString(PortNumber);
mEdit2.setText(strI);
Button clickButton = (Button) rootView.findViewById(R.id.Update_Settings);
clickButton.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString("IP Address", mEdit.getText().toString());
editor.putInt("Port Numner", Integer.parseInt(mEdit2.getText().toString()));
editor.commit();
Toast.makeText(getActivity(),"Port and Ip Updated!",Toast.LENGTH_SHORT).show();
}
});
final Button Authorise = (Button) rootView.findViewById(R.id.Authorise_Button);
if (Admin_Mode == false){Authorise.setText("Authorise");}
else if (Admin_Mode == true){Authorise.setText("Deactivate");}
Authorise.setOnClickListener( new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Admin_Mode == false){
if (AdminCommandBox.getText().toString().equals("FerasQUT123")) {
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean("AdminCode", true);
editor.commit();
Toast.makeText(getActivity(),"Code Authorised",Toast.LENGTH_SHORT).show();
Authorise.setText("Deactivate");
}
else{
Toast.makeText(getActivity(),"Please Enter the Correct Code",Toast.LENGTH_SHORT).show();
}
}
else if (Admin_Mode == true){
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putBoolean("AdminCode", false);
editor.commit();
Toast.makeText(getActivity()," Deactivated",Toast.LENGTH_SHORT).show();
Authorise.setText("Authorise");
}
}
});
return rootView;
}
public void onDestroy() {
super.onDestroy();
}}
In the shared preference i get the state of the admin mode at the beginning of the on create, i set it in the main activity to false and then update it in the settings fragment if the correct code is entered.
Your issue is that you are setting admin mode to false in the activity's onCreate method. When the screen orientation changes, the activity will be destroyed and recreated--so onCreate will be called again, which is setting your admin mode preference to false.
Related
Trying to create Android settings with preferences, which some of them open new Activity / custom Dialog with OnPreferenceClickListener. Everything is working fine, but the problem is that on real device, random preferences have gray colour like they are disabled. I am not able to find any pattern, why it is happening, but it only happens with clean Preference class. EditTextPreferences and others do not have this kind of problem. Here is example with some code.
<PreferenceCategory
app:title="#string/extra"
app:key="annots">
<Preference
app:key="annot"
app:title="#string/pref_annotation" />
<Preference
app:key="reset"
app:title="#string/reset_extra" />
</PreferenceCategory>
<PreferenceCategory
app:title="#string/app"
app:key="version_android">
<Preference
app:key="about_app"
app:title="#string/third_party"/>
<Preference
app:key="show_web"
app:title="#string/website"/>
<Preference
app:key="pref_about_build"
app:persistent="false"
app:selectable="false"
app:title="#string/build_version" />
</PreferenceCategory>
Whole Java code:
public class SettingsActivity extends AppCompatActivity {
Context context;
public final static String GPS_DIS = "GPS_distance", GPS_TIME = "GPS_time", FILESIZE = "file_size", SAMPLING = "sampling_frequency", SAMPLING_WEAR = "sampling_frequency_wear";
public final static String FREE_MEMORY_PHONE_TO_SAVE = "free_memory_phone", FREE_MEMORY_WEAR_TO_SAVE = "free_memory_wear";
public final static String ACTIVITY_RECOGNITION_INTERVAL = "activity_recognition_refresh";
private final static String AVAILABLE_MEMORY = "available_memory";
public final static String AVAILABLE_MEMORY_WEAR = "available_memory_wear";
private static int getDelay(int rate) {
int delay = 0;
switch (rate) {
case SENSOR_DELAY_FASTEST:
break;
case SENSOR_DELAY_GAME:
delay = 20000;
break;
case SENSOR_DELAY_UI:
delay = 66667;
break;
case SENSOR_DELAY_NORMAL:
delay = 200000;
break;
}
return delay;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle(getString(R.string.settings));
context = this;
setContentView(R.layout.activity_settings);
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, new PreferencesFragmentNew())
.commit();
if(getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
}
#Override
public boolean onSupportNavigateUp() {
onBackPressed();
return true;
}
#Override
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
finish();
startActivity(new Intent(this, Main.class));
return true;
}
public static class PreferencesFragmentNew extends PreferenceFragmentCompat {
private ArrayList<String> setDigits = new ArrayList<String>(){{
add(GPS_DIS);
add(GPS_TIME);
add(FILESIZE);
add(ACTIVITY_RECOGNITION_INTERVAL);
add(FREE_MEMORY_PHONE_TO_SAVE);
add(FREE_MEMORY_WEAR_TO_SAVE);
}};
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.prefs, rootKey);
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(Objects.requireNonNull(getActivity()));
findPreference(SAMPLING).setSummary(getDelay(preferences.getInt(SAMPLING, 0)) +" μs");
findPreference(SAMPLING).setOnPreferenceClickListener(preference -> {
DialogsOther.infoDialog(getContext(), DialogsOther.SAMPLING);
return true;
});
findPreference(SAMPLING_WEAR).setSummary(getDelay(preferences.getInt(SAMPLING_WEAR, 2)) +" μs");
findPreference(SAMPLING_WEAR).setOnPreferenceClickListener(preference -> {
DialogsOther.infoDialog(getContext(), DialogsOther.SAMPLING_WEAR);
return true;
});
findPreference(AVAILABLE_MEMORY).setSummary(Memory.getFreeMemoryString());
String memoryWear = preferences.getString(AVAILABLE_MEMORY, "");
if(memoryWear.equals("")){
findPreference(AVAILABLE_MEMORY_WEAR).setSummary(getContext().getString(R.string.unknown));
}else{
findPreference(AVAILABLE_MEMORY_WEAR).setSummary(getContext().getString(R.string.last_known)+" "+memoryWear+" MB");
}
for(String s : setDigits){
EditTextPreference editTextPreference = findPreference(s);
if(editTextPreference != null) {
editTextPreference.setOnBindEditTextListener(editText -> editText.setInputType(InputType.TYPE_CLASS_NUMBER));
}
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
editTextPreference.setSummary(sharedPreferences.getString(s, ""));
}
// resetting to default values - annotations
findPreference("reset").setOnPreferenceClickListener(preference -> getContext().sendBroadcast(new Intent(Main.RESET_STATS)));
Preference pref = findPreference("activity_recognition_refresh");
pref.setOnPreferenceChangeListener((preference, newValue) -> {
preference.setSummary(newValue + " s");
return true;
});
findPreference("activity_recognition_about").setOnPreferenceClickListener(preference -> {
DialogsOther.infoDialog(getContext(), R.string.title_activity_recognition,
R.string.about_activity_recognition_text).show();
return true;
});
findPreference("about_app").setOnPreferenceClickListener(preference -> {
startActivity(new Intent(getActivity(), AboutApp.class));
return true;
});
findPreference("annot").setOnPreferenceClickListener(preference -> {
startActivity(new Intent(getActivity(), AnnotationActivitySet.class));
return true;
});
findPreference("show_web").setOnPreferenceClickListener(preference -> {
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("..."));
startActivity(browserIntent);
return true;
});
findPreference("pref_about_build").setSummary(BuildConfig.VERSION_NAME);
}
}
#Override
public void onBackPressed() {
finish();
startActivity(new Intent(this, Main.class));
}
}
The last one should be with gray color, but this happens and every time it is random:
I tried to change styles of preferences, their colours, set enabled programmatically, tried multiple phones with different versions of Android. Any suggestion / quick fix ? Or should I create own implementation.
Hello i am building a preference activity in which i have a SwitchPreference through i enable some EditTexts. When the switch is checked an AlertDialog for the user to pick a master password. I want if the user does not select a password the switch to be disabled again.
Code:
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
public static class GeneralPreferenceFragment extends PreferenceFragment implements View.OnClickListener {
private AlertDialog pinDialog;
private SwitchPreference master;
private boolean updated;
private SharedPreferences mUpdated;
private SharedPreferences.Editor mEditor;
private Button one, two, three, four, five, six, seven, eight, nine, zero, buttonClicked, openButton, settings;
private ImageView image1, image2, image3, image4;
private TextView tv;
private AlertDialog.Builder builder;
private StringBuffer pinCode, checkPinCode;
private int count = 0;
private String encryptedString;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.pref_general);
setHasOptionsMenu(true);
master = (SwitchPreference) findPreference("master_switch");
mUpdated = PreferenceManager.getDefaultSharedPreferences(getActivity().getApplicationContext());
updated = mUpdated.getBoolean("master_switch", false);
pinDialog = enablePinDialog();
pinCode = new StringBuffer();
checkPinCode = new StringBuffer();
setListeners();
bindPreferenceSummaryToValue(findPreference("coffees_file"));
bindPreferenceSummaryToValue(findPreference("snacks_file"));
bindPreferenceSummaryToValue(findPreference("sweets_file"));
bindPreferenceSummaryToValue(findPreference("spirits_file"));
bindPreferenceSummaryToValue(findPreference("beverages_file"));
bindPreferenceSummaryToValue(findPreference("beers_file"));
master.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean switched = ((SwitchPreference) preference).isChecked();
updated = !switched;
mEditor = mUpdated.edit();
mEditor.putBoolean("master_switch", updated);
mEditor.apply();
master.setSummary(!updated ? "Disabled" : "Enabled");
if (updated) {
if (pinDialog != null) {
pinDialog.show();
}
} else {
removePrefs();
}
return true;
}
});
}
private void setListeners() {
one.setOnClickListener(this);
two.setOnClickListener(this);
three.setOnClickListener(this);
four.setOnClickListener(this);
five.setOnClickListener(this);
six.setOnClickListener(this);
seven.setOnClickListener(this);
eight.setOnClickListener(this);
nine.setOnClickListener(this);
zero.setOnClickListener(this);
}
public AlertDialog enablePinDialog() {
builder = new AlertDialog.Builder(getActivity());
View view = LayoutInflater.from(builder.getContext()).inflate(R.layout.dialog_layout, null, false);
one = (Button) view.findViewById(R.id.button);
two = (Button) view.findViewById(R.id.button2);
three = (Button) view.findViewById(R.id.button3);
four = (Button) view.findViewById(R.id.button4);
five = (Button) view.findViewById(R.id.button5);
six = (Button) view.findViewById(R.id.button6);
seven = (Button) view.findViewById(R.id.button7);
eight = (Button) view.findViewById(R.id.button8);
nine = (Button) view.findViewById(R.id.button9);
zero = (Button) view.findViewById(R.id.buttonzero);
image1 = (ImageView) view.findViewById(R.id.imageView);
image2 = (ImageView) view.findViewById(R.id.imageView2);
image3 = (ImageView) view.findViewById(R.id.imageView3);
image4 = (ImageView) view.findViewById(R.id.imageView4);
tv = (TextView) view.findViewById(R.id.changeText);
builder.setView(view);
builder.setTitle("Master Password");
return builder.create();
}
private void savePassword() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(checkPinCode.toString().getBytes());
encryptedString = new String(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
editor.putString("master_pin", encryptedString);
editor.apply();
}
private void removePrefs() {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
SharedPreferences.Editor editor = preferences.edit();
editor.remove("master_pin");
editor.apply();
}
private void typePassword() {
count++;
pinCode.append(String.valueOf(buttonClicked.getText()));
if (count == 1) {
image1.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 2) {
image2.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 3) {
image3.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 4) {
image4.setImageResource(R.drawable.ic_lens_black_24dp);
image1.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image2.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image3.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image4.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
tv.setText(R.string.second_text);
}
}
private void retypePassword() {
checkPinCode.append(String.valueOf(buttonClicked.getText()));
if (count == 5) {
image1.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 6) {
image2.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 7) {
image3.setImageResource(R.drawable.ic_lens_black_24dp);
} else if (count == 8) {
image4.setImageResource(R.drawable.ic_lens_black_24dp);
checkPinCode = checkPinCode.delete(0, 4);
pinCode = pinCode.delete(4, 8);
Log.e("1st Try", pinCode.toString());
Log.e("2nd Try", checkPinCode.toString());
if (checkPinCode.toString().equals(pinCode.toString())) {
tv.setText(R.string.second_text);
Toast.makeText(getActivity(), "Master Password created", Toast.LENGTH_SHORT).show();
savePassword();
pinDialog.dismiss();
} else {
tv.setText(R.string.first_text);
Toast.makeText(getActivity(), "Pins don't match", Toast.LENGTH_SHORT).show();
count = 0;
image1.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image2.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image3.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
image4.setImageResource(R.drawable.ic_radio_button_unchecked_black_24dp);
pinCode.delete(0, pinCode.length());
checkPinCode.delete(0, checkPinCode.length());
pinDialog.dismiss();
}
}
}
Edit: using Ajit Pratap Singh answer
master.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
final boolean switched = ((SwitchPreference) preference).isChecked();
updated = !switched;
mEditor = mUpdated.edit();
mEditor.putBoolean("master_switch", updated);
Log.e("Switch is", String.valueOf(updated));
mEditor.apply();
master.setSummary(!updated ? "Disabled" : "Enabled");
if (updated) {
if (pinDialog != null) {
pinDialog.show();
}
} else {
removePrefs();
}
pinDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
updated = switched;
mEditor = mUpdated.edit();
mEditor.putBoolean("master_switch", updated);
Log.e("Switch after dismiss", String.valueOf(updated));
mEditor.apply();
master.setSummary(!updated ? "Disabled" : "Enabled");
}
});
return true;
}
});
The result is that the switch becomes disabled but the indicator is on:
After edit
When i dismiss it through back dialog it gets disabled but when i create the master password it still remains disabled. this happens due to master.setChecked(false); this line. if i remove it still remains enabled when i dismiss it.
You need to use Dismiss Listener
http://developer.android.com/reference/android/content/DialogInterface.OnDismissListener.html
In other words. I'd like to create editable textfield in fragment, wich after close or stop of app would be saved. But there's something wrong in line with return notatki; I already have this:
public class DetailFragment2 extends Fragment {
private EditText notatki;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("Test", "hello");
}
#SuppressLint("SimpleDateFormat")
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup parent,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.details2, parent, false);
EditText notatki = (EditText) view.findViewById(R.id.editText1);
SharedPreferences settings = this.getActivity().getSharedPreferences("PREFS", 0);
notatki.setText(settings.getString("value", ""));
return notatki;
}
#Override
public void onStop( ){
super.onStop();
if(notatki.getText() != null) {
SharedPreferences settings = this.getActivity().getSharedPreferences("PREFS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("value", notatki.getText().toString());
editor.commit();
}
}
}
When I change return notatki; to return view; it works till the stop of app, when I wanted to save content of editText but it isnt saving anything.
Probably you are setting null to your EditText notatki at:
notatki.setText(settings.getString("value", "raz dwa trzy"));
And thus you have a NPE at onStop() with:
notatki.getText().toString()
To solve this change your onStop() method to:
public void onStop( ){
super.onStop();
if(notatki.getText() != null) {
SharedPreferences settings = this.getActivity().getSharedPreferences("PREFS", 0);
SharedPreferences.Editor editor = settings.edit();
editor.putString("value", notatki.getText().toString());
editor.commit();
}
}
I want to change the background color of my app with a button. It should switch between two colors, for this I used SharedPreference, but >I don't know yet how to store the boolean for switching..
I got this:
public void method1(View view) {
SharedPreferences settings = getSharedPreferences(PREFS, 0);
SharedPreferences.Editor editor = settings.edit();
editor.putBoolean("modus", !modus);
editor.commit();
if (settings.getBoolean("modus", false)) {
int i = Color.GREEN;
LinearLayout layout = (LinearLayout) findViewById(R.id.mylayout);
layout.setBackgroundColor(i);
} else {
int j = Color.BLUE;
LinearLayout layout = (LinearLayout) findViewById(R.id.mylayout);
layout.setBackgroundColor(j);
}
}
To save and get boolean from prefs you can use this :
public class Settings
{
private static final String PREFS_NAME = "com.yourpackage.Settings";
private static final String MODUS = "Settings.modus";
private static final SharedPreferences prefs = App.getContext().getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
private Settings()
{
}
public static void setUseGreen(boolean useGreen)
{
Editor edit = prefs.edit();
edit.putBoolean(MODUS, useGreen);
edit.commit();
}
public static boolean useGreen()
{
return prefs.getBoolean(MODUS, false);
}
}
And then in your Activity just use this :
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.your_layout);
initModus();
}
public void initModus()
{
CheckBox modus = (CheckBox)findViewById(R.id.yourChackBoxId);
modus.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean checked)
{
Settings.setUseGreen(checked);
changeColor(checked);
}
});
boolean useGreen = Settings.useGreen();
modus.setChecked(useGreen);
}
private void changeColor(boolean checked)
{
LinearLayout layout = (LinearLayout) findViewById(R.id.mylayout);
if (useGreen) {
int green = Color.GREEN;
layout.setBackgroundColor(green);
} else {
int blue = Color.BLUE;
layout.setBackgroundColor(blue);
}
}
I have 10 TextViews in my code and i would like to change font size on all of them. On my layout i have used a #style to define common properties however i don't know how to change them all from code once layout is on screen.
What i dont want to do is update N objects but write only in one place. I know that i could use applyTheme but this assumes that you have an XML theme somewhere on disk, i want to be able to scale fonts to any size so this solution is not practical.
Any idea?
See similar questions:
How to programmatically setting style attribute in a view
android dynamically change style at runtime
android : set textView style at runtime
It sounds like its not possible to change an individual style element at runtime. You could apply a different theme, but then you would need a different theme for every font size you want to support. Annoying, but possible.
Otherwise, you have to come up with a way to reduce the pain of updating all of the textViews. You could store the size in your application class, so it is accessible by all of your activities, and then in onCreate update the size for each TextView.
Here is the whole code for dynamically change font size and theme
MainActivity:
public class MainActivity extends AppCompatActivity {
TextView textViewMain;
Button buttonChangeFont;
int size, value;
SharedPreferences pref;
SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
changeTheme();
setContentView(R.layout.activity_main);
//References
textViewMain = findViewById(R.id.textViewMain);
buttonChangeFont = findViewById(R.id.buttonChangeFont);
//Set Onclick on button
buttonChangeFont.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent goToPreview = new Intent(MainActivity.this, PreviewActivity.class);
startActivity(goToPreview);
}
});
int value = pref.getInt("value", 0);
textViewMain.setTextSize(value);
}
private void changeTheme() {
String theme = pref.getString("theme", "default");
if (theme != null && theme.equals("default")) {
setTheme(R.style.AppTheme);
} else if (theme != null && theme.equals("black")) {
setTheme(R.style.BlackTheme);
} else {
setTheme(R.style.BlueTheme);
}
}
public void getSize() {
editor = pref.edit();
size = getIntent().getIntExtra("size", 14);
if (size == 14) {
value = 14;
editor.putInt("value", value);
} else if (size == 20) {
value = 20;
textViewMain.setTextSize(value);
editor.putInt("value", value);
} else {
value = 30;
textViewMain.setTextSize(value);
editor.putInt("value", value);
}
editor.commit();
}
#Override
protected void onStart() {
getSize();
super.onStart();
}
}
PreviewActivity:
public class PreviewActivity extends AppCompatActivity {
TextView textViewSmall, textViewMedium, textViewLarge, textViewPreview;
Button buttonOK;
String size;
int value;
SharedPreferences pref;
SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
setContentView(R.layout.activity_preview);
//TextView References
textViewLarge = findViewById(R.id.textViewLarge);
textViewMedium = findViewById(R.id.textViewMedium);
textViewSmall = findViewById(R.id.textViewSmall);
textViewPreview = findViewById(R.id.textViewPreview);
//Button References
buttonOK = findViewById(R.id.buttonOK);
//Set Onclick listener to TextView and Button
textViewSmall.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textViewPreview.setTextSize(14);
size = "small";
}
});
textViewMedium.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textViewPreview.setTextSize(20);
size = "medium";
}
});
textViewLarge.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
textViewPreview.setTextSize(30);
size = "large";
}
});
buttonOK.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
switch (size) {
case "small":
value = 14;
break;
case "medium":
value = 20;
break;
case "large":
value = 30;
break;
}
Intent i = new Intent(PreviewActivity.this, MainActivity.class);
i.putExtra("size", value);
startActivity(i);
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu options from the res/menu/menu_catalog.xml file.
// This adds menu items to the app bar.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
editor = pref.edit();
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
case R.id.default_theme:
textViewPreview.setBackgroundColor(Color.WHITE);
textViewPreview.setTextColor(Color.DKGRAY);
editor.putString("theme", "default");
editor.commit();
changeTheme();
return true;
case R.id.black_theme:
textViewPreview.setBackgroundColor(Color.BLACK);
textViewPreview.setTextColor(Color.WHITE);
editor.putString("theme", "black");
editor.commit();
changeTheme();
return true;
case R.id.blue_theme:
textViewPreview.setBackgroundColor(Color.BLUE);
textViewPreview.setTextColor(Color.RED);
editor.putString("theme", "blue");
editor.commit();
changeTheme();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void changeTheme() {
String theme = pref.getString("theme", "default");
if (theme != null && theme.equals("default")) {
setTheme(R.style.AppTheme);
} else if (theme != null && theme.equals("black")) {
setTheme(R.style.BlackTheme);
} else {
setTheme(R.style.BlueTheme);
}
}
}
I am using my own custom theme. To create a custom theme you can reference this article on custom theme creation.