Changin layout background from preferences - android

I want to change the background of a layout through what the user selects from a ListPreference in the preferences. I am having a little bit of trouble doing this. I have set up the preferences in my Java:
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
}
and have an array set up for the ListPreference.
This is where I get the string from the preferences to change the background based on what is selected:
SharedPreferences SP = PreferenceManager
.getDefaultSharedPreferences(getBaseContext());
String strFavTeam = SP.getString("keyFavTeam", "0");
LinearLayout linearLayout = (LinearLayout) this.findViewById(R.layout.main);
if(strFavTeam.equals("0")){
linearLayout.setBackgroundResource(R.drawable.first_screen);
}
if(strFavTeam.equals("73")){
linearLayout.setBackgroundResource(R.drawable.tennessee_screen);
}
if(strFavTeam.equals("67")){
linearLayout.setBackgroundResource(R.drawable.georgia_screen);
}
I get a force close every time I choose Tennessee (which has a value of 73) from the ListPreference.
Please help!
Thanks!!

You're searching for a view using a layout id. That's never going to return anything except null. You need to search for the id of the LinearLayout view you want to change. It will be something like R.id.? where ? is whatever id you assigned to the view in main.xml.

Related

Where check if CheckBox that is added dynamically is checked? (Android)

I have added checkboxes dynamically in my onCreate() method. When one or more of them are checked I want two buttons to be displayed. I am new to working with Android, but from what I can tell it won't work to do this check (see if checkboxes are checked) in the same method as the checkboxes are added, i.e. onCreate(), because they can't be found, i.e. haven't been created yet? If this is the case, in what method should I do the check? I want to add the checkboxes at startup of the activity and to check if the boxes are checked all the time.
The checkboxes are added in displayEntries(db).
Here is my onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DatabaseHandler db = new DatabaseHandler(this);
displayEntries(db);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent i = new Intent(MainActivity.this, AddActivity.class); //FromActivity.this
startActivity(i);
}
});
checkChecked();
}
checkChecked():
public void checkChecked() {
//Check whether items have been checked
TableLayout tl = (TableLayout) findViewById(R.id.entry_table);
for (int i = 0; i < tl.getChildCount(); i++) {
View child = tl.getChildAt(i);
if (child instanceof CheckBox) {
CheckBox checkBoxChild = (CheckBox) child;
Log.d("Checkbox", "Checkbox is found");
if (checkBoxChild.isChecked()) {
Log.d("Checkbox", "working!");
Button button1 = (Button) findViewById(R.id.button_edit);
button1.setVisibility(View.INVISIBLE);
Button button2 = (Button) findViewById(R.id.button_delete);
button2.setVisibility(View.INVISIBLE);
}
}
}
}
(At the moment I am trying to make the buttons invisible as you could see above, since I didn't want to "hardcode" in the layout file that they should be invisible to start with - thought that might make it impossible to change? But that's a later question...)
EDIT: I realised my mistake was thinking that the checkboxes where children of my TableLayout. They were in fact children of the rows in the TableLayout. Now that I managed to locate the actual checkbox, I can make the buttons disappear by setting them as invisible when creating them and visible onClick. The remaining problem is that the buttons of course stay visible even if all buttons are unchecked again. Any ideas on how to toggle the buttons on and off depending on if any of the checkboxes are checked or not?
Did not understand your question at first. Please ignore my first answer.
If you want to listen on a check box you might want to try
myCheckBox.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
//do something
}
});
Anything you do in onCreate() will be re-created with each activity cycle.
Therefore you might want to store the state of the check box, and change that state when someone clicks on it.
EDIT after #Ingrid comment:
Looks like there are two problems that need to be solved. One is saving the state and restoring it in on activity/fragment cycle, the other is setting the buttons visible based on condition of N checkboxes.
Assuming you are working with a database object you have an option to use dynamically created check boxes to manipulate the data in your Database Object. The checkboxes represent Boolean values in your DB object or list of objects. Since the checkboxes are dynamic and represent things in your DB, it does not make much sense to store their state in two places. If you do that, things will get out of sync and you will have a nasty bug. Rather rely on the DB object instead. Thus, update your DB object when you click on a checkbox. In onResume() retrieve that DB object (from bundle or DB depending on your architecture) and set your checkboxes / button state based on the state of the DB object.
You can use onPause() to persist your db object. or persist it on click of the check box so your don't have to wary about losing the state in-between. use onResume to setup your UI component base on the current state of the db object. Last but not least, when you update your db object check if you need to show/hide the buttons. (That is if there are on fixed number of buttons but N number of check boxes.
Hope this helps.
//Use shared preference to save.
SharedPreferences preferedName=getSharedPreferences("SavedName", Activity.MODE_PRIVATE);
SharedPreferences.Editor editor = preferedName.edit();
editor.putboolean("SavedName",value);
editor.apply();
editor.commit();
//and to retrive.
SharedPreferences preferedName=getSharedPreferences("SavedName", Activity.MODE_PRIVATE);
boolean chkNull =preferedName.getString("SavedName",false);
and use the boolean as the value of the checkbox.
you can see check CompoundButton because CheckBox inherit from CompoundButton
https://developer.android.com/reference/android/widget/CompoundButton.html#setOnCheckedChangeListener(android.widget.CompoundButton.OnCheckedChangeListener)
checkBoxChild.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
}
});

Activity not updating properly

I'm new to android, so maybe I'm doing something horribly wrong. I want to have a particular Activity that shows details about an instance of a "Creature" class for a game. Name, damage taken, that sort of thing.
I'm having a problem getting the creature data to be properly shown in the GUI objects. Both at initial creation (where it should copy the creature's name into the name field) and when a damage mark is added (where it doesn't update to show the proper image).
Here's my mini-example of what I have:
public class CreatureDetailActivity2 extends Activity
{
Creature creature;
public void addMark(View v)
{
// connected to the button via android:onClick="addMark" in the XML
creature.getTrack().addDamage(DamageType.Normal, 1);
refreshDisplay();
new AlertDialog.Builder(this).setTitle(creature.getName())
.setMessage(creature.getTrack().toString()).show();
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_creature_detail);
creature = new Creature("Example");
refreshDisplay();
}
public void refreshDisplay()
{
final View creatureDetailView = this.getLayoutInflater().inflate(
R.layout.activity_creature_detail, null);
final EditText nameField = (EditText) (creatureDetailView
.findViewById(R.id.textbox_creature_name));
nameField.setText(creature.getName());
final ImageView damageBox0 = (ImageView) (creatureDetailView.findViewById(R.id.damageBox0));
damageBox0.setImageResource(R.drawable.__n);
// in the full program this does the same for 0 through 9, but this is a sample
// also, in the full program, this is a dynamic lookup for the correct pic
// but again, this is just a sample version.
}
}
Now the problem is that the app will load up and start, but then none of the widgets will update properly. You can click the button, and it'll show the AlertDialog, and the text of the AlertDialog will change, but the textfield in the activity won't be changed, and the ImageView doesn't change at any point from what it starts as to the one it's supposed to change to.
So I'm very stumped. I can post more about the project's setup if I'm leaving out something important, but I'm not even sure what the problem going on is so I'm not sure what else to include in my question.
final View creatureDetailView = this.getLayoutInflater().inflate(
R.layout.activity_creature_detail, null);
Inflates your Activity's layout into basically nothing, just returning the View it inflated. setContentView is what actually inflates your layout into the Activity's View hierarchy.
Once you inflate your layout you don't need to do it again. Just use findViewById without the reference to a dangling unattached View.
Change your refreshDisplay method to this:
public void refreshDisplay()
{
final EditText nameField = (EditText) findViewById(R.id.textbox_creature_name);
nameField.setText(creature.getName());
final ImageView damageBox0 = (ImageView) findViewById(R.id.damageBox0);
damageBox0.setImageResource(R.drawable.__n);
// in the full program this does the same for 0 through 9, but this is a sample
// also, in the full program, this is a dynamic lookup for the correct pic
// but again, this is just a sample version.
}
Nothing changes because You do it completely wrong.
If You wish to update any view element of current activity You do it like this
View v = findViewById(R.id.element);
v.setText("text");
this is just simple example.
You would need to cast a returned element to correct type like to be able to access all available methods.
What You do wrong is trying to inflate a layout again.

Is it possible to create a preference screen with PreferenceFragment without using an XML resource?

I am currently able to create a preference screen with a PreferenceFragment, in which I assign my preferences using:
addPreferencesFromResource(R.xml.preferences);
Instead of using the resource 'R.xml.preferences', I would like to use my SharedPreferences i have already saved, for example:
SharedPreferences prefs = this.getActivity().getSharedPreferences("preferences", 0);
addPreferencesFromResource(prefs);
However, this does not work. Is it possible to do this? If so, How? Or is it required that I use an xml document?
I happen to had exactly the same problem but I figured it out, hope this helps.
You need to do the following steps in order to add a Custom Preference without using an XML Reouser
First:
You need to create a Preference Screen, this is as it says a "screen" which can containt several Preferences and must be linked to your PreferenceFragment or PreferenceActivity.
Consider the Following PreferenceFragment for example (and consider it is contained in a superior Activity..)
public static class YourPreferenceFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceScreen p = createPreferences();
this.setPreferenceScreen(p);//Set the PreferenceScreen as the current one on this fragment
//now bind values, notice we use p.findPreference which means whe look into the preferenceScreen Associated with the PreferenceFragment/Activity
bindPreferenceSummaryToValue(p.findPreference("some_key"));
}
}
Now Consider that createPreferences is a method that will return a PreferenceScreen with your custom preferences such as a ListPreference or CheckboxPreference. This is how you really create the preferences and add them into a PreferenceScreen
private PreferenceScreen createPreferences()
{
PreferenceScreen p =
getPreferenceManager().createPreferenceScreen(getActivity());
ListPreference listPref = new ListPreference(getActivity());
listPref.setKey("some_key"); //Refer to get the pref value
CharSequence[] csEntries = new String[]{"Item1","Item2"};
CharSequence[] csValues = new String[]{"1","2"};
listPref.setDefaultValue(-1);
listPref.setEntries(csEntries); //Entries(how you display them)
listPref.setEntryValues(csValues);//actual values
listPref.setDialogTitle("Dialog title");
listPref.setTitle("Title");
listPref.setSummary("Some summary");
p.addPreference(listPref);
return p;
}
Please let me know if this helps
best,
EDIT: Code for bindPreferenceSummaryToValue
private static void bindPreferenceSummaryToValue(Preference preference) {
// Set the listener to watch for value changes.
preference.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
if (preference instanceof CheckBoxPreference) {
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager.
getDefaultSharedPreferences(preference.getContext()).
getBoolean(preference.getKey(),false));
} else {
sBindPreferenceSummaryToValueListener.onPreferenceChange(preference, PreferenceManager.
getDefaultSharedPreferences(preference.getContext()).
getString(preference.getKey(),""));
}
}

Updating checkbox on PreferenceActivity

How do I update my PreferenceActivity?
I've saved in the SharedPreferences the value of my CheckBox in an activity (in that case, true). And even if I go to other activities I can see that it's true. But, when I go to my PreferenceActivity, the checkbox is not checked, it's false. So what I want to know is, how do I load my SharedPreferences in my PreferenceActivity, and how do I update the CheckBox (load the value, and if it's true, set the CheckBox as checked).
Should I load it like this?
Shared Preferences SP = getSharedPreferences(DATA, MODE_PRIVATE);
fw = SP.getBoolean("fw", false);
But, how do I set the CheckBox true or false since I can't use findViewById?
EDIT:
Activity where I save the CheckBox value:
Editor edit = SP.edit();
edit.putBoolean("fw", fwbt.isChecked());
edit.commit();
My preference xml file:
<CheckBoxPreference
android:title="CheckBox FW"
android:key="fw"
android:summary="Estado do CheckBox" />
My preference Activity:
public class Prefs extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
//Don't know what to do here...
}
}
You need to create an Editor to modify the SharedPreferences.
Example
getSharedPreferences(DATA, MODE_PRIVATE).edit().putBoolean("fw", true).commit();
Update
You need to define the used SharedPreferences in the Activity, too.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(DATA);
addPreferencesFromResource(R.xml.prefs);
}
I have not use PreferenceActivity before but I think you simply need to implement it like any other activity.
public class PreferenceWithHeaders extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
CheckBox cb = (CheckBox)this.findViewById(IDOFBUTTON);
... do whatever on checkbox
}
I can't find a solution, so I gave up. I've just created created a custom Preferences, it's way easier.
Anyway, I'll keep looking for a solution for this later.
You've mess it up - the PreferenceActivity writes/reads from the SharedPreferences. So in your activity do
Shared Preferences SP = PreferenceManager.getDefaultSharedPreferences(this);
Editor edit = SP.edit();
edit.putBoolean("fw", fwbt.isChecked());
edit.commit();
and the change should be there in your PreferenceActivity.
Also :
SP.edit().putBoolean("fw", fwbt.isChecked()).commit();
will do

Change background image on user's choice

Guys I want the user to change the background image of all the activities in my app on user selection.
I am able to change the background image of the Activity from where am changing the image
but if I try to change the image of other Activity, I get a NullPointerException!
Yes, I have checked that the id of other activity's Layout !
this is the code.
public class setting extends Activity {
TextView tv;
CheckBox cbS, theme1, theme2;
RelativeLayout rel;
OnClickListener checkBoxListener;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setting);
cbS = (CheckBox) findViewById(R.id.cb);
theme1 = (CheckBox) findViewById(R.id.theme1);
theme2 = (CheckBox) findViewById(R.id.theme2);
// cbW=(CheckBox)findViewById(R.id.cbWordPress);
checkBoxListener = new OnClickListener() {
public void onClick(View v) {
if (cbS.isChecked()) {
// anything
}
if (theme2.isChecked()) {
RelativeLayout rel = (RelativeLayout) findViewById(R.id.rel);
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.back_image1);
rel.setBackgroundDrawable(drawable);
// findViewById(R.id.rel).setBackgroundResource(R.drawable.back_image1);
}
}
};
cbS.setOnClickListener(checkBoxListener);
theme2.setOnClickListener(checkBoxListener);
// cbW.setOnClickListener(checkBoxListener);
}
}
you cannot access the UI components which are not yet instantiated. Use Intents to pass information across activities (user's choice, or some custom flags or Strings) and use this "extra" information in the launched activity to change the background accordingly.
Read more about intents in the documentation for better understanding and examples.
You cannot do this.. When you refer a layout file using findViewById(), the android system looks for this in your current ContentView only. (i.e the view which you have set using setContentView() for the current activity). So obvioulsy the sytem will not be able find the resource you are specifying and hence you will get the NullPointerExeption only.
You have to maintain the reference to the backgrounds separately and use it in your other Activity when you actually pass on there.

Categories

Resources