Programatically make LinearLayout dismissible in android studio using shared preference - android

There is this thing I want to achieve, I have searched all questions on SO and no answer related to this, so I guess no one has asked which makes me curious.
On my XML, Android studio app, I added a Linear Layout, under the Linear layout, I added a 《TextView with text "Dismiss"》.
I want to set an onclick listener to this textview, once user clicks this TextView with text "Dismiss" I don't want that user to see that Linear Layout again on the page until they reinstall the app.
Logically, the Linear Layout will be like a notice to highlight something on my app when users arrive at that page, but instead of that notice to stay there forever I want user to be able to dismiss it which shows they have gotten the notice.
My workings:
Since I want each app user to decide not to see that text again after clicking dismiss, I need to use shared preference on that TextView with text "Dismiss", so whenever app gets the value of this shared preference then it will hide that layout.
I can set the LinearLayout to be invisible if that value from shared preference is found when stored on the app
The question now, how will I set this shared preference and which code will I use to make the Layout "GONE" or "INVISIBLE" if the TextView with text "Dismiss" is clicked?
Your intelligent solution to this will be much appreciated.

check this out , its in Java, and this will hide the layout after clicking the dismisstextview and when u re open it alert will still be hidden.
public class MainActivity extends AppCompatActivity {
SharedPreferences sharedPref;
SharedPreferences.Editor editor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sharedPref = getSharedPreferences(getApplicationContext().getPackageName(),0);
editor = sharedPref.edit();
LinearLayout alertLayout = (LinearLayout)findViewById(R.id.alertLayout);
TextView textViewDismiss = (TextView)findViewById(R.id.textViewDismiss);
if(sharedPref.getBoolean("isLayoutAlertShown",false)){
alertLayout.setVisibility(View.GONE);
}else{
alertLayout.setVisibility(View.VISIBLE);
}
textViewDismiss.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
alertLayout.setVisibility(View.GONE);
editor.putBoolean("isLayoutAlertShown",true);
editor.apply();
}
});
}
}

I would recommend you to use SharedPreferences since this is related to setting matter. You can refer to this link: https://developer.android.com/training/data-storage/shared-preferences#java
You have to call this method at the onCreate. So it will check if the there is showLayout stated true or false, then it will update the design.
//Inside onCreate
private void initSharedPreference(final Activity activity, final LinearLayout linearLayout) {
final SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
if (sharedPref.getBoolean("showLayout", false)) {
linearLayout.setVisibility(View.GONE);
} else {
linearLayout.setVisibility(View.VISIBLE);
}
}
At the setOnClickListener you need to implement this method.
//At the button
private void setSharedPrefShowLayout(final Activity activity, final Boolean isVisible) {
final SharedPreferences sharedPref = activity.getPreferences(Context.MODE_PRIVATE);
final SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean("showLayout", isVisible);
editor.apply();
}

Related

Android Studio: Try to change Background based on Shared Pref, but reset to default background when force close

So, i try to change Background based on Shared Preference onCreate like this:
**strong text**
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setting);
prefManager = new PrefManager(this);
String imagename = prefManager.getBg();
if (imagename=="1") {
RelativeLayout settinglin = (RelativeLayout) findViewById(R.id.settinglin);
settinglin.setBackgroundResource(R.drawable.lginbg);
} else if(imagename=="2") {
RelativeLayout settinglin = (RelativeLayout) findViewById(R.id.settinglin);
settinglin.setBackgroundResource(R.drawable.lginbgload);
etc...
It work fine for this function but the problem is, when the application force close it always return the background picture to the default background (in layout)
for example:
android:background="#drawable/lginbg"
I check the value of my shared Preference is not reset when force close (so the problem isn't in shared preference)
Can someone help me please with this problem

Add preferences to specific places in PreferenceScreen programmatically

I am populating parts of my preferences programmatically. This works fine. Unfortunately new preferences there has to be added, when the user changes some preferences (think of an 'add a new alarm'-preference). This works fine as well, when I use PreferenceCategories (because the new ones are added at the end of one such, so myPreferenceCategory.addPreference(newPreference) does the trick). But what can I do to programmatically add a Preference to any specific place (not just the end of usual categories/the prefScreen??
I tried to use some kind of "invisible" PreferenceCategory, by setting android:layout="my_custom_invis_layout" with
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/my_custom_invis_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingBottom="0dp"
android:paddingTop="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"/>
Unfortunately those padding and margin does not seem to have an impact on the minimum space the empty category take (but do so with positive values, which is - of cause - of no help).
I tried as well to nullify the layout by
<PreferenceCategory
android:layout="#null">
but this just enlarges the space the category takes to those the other preferences have.
Unfortunately SO did not help me on this so far. I would be very happy if anyone can point me to something like "add a preference A below preference B" or on how to make a category taking no space at all (as this would resolve my problem as well).
I see this question is quite old, but since I was facing a similar problem and managed to solved it, I figured there would be no harm done by posting anyway.
The way I solved this is by adding the Preference (in my case a category that needed to be added in a particular spot amongst the other categories) in xml from the start, removing it programmatically if not yet needed. When putting it back (programmatically) afterwards, it appears at the same position it was before removing it. Haven't tried your particular case (with single Preferences needing to go in a particular spot within a category), but I bet it works the same way.
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
private PreferenceCategory mPreferenceCategory;
#Override
public void onCreatePreferences(#Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
if (preferenceNotRequiredYet) {
removePreferenceCategory();
}
// an I have a SharedPreferenceListener attached that calls
// addPreferenceCategory when I need to add it back
}
private void removePreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.removePreference(mPreferenceCategory);
}
private void addPreferenceCategory() {
PreferenceScreen parentScreen = (PreferenceScreen) findPreference("parent_screen_key");
parentScreen.addPreference(mPreferenceCategory);
}
}
Ok, I've tried that other approach with Preferences#setOrder(int). (I left the previous answer there, cause for some use cases it might be the easier solution.) Does this one better suit your needs?
public class PreferencesFragment extends PreferenceFragmentCompat {
private SharedPreferences mSharedPreferences;
PreferenceCategory mMyPreferenceCategory;
// ArrayList to keep track of the currently added Preferences
ArrayList<Preference> mPreferenceList = new ArrayList<>();
// this counter only serves for name-giving of the added
// Preferences in this example
int mCounter = 0;
#Override
public void onCreatePreferences(#Nullable Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.preferences);
mMyPreferenceCategory = (PreferenceCategory) findPreference("preferenceCategoryKey");
addPreference(null);
}
// adds a Preference that is inserted on the position of the
// clicked Preference, moving the clicked Preference - and all
// Preferences after - one position down
private void addPreference(Preference pref) {
int order = 0;
if (pref != null) {
order = pref.getOrder();
}
for (Preference preference : mPreferenceList) {
int oldOrder = preference.getOrder();
if (oldOrder >= order) {
preference.setOrder(oldOrder+1);
}
}
Preference newPreference = new Preference(getContext());
newPreference.setTitle("Preference " + mCounter);
newPreference.setOrder(order);
newPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
addPreference(preference);
return false;
}
});
mMyPreferenceCategory.addPreference(newPreference);
mPreferenceList.add(newPreference);
mCounter++;
}
}

How to retain changed button text in android?

In my project I have one edit text and one button.
When the project loads and I press the button,
the text of the button changes to the value of edit text.
But when I press the back button the change of button text does not persist.
I have included the snapshot which can describe my problem better.
I basically want the button text change to persist.
Please help.
The text doesn't show up on reopening the app because it was stored temporarily and when you closed your app it got destroyed. To retain the text you can store it in shared preference or file and on app startup load the text of the button from that source and if source is not present(When opening app for the first time) then put the default text on the button.
In your activity onCreate () method, you can add this code:
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
String btnText = preferences.getString("btnText", "");
if(!btnText.equalsIgnoreCase(""))
{
yourButton.setText(btnText);
}
yourButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("btnText",yourTextEdit.getText().toString());
editor.apply();
....your code
}
});
In your layout xml file, set your button default text. android:text="#string/yourtext"
You need to save the text somewhere and load it when the activity starts. There are various ways to do this but I think Shared Preferences will work for you.
In the on click function for the button set the Shared Preference and in the Activity's onCreate check if the same Shared Preference is set. If the value is present load it else load the default value.
When you press the button for first time after getting text from edit text use the following code to save the edit text text that to be set on button in shared prefrences:
In on Button Click method:
EditText et = (EditText) findViewById(....);
String text = et.getTex().toString();
then you set it on button and so..
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE).edit();
editor.putString("buttonText", text);
editor.commit();
then when you relauch the app in onCreate method use the following code:
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
String value= prefs.getString("buttonText", "");
button.setText(value); //whatever you button is

Android: checkbox.isChecked() is always returning a false condition

I'm trying to code a checkbox into a help screen which is essentially a pop up view (an activity that's started by the main program) containing a ScrollView that has the help text, and OK button, and a checkbox that asks if you want the help screen to appear automatically at program start. Everything displays properly on the screen, and the checkbox toggles, when touched. However, when OK is pressed, and I test the state of the checkbox with .isChecked() I'm always getting a false. I'm sure it's something simple I've missed. XML file follows follows:
helpdialog.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="wrap_content"
android:background="#ffffff">
<ScrollView android:id="#+id/ScrollView01"
android:layout_width="wrap_content" android:layout_below="#+id/ImageView01"
android:layout_height="300px">
<TextView android:text="#+id/helpView" android:id="#+id/helpView"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:textColor="#000000"/>
</ScrollView>
<Button android:id="#+id/Button01"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_centerHorizontal="true" android:text=" OK "
android:layout_below="#id/ScrollView01"/>
<CheckBox android:id="#+id/chkNoHelp" android:textColor="#000000"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:text="Don't Display at Startup"
android:layout_below="#id/Button01" />
</RelativeLayout>
HelpBox.java:
public class HelpBox extends Activity {
CheckBox checkBox;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//set up dialog
Dialog dialog = new Dialog(this);
dialog.setContentView(R.layout.helpdialog);
dialog.setTitle("Help");
dialog.setCancelable(true);
//set up text
TextView text = (TextView) dialog.findViewById(R.id.helpView);
text.setText(getString(R.string.help_text));
//set up button
Button button = (Button) dialog.findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Boolean mDisplayHelp;
setContentView(R.layout.helpdialog);
checkBox = (CheckBox) findViewById(R.id.chkNoHelp);
if (checkBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
finish();
}
});
//now that the dialog is set up, it's time to show it
dialog.show();
}
}
Setting breakpoints on both "mDisplayHelp" lines always breaks at the 'false' branch regardless of whether the check box displays a green check or not when the OK button is pressed.
Thanks in advance.
Edit (10/10):
Its clear what I want to do is pick up information after the user exits the dialog, so I can sense the state of the checkbox and store it as a preference. For this I assume I have to test it in onDestory. So, I did that:
#Override
public void onDestroy() {
Boolean mDisplayHelp;
setContentView(R.layout.helpdialog);
checkBox = (CheckBox) findViewById(R.id.chkNoHelp);
if (checkBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
}
However, I'm still always coming up with FALSE as a result, regardless of whether the checkbox is display checked or off. In this instance, if I don;t include the setContentView, I get a NullPointerException on the isChecked.
Why are you calling setContentView a second time? After the second time you call it, your checkbox is being reset to unchecked (the default state) and then you are immediately checking its state to set a flag.
Its not clear what your intention is here by inflating helpdialog.xml twice, once in a Dialog and once in your main Activity. It sounds like you want to use a dialog-themed activity here and only call setContentView() once in onCreate. It should behave as expected after that.
I finally figured this out, and boy was I going about things the wrong way. Chalk it up to learning curve.
What I needed to do was save the checkbox state. I needed to use SharedPreferences for that. I needed to detect when the checkbox was touched by using a listener on it and then saving the preference at that time. Upon opening the help box, I load the preference state and set the check box to that state so it shows properly based on the user's previous setting.
Finally, load the preference in onCreate at the main activity and call the showHelpBox() if the preference was so set.
In onCreate of main activity:
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
Boolean mDisplayHelp = prefs.getBoolean("checkboxPref", false);
if (mDisplayHelp == false)
showHelpBox();
In help box activity pre-initialize the check box based on previous setting:
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
mDisplayHelp = prefs.getBoolean("checkboxPref", false);
final CheckBox ckBox = (CheckBox) dialog.findViewById(R.id.chkNoHelp);
ckBox.setChecked(mDisplayHelp);
When checkbox is touched:
ckBox.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (ckBox.isChecked()) {
mDisplayHelp = true;
} else {
mDisplayHelp = false;
}
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("checkboxPref", mDisplayHelp);
// Don't forget to commit your edits!!!
editor.commit();
}
});
Hopefully others can learn from my foolish mistakes and misunderstanding.

How to show and hide preferences on Android dynamically?

Is there a way to dynamically show and hide preferences? In my case, I have a checkbox preference that would disable or enable one of 2 preference groups ("with-" and "without-handicap" groups). While this would be the ideal GUI in a desktop environment, the "with-handicap" takes up nearly the whole screen, while the other, "without-handicap" takes up only a small portion of the screen.
Rather than showing both groups at the same time, I'd like to show only one of them at a time, and dynamically show or hide the 2 groups when the checkbox changes. Is there a way to do this?
From a PreferenceActivity call
Preference somePreference = findPreference(SOME_PREFERENCE_KEY);
PreferenceScreen preferenceScreen = getPreferenceScreen();
preferenceScreen.removePreference(somePreference);
you can later call:
preferenceScreen.addPreference(somePreference);
The only a little bit tricky part is getting the order correct when adding back in. Look at PreferenceScreen documentation, particularly it's base class, PreferenceGroup for details.
Note: The above will only work for immediate children of a PreferenceScreen. If there is a PreferenceCategory in between, you need to remove the preference from its parent PreferenceCategory, not the PreferenceScreen. First to ensure the PreferenceCategory has an android:key attribute set in the XML file. Then:
Preference somePreference = findPreference(SOME_PREFERENCE_KEY);
PreferenceCategory preferenceCategory = (PreferenceCategory) findPreference(SOME_PREFERENCE_CATEGORY_KEY);
preferenceCategory.removePreference(somePreference);
and:
preferenceCategory.addPreference(somePreference);
Not exactly hiding/showing but if you only want disabling/enabling preference depending on another preference you can specify android:dependency="preferenceKey" or Preference.setDependency(String)
Example from developer.android.com:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<CheckBoxPreference
android:key="pref_sync"
android:title="#string/pref_sync"
android:summary="#string/pref_sync_summ"
android:defaultValue="true" />
<ListPreference
android:dependency="pref_sync"
android:key="pref_syncConnectionType"
android:title="#string/pref_syncConnectionType"
android:dialogTitle="#string/pref_syncConnectionType"
android:entries="#array/pref_syncConnectionTypes_entries"
android:entryValues="#array/pref_syncConnectionTypes_values"
android:defaultValue="#string/pref_syncConnectionTypes_default" />
</PreferenceScreen>
I recommend using V7 preference, it has setVisible() method. But I have not tried it yet.
If you want to implement the hiding of the preference completely in the Preference, here is one example. Does not allow to make it visible again, though.
public class RemovablePreference extends Preference {
#Override
protected void onBindView(View view) {
super.onBindView(view);
updateVisibility(); // possibly a better place available?
}
private void updateVisibility() {
Context context = getContext(); // should be a PreferenceActivity
if (context instanceof PreferenceActivity) {
updateVisibility((PreferenceActivity)context);
}
}
private void updateVisibility(PreferenceActivity activity) {
updateVisibility(getPreferenceScreen(activity));
}
private PreferenceScreen getPreferenceScreen(PreferenceActivity activity) {
if (activity.getPreferenceScreen() != null) {
return activity.getPreferenceScreen(); // for old implementations
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
Fragment fragment = activity.getFragmentManager().findFragmentById(android.R.id.content);
if (fragment instanceof PreferenceFragment) {
return ((PreferenceFragment) fragment).getPreferenceScreen();
}
}
return null;
}
private void updateVisibility(PreferenceScreen screen) {
if (!isVisible() && screen != null) {
hidePreference(screen, this);
}
}
private boolean hidePreference(PreferenceGroup prefGroup, Preference removedPreference) {
boolean removed = false;
if (prefGroup.removePreference(removedPreference)) {
removed = true;
}
for (int i = 0; i < prefGroup.getPreferenceCount(); i++) {
Preference preference = prefGroup.getPreference(i);
if (preference instanceof PreferenceGroup) {
PreferenceGroup prefGroup2 = (PreferenceGroup)preference;
if (hidePreference(prefGroup2, this)) {
// The whole group is now empty -> remove also the group
if (prefGroup2.getPreferenceCount() == 0) {
removed = true;
prefGroup.removePreference(prefGroup2);
}
}
}
}
return removed;
}
protected boolean isVisible() {
return true; // override
}
I needed something similar: toggling a switch to hide or show two extra preferences. Check out the sample app from Android-Support-Preference-V7-Fix which bring some new preference types and fixes some issues from the official library. There's an example there to toggle a checkbox to show or hide a preference category.
In the fragment that extends PreferenceFragmentCompatDividers, you could use something like:
findPreference("pref_show_extra_stuff").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
findPreference("pref_extra_stuff_01").setVisible((Boolean) newValue);
findPreference("pref_extra_stuff_02").setVisible((Boolean) newValue);
return true;
}
});
pref_extra_stuff_01 and pref_extra_stuff_02 are the two preferences that are hidden when pref_show_extra_stuff is toggled.
For hiding preferences dynamically, I created an if-condition upon whose value I decide whether I want the pref to show or not. To do the actual hiding, I have been using:
findPreference(getString(R.string.pref_key)).setLayoutResource(R.layout.hidden);
The tricky part is to make it visible again. There is no direct way to do it except to recreate the layout. If the value of the if-condition is false, which means the pref should be visible, then the code to hide the pref will never be executed, thus resulting in a visible pref. Here is how to recreate the layout (in my case, I am extending a PreferencesListFragment):
getActivity().recreate();
I hope that was helpful.
Instead of doing this in onCreate in the settings activity:
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, new SettingsFragment()).commit();
You can initialize a global variable for the settings fragment and set it up like this:
settingsFragment = new SettingsFragment();
getSupportFragmentManager().beginTransaction()
.replace(R.id.settings_container, settingsFragment).commit();
Then further down you can set up an OnSharedPreferenceChangeListener with a global SharedPreferences.OnSharedPreferenceChangeListener to set up what should be shown or hidden when you change preferences:
// Global SharedPreferences.OnSharedPreferenceChangeListener
sharedPreferenceChangeListener = new SharedPreferences.OnSharedPreferenceChangeListener()
{
Override
public void onSharedPreferenceChanged(SharedPreferences preferences, String key)
{
if (key.equals("switch key"))
{
boolean newPref = preferences.getBoolean("switch key", true);
settingsFragment.findPreference("seekbar key").setVisible(newPref);
}
}
};
sharedPreferences.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
Then in onCreate in the settings fragment you can do something like this to set what should be hidden based on existing preferences:
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
if (!sharedPreferences.getBoolean("switch key", true)
{
SeekBarPreference seekBarPreference = findPreference("seekbar key");
seekBarPreference.setVisible(false);
}

Categories

Resources