hello everyone i am new to android development.i want to open a alert dialog when user choose any theme in list preference in preference activity.i search lot in google but did not find any appropriate answer.here is my PrefenceActivity.
public class Setting extends PreferenceActivity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
Setting.setAppTheme(this);
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.prefs);
}
String ListPreference;
public static void setAppTheme(Activity a) {
// Get the xml/preferences.xml preferences
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(a);
int ListPreference = Integer.parseInt(prefs.getString("listPref", "3"));
if(ListPreference == 0) {
a.setTheme(R.style.AppBaseThemeDark);
return;
} else if(ListPreference == 1){
a.setTheme(R.style.AppBaseThemeLight);
//Toast.makeText(getApplicationContext(),"TTS Engines not found.\n Install TTS Engins",Toast.LENGTH_LONG).show();
} else if(ListPreference == 2){
a.setTheme(R.style.AppBaseTheme);
}
}
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
getActionBar().setDisplayHomeAsUpEnabled(true);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in action bar clicked; go home
getFragmentManager().popBackStack();
finish();
return true;
}
return super.onOptionsItemSelected(item);
}
}
I faced the same problem a few days ago and I implemented a custom preference class extending ListPreference to do this. This is the class I implemented:
public class LogCleanPreference extends ListPreference {
private int mClickedDialogEntryIndex;
private Context mContext;
public LogCleanPreference(Context ctxt) {
this(ctxt, null);
}
public LogCleanPreference(Context ctxt, AttributeSet attrs) {
super(ctxt, attrs);
mContext = ctxt;
setNegativeButtonText(ctxt.getString(R.string.alert_cancel));
}
#Override
protected void onPrepareDialogBuilder(Builder builder) {
if (getEntries() == null || getEntryValues() == null) {
throw new IllegalStateException(
"ListPreference requires an entries array and an entryValues array.");
}
mClickedDialogEntryIndex = findIndexOfValue(getValue());
builder.setSingleChoiceItems(getEntries(), mClickedDialogEntryIndex,
new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, final int which) {
// In my case I only show the AlertDialog if the user didn't select option number 2
if(which != 2){
// Show AlertDialog
}
else{
// Save preference and close dialog
mClickedDialogEntryIndex = which;
LogCleanPreference.this.onClick(dialog, DialogInterface.BUTTON_POSITIVE);
dialog.dismiss();
}
}
});
builder.setPositiveButton(null, null);
}
#Override
protected void onDialogClosed(boolean positiveResult) {
CharSequence[] mEntryValues = getEntryValues();
if (positiveResult && mClickedDialogEntryIndex >= 0 && mEntryValues != null) {
String value = mEntryValues[mClickedDialogEntryIndex].toString();
if (callChangeListener(value)) {
setValue(value);
}
}
}
}
This is how I use the preference in my prefs.xml:
<com.timeondriver.tod.settings.LogCleanPreference
android:defaultValue="0"
android:dialogTitle="#string/dialog_title_log_clean"
android:entries="#array/log_clean"
android:entryValues="#array/log_clean_values"
android:key="log_clean_preference"
android:summary="#string/summary_log_clean_preference"
android:title="#string/title_log_clean_preference" />
1st, Create a change listener:
private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
String stringValue = value.toString();
if (preference instanceof ListPreference) {
// For list preferences, look up the correct display value in
// the preference's 'entries' list.
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(stringValue);
// Set the summary to reflect the new value.
preference
.setSummary(index >= 0 ? listPreference.getEntries()[index]
: null);
}
return true;
}
};
2nd, Bind preference to its value:
// Set the listener to watch for value changes.
preference
.setOnPreferenceChangeListener(sBindPreferenceSummaryToValueListener);
// Trigger the listener immediately with the preference's
// current value.
sBindPreferenceSummaryToValueListener.onPreferenceChange(
preference,
PreferenceManager.getDefaultSharedPreferences(
preference.getContext()).getString(preference.getKey(),
""));
3rd, in the 1st step you can insert the code to launch you dialog with the if condition.
Related
My items for Listview are not showing, can someone point me where is the error.
There is no error when adding items but its not showing on the Listview. I revised my post, I'm trying to use BaseAdapter to populate the items. I can confirm that the items are added to the database because the total amount is updated everytime i add item.
public class ViewTransactions extends Activity {
private ListView mListViewTransactions;
private TransactionAdapter mAdapter;
private List<TransactionModel> mListTransactions;
/** transactions data source. */
private TransactionDao transactionSource;
/** Currently selected broker, as specified by intent received from ViewBrokers class. */
private BrokerModel currentBroker;
/** The sum total of all transactions for the active broker. */
private BigDecimal brokerTotal;
private ArrayAdapter<TransactionModel> aa;
/** Action mode for the context menu. */
private ActionMode aMode;
/** Call back methods for the context menu. */
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
/** Title which displays broker name. */
private TextView title;
// Called when the action mode is created; startActionMode() was called
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
// Inflate a menu resource providing context menu items
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_transactions, menu);
// disable listener here; moved from onPrepareActionMode
title = (TextView) findViewById(R.id.exCat);
title.setClickable(false); // prevent navigation away from activity
return true;
}
// Called each time the action mode is shown. Always called after onCreateActionMode, but
// may be called multiple times if the mode is invalidated.
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
title = (TextView) findViewById(R.id.exCat);
title.setClickable(false); // prevent navigation away from activity
return false; // Return false if nothing is done
}
// Called when the user selects a contextual menu item
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
switch (item.getItemId()) {
case R.id.action_edit:
// edit selected expense
editTransaction();
mode.finish(); // Action picked, so close the CAB
return true;
case R.id.action_del:
// delete selected expense
deleteTransaction();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
// Called when the user exits the action mode
#Override
public void onDestroyActionMode(ActionMode mode) {
// unselect item that was selected (if it wasn't deleted)
final ListView lv = (ListView)findViewById(R.id.tList);
lv.clearChoices();
lv.setItemChecked(lv.getCheckedItemPosition(), false);
lv.post(new Runnable() {
#Override
public void run() {
lv.setChoiceMode(ListView.CHOICE_MODE_NONE);
}
});
aMode = null;
title.setClickable(true); // restore broker name click
}
};
/**
* Class to asynchronously retrieve transactions from database.
*/
private class GetTransactions extends AsyncTask<Void, Void, List<TransactionModel>> {
#Override
protected List<TransactionModel> doInBackground(Void... params) {
// retrieve all transactions for the user and broker
return transactionSource.getTransactions(currentBroker);
}
#Override
protected void onPostExecute(final List<TransactionModel> result) {
mAdapter = new TransactionAdapter(ViewTransactions.this, mListTransactions);
mListViewTransactions.setAdapter(mAdapter);
mListViewTransactions.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
// Called when the user long-clicks on an item
public boolean onItemLongClick(AdapterView<?> aView, View view, int i, long l) {
if (aMode != null) {
return false;
}
mListViewTransactions.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
// mark item at position i as selected
mListViewTransactions.setItemChecked(i, true);
// Start the CAB using the ActionMode.Callback defined above
aMode = ViewTransactions.this.startActionMode(mActionModeCallback);
return true;
}
});
}
}
/**
* Class to asynchronously add new expense to database.
*/
private class AddTransaction extends AsyncTask<String, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(String... params) {
return transactionSource.newTransaction(params[0], new BigDecimal(params[1]), params[2],
currentBroker);
}
#Override
protected void onPostExecute(TransactionModel result) {
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
mAdapter = new TransactionAdapter(ViewTransactions.this, mListTransactions);
// mAdapter.add(result);
mAdapter.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.add(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Class to asynchronously edit an expense in database.
*/
private class EditTransaction extends AsyncTask<TransactionModel, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(TransactionModel... params) {
return transactionSource.editTransaction(params[0]);
}
#Override
protected void onPostExecute(TransactionModel result) {
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
aa.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.add(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Class to asynchronously delete an expense from database.
*/
private class DeleteTransaction extends AsyncTask<TransactionModel, Void, TransactionModel> {
#Override
protected TransactionModel doInBackground(TransactionModel... params) {
return transactionSource.deleteTransaction(params[0]); // delete selected item from db
}
#Override
protected void onPostExecute(TransactionModel result) {
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
aa.remove(result); // remove selected item from adapter
aa.notifyDataSetChanged();
// update total
brokerTotal = brokerTotal.subtract(result.getTransactionAmount());
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
}
}
/**
* Method to record a new expense. Called when Add button in action bar is clicked.
*/
private void addTransaction() {
// build dialog to ask for expense details
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Record Transaction");
builder.setMessage("Please enter transaction details.");
// construct input fields
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
final EditText enterDate = new EditText(this);
final EditText enterCost = new EditText(this);
final EditText enterDesc = new EditText(this);
enterDate.setHint("Date");
enterCost.setHint("Amount");
enterDesc.setHint("Transaction");
enterDate.setInputType(InputType.TYPE_CLASS_DATETIME); // date text
enterDate.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
enterCost.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED); // to accept dollar amount
enterCost.setKeyListener(DigitsKeyListener.getInstance("0123456789.-")); // accept digits
enterDesc.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); // description text
enterDesc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
ll.addView(enterDate);
ll.addView(enterCost);
ll.addView(enterDesc);
builder.setView(ll);
// add ok and cancel buttons
builder.setPositiveButton(R.string.ok, null);
builder.setNegativeButton(R.string.cancel, null);
// create dialog
final AlertDialog dia = builder.create(); // don't show yet
// set listener to description input field to click OK when done
enterDesc.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set listener to date input field to click OK when done
enterDate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set input mode to let keyboard appear when dialog is shown
dia.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dia.show();
// override onclick for OK button; must be done after show()ing to retrieve OK button
dia.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// retrieve name entered
String date = enterDate.getText().toString().trim();
String cost = enterCost.getText().toString().trim();
String desc = enterDesc.getText().toString().trim();
// perform checks and add if pass
if (cost.equals("")) { // must not be empty
enterCost.setError("Please enter an amount.");
//} else if (!Pattern.matches("^(\\d{1,10})?(\\.\\d{0,2})?$", cost)) { // must be $$
// enterCost.setError("Please enter a valid amount.");
} else {
// can be added
new AddTransaction().execute(date, cost, desc);
dia.dismiss();
}
}
});
}
/**
* Method to edit selected expense. Called when Edit button is clicked in context menu.
*/
private void editTransaction() {
// retrieve adapter and retrieve selected expense
// ListView lv = getListView();
#SuppressWarnings("unchecked")
// final ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
// final TransactionModel exToEdi = aa.getItem(lv.getCheckedItemPosition()); // get item at checked pos
// build dialog to ask for expense details
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Edit Transaction");
builder.setMessage("Please enter transaction details.");
// construct input fields
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
final EditText enterDate = new EditText(this);
final EditText enterCost = new EditText(this);
final EditText enterDesc = new EditText(this);
// enterDate.setText(exToEdi.getTransactionDate());
// enterCost.setText(exToEdi.getTransactionAmount().toString());
// enterDesc.setText(exToEdi.getTransactionDescription());
enterDate.setInputType(InputType.TYPE_CLASS_DATETIME); // description text
enterDate.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
enterCost.setInputType(InputType.TYPE_CLASS_NUMBER); // to accept dollar amount
enterCost.setKeyListener(DigitsKeyListener.getInstance("0123456789.")); // accept digits
enterDesc.setInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES); // description text
enterDesc.setFilters(new InputFilter[]{new InputFilter.LengthFilter(40)});
ll.addView(enterDate);
ll.addView(enterCost);
ll.addView(enterDesc);
builder.setView(ll);
// add ok and cancel buttons
builder.setPositiveButton(R.string.ok, null);
builder.setNegativeButton(R.string.cancel, null);
// create dialog
final AlertDialog dia = builder.create(); // don't show yet
// set listener to description input field to click OK when done
enterDesc.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set listener to date input field to click OK when done
enterDate.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
boolean handled = false;
if (actionId == EditorInfo.IME_ACTION_DONE) {
// click dialog's OK when user presses Done on keyboard
dia.getButton(Dialog.BUTTON_POSITIVE).performClick();
handled = true;
}
return handled;
}
});
// set input mode to let keyboard appear when dialog is shown
dia.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
dia.show();
// override onclick for OK button; must be done after show()ing to retrieve OK button
dia.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// retrieve name entered
String date = enterDate.getText().toString().trim();
String cost = enterCost.getText().toString().trim();
String desc = enterDesc.getText().toString().trim();
// perform checks and add if pass
if (cost.equals("")) { // must not be empty
enterCost.setError("Please enter a dollar amount.");
//} else if (!Pattern.matches("^(\\d{1,10})?(\\.\\d{0,2})?$", cost)) { // must be $$
// enterCost.setError("Please enter a valid dollar amount.");
} else {
// can be changed
// brokerTotal = brokerTotal.subtract(exToEdi.getTransactionAmount());
// exToEdi.setTransactionAmount(new BigDecimal(cost));
// exToEdi.setTransactionDescription(desc);
// exToEdi.setTransactionDate(date);
// new EditTransaction().execute(exToEdi);
dia.dismiss();
}
}
});
}
/**
* Method to delete selected expense. Called when Delete button is clicked in context menu.
*/
private void deleteTransaction() {
// get list view and list adapter
// ListView lv = getListView();
// #SuppressWarnings("unchecked")
// ArrayAdapter<TransactionModel> aa = (ArrayAdapter<TransactionModel>) getListAdapter();
// int pos = lv.getCheckedItemPosition(); // get pos of selected item
// TransactionModel del = aa.getItem(pos); // get item in adapter at position pos
// new DeleteTransaction().execute(del); // delete expense async and update total
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.capital_activity_view_transactions);
initViews();
currentBroker = (BrokerModel) getIntent().getSerializableExtra(IntentTags.CURRENT_BROKER);
// set totalCost = ; here
// set title to broker
TextView title = (TextView) findViewById(R.id.exCat);
title.setText(currentBroker.getBroker());
title.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent it = new Intent(ViewTransactions.this, ViewBrokers.class);
startActivity(it);
}
});
// open data source
transactionSource = new TransactionDao(this);
transactionSource.open();
// display total for user, cat, month/year
brokerTotal = transactionSource.getTotalCost(currentBroker);
TextView total = (TextView) findViewById(R.id.transactionTotal);
NumberFormat formatter = new DecimalFormat("#,##0.00");
total.setText(formatter.format(brokerTotal));
new GetTransactions().execute(); // retrieve display transactions for the broker
}
private void initViews(){
this.mListViewTransactions = (ListView)findViewById(R.id.tList);
}
#Override
protected void onResume() {
transactionSource.open();
super.onResume();
}
#Override
protected void onPause() {
transactionSource.close();
super.onPause();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu
getMenuInflater().inflate(R.menu.view_transactions, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_new) {
addTransaction();
return true;
} else if (id == R.id.switch_user) {
// Intent intent = new Intent(this, ViewUsers.class);
// startActivity(intent); // start user activity
return true;
}
return super.onOptionsItemSelected(item);
}
}
public class TransactionAdapter extends BaseAdapter {
public static final String TAG = "ListTransactionsAdapter";
private List<TransactionModel> mItems;
private LayoutInflater mInflater;
public TransactionAdapter(Context context, List<TransactionModel> listBrokers) {
this.setItems(listBrokers);
this.mInflater = LayoutInflater.from(context);
}
#Override
public int getCount() {
return (getItems() != null && !getItems().isEmpty()) ? getItems().size() : 0 ;
}
#Override
public TransactionModel getItem(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position) : null ;
}
#Override
public long getItemId(int position) {
return (getItems() != null && !getItems().isEmpty()) ? getItems().get(position).getId() : position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
ViewHolder holder;
if(v == null) {
v = mInflater.inflate(R.layout.capital_row_layout_transaction, parent, false);
holder = new ViewHolder();
holder.txtCapitalTransactionDate = (TextView) v.findViewById(R.id.capital_broker_date_transaction);
holder.txtCapitalTransaction = (TextView) v.findViewById(R.id.capital_broker_add_transaction);
holder.txtCapitalTransactionAmount = (TextView) v.findViewById(R.id.capital_broker_add_amount);
v.setTag(holder);
}
else {
holder = (ViewHolder) v.getTag();
}
// fill row data
TransactionModel currentItem = getItem(position);
if(currentItem != null) {
holder.txtCapitalTransactionDate.setText(currentItem.getTransactionDate());
holder.txtCapitalTransaction.setText(String.valueOf(currentItem.getTransactionDescription()));
holder.txtCapitalTransactionAmount.setText(String.valueOf(currentItem.getTransactionAmount()));
}
return v;
}
public List<TransactionModel> getItems() {
return mItems;
}
public void setItems(List<TransactionModel> mItems) {
this.mItems = mItems;
}
class ViewHolder {
TextView txtCapitalTransactionDate;
TextView txtCapitalTransaction;
TextView txtCapitalTransactionAmount;
}
}
How to make a preference activity where contain listpreference, where the summary will change based on selected listpreference item, and when certain list item is taped, it will show a edit text dialog which it will also become the the summary string value.
Thank in advance.
as requested, here my current code
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<PreferenceCategory
android:title="#string/pref_category_general"
android:key="pref_category_general">
<CheckBoxPreference
android:key="pref_debug_mode"
android:title="#string/pref_debug_mode"
android:summary="#string/pref_debug_mode_summary"
android:defaultValue="false" />
<ListPreference
android:dependency="pref_debug_mode"
android:key="pref_remotehost"
android:title="#string/pref_remotehost"
android:dialogTitle="#string/pref_remotehost_dialog_title"
android:entries="#array/pref_remotehost_entries"
android:entryValues="#array/pref_remotehost_entries_values"
android:defaultValue="#string/pref_remotehost_default" />
</PreferenceCategory>
</PreferenceScreen>
and my activity
public class SettingActivity extends SherlockPreferenceActivity implements View.OnClickListener {
private MainApplication G;
private SherlockPreferenceActivity me;
private Intent intent;
#Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
this.G = ((MainApplication) getApplicationContext());
assert this.G != null;
super.onCreate(bundle);
// Make sure we're running on Honeycomb or higher to use ActionBar APIs
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
// Show the Up button in the action bar.
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
// Add a button to the header list.
if (hasHeaders()) {
Button button = new Button(this);
button.setText("Some action");
setListFooter(button);
button.setOnClickListener(this);
}
PreferenceFragment prefFragment = new PreferenceGeneralFragment();
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.replace(android.R.id.content, prefFragment);
fragmentTransaction.commit();
this.intent = getIntent();
this.me = this;
}
#Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
#Override
public void onClick(View v) {
/*
switch (element.getId()) {
default:
return;
case R.id.setting_cancel_config:
onBackPressed();
return;
case R.id.setting_save_config:
int i = this.modeSpinner.getSelectedItemPosition();
boolean flag = true;
if (i == 1) {
flag = false;
};
MainApplication.setDeveloperMode(flag);
MainApplication.setRemoteHost(this.remoteHostEdittext.getText().toString());
SettingActivity.this.finish();
onBackPressed();
return;
}
*/
}
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
}
/**
* This fragment shows the preferences for the first header.
*/
public static class PreferenceGeneralFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make sure default values are applied. In a real app, you would
// want this in a shared function that is used to retrieve the
// SharedPreferences wherever they are needed.
//PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences_general, false);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences_general);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updatePrefSummary(findPreference(key));
}
private void initSummary(Preference p) {
if (p instanceof PreferenceCategory) {
PreferenceCategory pCat = (PreferenceCategory) p;
for (int i = 0; i < pCat.getPreferenceCount(); i++) {
initSummary(pCat.getPreference(i));
}
} else {
updatePrefSummary(p);
}
}
private void updatePrefSummary(Preference p) {
if (p instanceof ListPreference) {
ListPreference listPref = (ListPreference) p;
p.setSummary(listPref.getEntry());
}
if (p instanceof EditTextPreference) {
EditTextPreference editTextPref = (EditTextPreference) p;
p.setSummary(editTextPref.getText());
}
}
}
}
i don't know where to start
I have an issue I have been unable to figure out. I have a spinner loaded from an ArrayList saved in SharedPreferences. I allow the users to modify the spinner names through a PreferenceActivity in a separate class that is startActivityForResult. It works but I cannot for the life of me make the spinner refresh itself with the new name(s) unless the app is closed and then reopened.
When the user uses the back key to close the Edit names window the result code and result_ok information is passed back correctly. This is where I can't figure things out. I know I need to use NotifyDataSetChanged but I can't figure out how to do it since the modifications are made in a separate class and not in the OnItemSelectedListener like so many answers to questions here on StackOverflow suggest for refreshing spinner data.
Here is my spinner code:
private ArrayAdapter<String> adapter1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
/* enable hardware acceleration on Android >= 3.0 */
final int FLAG_HARDWARE_ACCELERATED = WindowManager.LayoutParams.class
.getDeclaredField("FLAG_HARDWARE_ACCELERATED").getInt(null);
getWindow().setFlags(FLAG_HARDWARE_ACCELERATED,
FLAG_HARDWARE_ACCELERATED);
} catch (Exception e) {
}
checkPreferences();
setContentView(R.layout.main);
this.findViewById(R.id.label_mode).setOnClickListener(this);
this.findViewById(R.id.label_clear).setOnClickListener(this);
this.findViewById(R.id.label_data).setOnClickListener(this);
this.findViewById(R.id.label_wifi).setOnClickListener(this);
this.findViewById(R.id.label_roam).setOnClickListener(this);
this.findViewById(R.id.label_vpn).setOnClickListener(this);
this.findViewById(R.id.label_invert).setOnClickListener(this);
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
// create the spinner
spinner = (Spinner) findViewById(R.id.spinner);
// profile names for spinner
final List<String> profilestring = new ArrayList<String>();
profilestring.add(prefs.getString("default",
getString(R.string.defaultprofile)));
profilestring.add(prefs.getString("profile1",
getString(R.string.profile1)));
profilestring.add(prefs.getString("profile2",
getString(R.string.profile2)));
profilestring.add(prefs.getString("profile3",
getString(R.string.profile3)));
profilestring.add(prefs.getString("profile4",
getString(R.string.profile4)));
profilestring.add(prefs.getString("profile5",
getString(R.string.profile5)));
profileposition = profilestring
.toArray(new String[profilestring.size()]);
// adapter for spinner
adapter1 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_dropdown_item, profileposition);
adapter1.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(adapter1);
spinner.setSelection(prefs.getInt("itemPosition", 0));
spinner.post(new Runnable() {
public void run() {
spinner.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View view, int position, long id) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(getApplicationContext());
SharedPreferences.Editor editor = prefs.edit();
int index = parent.getSelectedItemPosition();
if (index == 0) {
editor.putInt("itemPosition", index);
editor.commit();
LoadDefaultProfile();
}
if (index == 1) {
editor.putInt("itemPosition", index);
editor.commit();
LoadProfile1();
}
if (index == 2) {
editor.putInt("itemPosition", index);
editor.commit();
LoadProfile2();
}
if (index == 3) {
editor.putInt("itemPosition", index);
editor.commit();
LoadProfile3();
}
if (index == 4) {
editor.putInt("itemPosition", index);
editor.commit();
LoadProfile4();
}
if (index == 5) {
editor.putInt("itemPosition", index);
editor.commit();
LoadProfile5();
}
}
public void onNothingSelected(AdapterView<?> parent) {
// do nothing
}
});
}
});
I then set my selection and run the spinner with spinner.post(New Runnable).
My preference screen is very simple.
<?xml version="1.0" encoding="utf-8"?>
<EditTextPreference
android:key="default"
android:summary="Edit name for Default Profile"
android:title="#string/defaultprofile" />
<EditTextPreference
android:key="profile1"
android:summary="Edit name for profile1"
android:title="#string/profile1" />
<EditTextPreference
android:key="profile2"
android:summary="Edit name for profile2"
android:title="#string/profile2" />
<EditTextPreference
android:key="profile3"
android:summary="Edit name for profile3"
android:title="#string/profile3" />
<EditTextPreference
android:key="profile4"
android:summary="Edit name for profile4"
android:title="#string/profile4" />
<EditTextPreference
android:key="profile5"
android:summary="Edit name for profile5"
android:title="#string/profile5" />
EditNames class
public class EditProfileNames extends PreferenceActivity implements
OnSharedPreferenceChangeListener {
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.layout.prefs);
PreferenceManager.setDefaultValues(EditProfileNames.this,
R.layout.prefs, false);
for (int i = 0; i < getPreferenceScreen().getPreferenceCount(); i++) {
initSummary(getPreferenceScreen().getPreference(i));
}
}
#SuppressWarnings("deprecation")
#Override
protected void onResume() {
super.onResume();
// Set up a listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.registerOnSharedPreferenceChangeListener(this);
}
#SuppressWarnings("deprecation")
#Override
protected void onPause() {
super.onPause();
// Unregister the listener whenever a key changes
getPreferenceScreen().getSharedPreferences()
.unregisterOnSharedPreferenceChangeListener(this);
}
#SuppressWarnings("deprecation")
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
updatePrefSummary(findPreference(key));
}
private void initSummary(Preference p) {
if (p instanceof PreferenceCategory) {
PreferenceCategory pCat = (PreferenceCategory) p;
for (int i = 0; i < pCat.getPreferenceCount(); i++) {
initSummary(pCat.getPreference(i));
}
} else {
updatePrefSummary(p);
}
}
private void updatePrefSummary(Preference p) {
if (p instanceof ListPreference) {
ListPreference listPref = (ListPreference) p;
p.setSummary(listPref.getEntry());
}
if (p instanceof EditTextPreference) {
EditTextPreference editTextPref = (EditTextPreference) p;
p.setSummary(editTextPref.getText());
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
resultOk();
}
return super.onKeyDown(keyCode, event);
}
/**
* Set the activity result to RESULT_OK and terminate this activity.
*/
private void resultOk() {
final Intent response = new Intent(Api.PREF_PROFILES);
setResult(RESULT_OK, response);
finish();
}
}
So what do I have to do to refresh the spinner? I know I could do it if the change was made in the OnItemSelectedListener but since it is an entirely different class that makes the changes I'm lost at the moment.
Thanks!
It sounds like you are passing a reference to your array, profileposition, to another class so that it can add elements to it. You will also need to pass a reference to adapter to that class as well, so that it can call adapter.notifyDataSetChanged(); after it has updated your array.
EDIT: Now that I see that you an Acitivty that you have started for a result is doing the updating of the array, you could just call adapter.notifyDataSetChanged(); in your onActivityResult() callback.
After changing the contents , call notifyDataSetChanged on the adapter and that will solve the issue.
Try this way
adapter.notifyDataSetChanged();
I'm trying to improve the user friendliness of an app by providing the user with "Select all" and "Deselect all" options in the preferences. Things seem to be working, except for one major flaw:
I'm using SharedPreferences.getAll() to retrieve all the checkboxes so I can iterate them and check/uncheck them. But it seems that getAll() doesn't quite live up to it's name. It doesn't return ALL preferences, but only the ones that have been previously altered by the user.
So, is there a way to retrieve ALL of the preferences?
The code I'm currently using:
public class ADRpreferences extends PreferenceActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
((Preference) findPreference("searchresult_select_all")).
setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
setCheckState("searchresult", true);
return true;
}
});
((Preference) findPreference("searchresult_deselect_all")).
setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
setCheckState("searchresult", false);
return true;
}
});
}
private void setCheckState(String prefix, Boolean state) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
#SuppressWarnings("unchecked")
Map<String, Boolean> categories = (Map<String, Boolean>) settings.getAll();
for (String s : categories.keySet()) {
Preference pref = findPreference(s);
if( s.startsWith(prefix) && (pref instanceof CheckBoxPreference) ){
((CheckBoxPreference) pref).setChecked(state);
}
}
}
}
EDIT
Ok, for now I will go with MH's solution. I put all the ID's of the checkbox preferences into arrays.xml, and will use those values to iterate through all the checkboxes (there are 44 of them in case you wonder why I just don't hardcode the ID's). Works great, of course in the future I will have to remember to add/remove the ID's in the arrays if I make changes to the preferences. Here's the new setCheckState():
private void setCheckState(String category, Boolean state) {
String[] arr = null;
if( category.equals("loadlist") ){
arr = getResources().getStringArray(R.array.array_loadlist_checkboxes);
}
else if( category.equals("searchresult") ){
arr = getResources().getStringArray(R.array.array_searchresult_checkboxes);
}
else{
return;
}
for( String s : arr ){
Preference pref = findPreference(s);
if( pref instanceof CheckBoxPreference ){
((CheckBoxPreference) pref).setChecked(state);
}
}
}
I have four checkboxpreferences in my preferencescreen that I would like to interact like a radiobuttongroup, meaning that you can only check one of them! If lets say the first is checked, and you like to check another one, its just the desired one checked, and the other ones is unchecked.
I did like this :
public class PreferenceActivity extends PreferenceActivity {
private SharedPreferences prefs;
private Editor editor;
private int keyItemChecked;
private CheckBoxPreference item1CheckBox, item2CheckBox, ..., itemICheckBox;
#SuppressWarnings("deprecation")
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
prefs = PreferenceManager.getDefaultSharedPreferences(this);
addPreferencesFromResource(R.xml.prefs);
item1CheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("item1");
item2CheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("item2");
...
itemICheckBox = (CheckBoxPreference) getPreferenceManager().findPreference("itemI");
item1CheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
manageItem(1, item1CheckBox);
return true;
}
});
....
itemICheckBox.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference arg0) {
manageItem(I, itemICheckBox);
return true;
}
});
}
private void manageItem(int i ,CheckBoxPreference pref) {
keyItemChecked = prefs.getInt("keyItemChecked",1); // 1 is your default checked item
if (! pref.isChecked() && keyItemChecked == i)
// If you click on the checked item, you don't want it to be unchecked :
pref.setChecked(true);
if (pref.isChecked() && keyItemChecked != i) {
editor = prefs.edit();
editor.putInt("keyItemChecked", i);
editor.commit(); // or editor.apply() if you use API > 9
unckeckOldItem(keyItemChecked);
}
}
private void unckeckOldItem(int item) {
switch (item) {
case 1:
item1CheckBox.setChecked(false);
break;
...
case I:
itemICheckBox.setChecked(false);
break;
}
}
You don't need to declare "keyItemChecked" on your prefs.xml.
The first time you call the activity, the data doesn't exist and
keyItemChecked = prefs.getInt("keyItemChecked",1);
will return 1.
Once you click on an other item than the default, the data will exist.
Looks like you can use http://developer.android.com/reference/android/preference/CheckBoxPreference.html#setDisableDependentsState%28boolean%29 to create that functionality. I think setting dependency of preferences can be done in xml.