AndroidX: Set Enter key to validate EditTextPreference dialog box - android

I'm trying to make a preference screen with AndroidX, but I'm encountering a small problem...
When I validate my entry with the "OK" button on the virtual keyboard, the preference is not validated. (keyboard is hidden, that's all...)
With AndroidX, we can no longer override showDialog() in EditTextPreference... and I couldn't find another way to access the dialog box to dismiss it.
In conclusion, what I wish: the DONE action of the button on the virtual keyboard validates the AlertDialog.
Here's my sample code:
XML file
<PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
<EditTextPreference
app:key="pref_1"
app:title="Test"
app:useSimpleSummaryProvider="true" />
</PreferenceScreen>
Preference activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
#Override
public void onBindEditText(#NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
}
});
}
}
}

If you want to validate that update value of text you need to use this listener
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
return true; //if you pass false here the updated value will not save
}
});
here is the example to use the true false return
public static class HeaderFragment extends PreferenceFragmentCompat {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.headerpref, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
// put validation here..
Log.d("Prefrence====>",newValue+"<=== validate you can validate this value");
if(newValue.toString().length()>0){
return true;
}else return false;
}
});
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
#Override
public void onBindEditText(#NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
//Your dialog will dissmiss on ok click
if(actionId==EditorInfo.IME_ACTION_DONE)dismissDialog();
return false;
}
});
}
});
}
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}
}
Since you want to dismiss Dialog manually you can do it like this way , cause there are no direct method available to get the dialog and dismiss it.
I updated the dialog dismiss listener as your need to save the data passing true in onDialogClosed method will help to save your data
void dismissDialog(){
for(Fragment fragments : HeaderFragment.this.getActivity().getSupportFragmentManager().getFragments()){
if(fragments instanceof EditTextPreferenceDialogFragmentCompat){
EditTextPreferenceDialogFragmentCompat dialog = ((EditTextPreferenceDialogFragmentCompat) fragments);
dialog.onDialogClosed(true);
dialog.dismiss();
return;
}
}
}

I found another way. I don't think it's the best, but if it can help anyone...
PreferenceFragmentCompat customized
public class PreferenceFragmentCompatCustom extends PreferenceFragmentCompat {
private static final String DIALOG_FRAGMENT_TAG =
"androidx.preference.PreferenceFragment.DIALOG";
private DialogFragment mDialogFragment;
#Override
public void onDisplayPreferenceDialog(Preference preference) {
if (getActivity() instanceof MySettingsActivity) {
final DialogFragment f;
if (preference instanceof EditTextPreference) {
f = EditTextPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else if (preference instanceof ListPreference) {
f = ListPreferenceDialogFragmentCompat.newInstance(preference.getKey());
} else {
throw new IllegalArgumentException("Tried to display dialog for unknown " +
"preference type. Did you forget to override onDisplayPreferenceDialog()?");
}
f.setTargetFragment(this, 0);
// Expose the dialog
mDialogFragment = f;
f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}else{
super.onDisplayPreferenceDialog(preference);
}
}
public DialogFragment getDialog(){ return mDialogFragment;}
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {}
}
Preference activity
public class MySettingsActivity extends AppCompatActivity implements
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
[...]
public static class HeaderFragment extends PreferenceFragmentCompatCustom {
#Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.header_preferences, rootKey);
EditTextPreference pref1 = getPreferenceManager().findPreference("pref_1");
pref1.setOnBindEditTextListener(new EditTextPreference.OnBindEditTextListener() {
#Override
public void onBindEditText(#NonNull EditText editText) {
editText.setInputType(InputType.TYPE_CLASS_TEXT | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS);
editText.setImeOptions(EditorInfo.IME_ACTION_DONE);
editText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_DONE) {
// If callOnClick, do not save value here
//etpTest.setText(v.getText().toString());
// If dismiss, the preference is not set !
//getDialog().dismiss();
((AlertDialog) getDialog().getDialog())
.getButton(DialogInterface.BUTTON_POSITIVE)
.callOnClick();
return true;
}
return false;
}
});
}
});
}
}
}

Related

Android adding event to a CustomPreference element (TextView)

I'm doing an with a PreferenceActivity with two Fragments, each one containing a PreferenceScreen.
The thing I want to do is to create an event listener on a Custom preference that I have (a row of this custom Preference is a TextView with a SwitchView). I handle well the Switch preference, it keeps it saved as I want, but now what I want to do is add an event on the TextView between the SwitchView to show what I want on the other part of the screen (the second Fragment).
Let me show you my current code.
This is my CustomPreference (it's just a TextView and a Switch)
public class ItemPreference extends Preference{
private static TextView text; // this is the text at the left of the switch, it's where i want to handle the event
// to show an other preferencescreen in the fragment between
private Switch switcher; // the key of the preference is for the SWITCH !!
private boolean checked;
private Context context;
public TextView getCustomText(){
return text;
}
public ItemPreference(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
setLayoutResource(R.layout.row_setting); // the layout resource of my custom preference
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
text = (TextView)view.findViewById(R.id.buttonRowSetting);
// to display the text in the TextView between the Switch, I use the key of the Switch
if (this.getKey().equals("pref_key_classification"))
text.setText(R.string.title_activity_classification);
// the switchview and it's preference saving
switcher = (Switch)view.findViewById(R.id.switchRowSetting);
Boolean value = this.getPersistedBoolean(false);
if (value){
switcher.setChecked(true);
} else {
switcher.setChecked(false);
}
switcher.setOnCheckedChangeListener(new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
setSwitchChecked(isChecked);
}
});
}
public void setSwitchChecked(boolean value) {
if (checked != value) {
checked = value;
persistBoolean(value);
notifyDependencyChange(shouldDisableDependents());
notifyChanged();
}
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getBoolean(index, false);
}
#Override
protected void onClick() {
super.onClick();
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
setSwitchChecked(restorePersistedValue ? getPersistedBoolean(checked) : (Boolean) defaultValue);
}
#Override
protected Parcelable onSaveInstanceState() {
return super.onSaveInstanceState();
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
}
}
This is the SettingsFragment, on the left part of the screen, where I want to handle the event to show what I want on the other part of the screen.
public class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.settings); // the left preferencefragment
Preference stat = (Preference) findPreference(getString(R.string.pref_key_statistic));
stat.setOnPreferenceClickListener(new OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if(getActivity() instanceof OnSettingPageListener){
// if i click on this preference, this loads this preferencescreen on the other fragment, works well.
((OnSettingPageListener)getActivity()).onSettingPageChange(R.xml.settings_stat);
}
return true;
}
});
// this is the custompreference, i would like to handle here a listener on the TextView to display a specific preferencescreen on the other fragment
ItemPreference classif = (ItemPreference) findPreference(getString(R.string.pref_key_classification));
// i tried this, and i also tried to make my own Listener also, but doesn't works
classif.getCustomText().setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
if (getActivity() instanceof OnSettingPageListener){
// the content i want to load on the other fragment
((OnSettingPageListener)getActivity()).onSettingPageChange(R.xml.settings_classification);
}
}
});
}
// [...]
}
So I hope you understand what's my problem, it's just a matter of listener. Does someone has a solution?
I'm not sure if you want the event on your first fragment to show the second fragment (for further editing) or if you want the event to make a change visible to the second fragment.
Let's say you want the change to be visible to the second fragment:
Have your second fragment implement SharedPreference.OnSharedPreferenceChangeListener with method onSharedPreferenceChanged, implemented to do what you want to have happen when the preference in the first fragment changes.
In the second fragment's onResume method, call registerOnSharedPreferenceChangeListener on your SharedPreferences object.
In the second fragment's onPause method, call unregisterOnSharedPreferenceChangeListener on your SharedPreferences object.
Now, if you want to show the second fragment for editing the preference in the first fragment:
Give your preference a fragment attribute that declares the fragment class that edits your preference
Have your first fragment implement PreferenceFragment.OnPreferenceStartFragmentCallback with method onPreferenceStartFragment implemented to instantiate your second fragment and display it. Your PreferenceActivity subclass will invoke this callback when the preference is clicked.
I finally found a solution, my problem was the way the handle a listener on the textview of my custom preference. I followed the observer pattern and made it work on my own listener.
On my fragment I instantiated my CustomSwitchPreference (I just renamed the ItemPreference class you can see upstairs ^^). I called my own listener, you will see the code after.
CustomSwitchPreference classif = (CustomSwitchPreference)
findPreference(getString(R.string.pref_key_classification));
classif.setHandlerListener(new ItemPreferenceTextViewListener() {
#Override
public void onHandle(TextView textView) {
if (getActivity() instanceof OnSettingPageListener){
((OnSettingPageListener)getActivity())
.onSettingPageChange(R.xml.settings_classification);
}
}
});
And there we go for the listener in the CustomPreference class, first create an interface to made your own listener (you can write it in the same file as the CustomPreference class you are doing) :
interface ItemPreferenceTextViewListener {
// the function which is going to be called when we will use our listener
void onHandle(TextView textView);
}
And then in the CustomPreference class you do this :
// you can put the interface here if you want to make it visible
public class CustomSwitchPreference extends Preference {
private static TextView text;
// the key of the preference is for the SWITCH !! this activates or
// not the "game" on the mainscreen
private Switch switcher;
private boolean checked;
// ---------------------------------------------------------------------- \\
// create a listener in your own custom preference
ItemPreferenceTextViewListener itemPreferenceTextViewListener ;
// this is the function to handle the event on the textview of the
// custom preference item, creates the listener
public void setHandlerListener(ItemPreferenceTextViewListener listener) {
itemPreferenceTextViewListener = listener;
}
// to make the event happen on a textview
// (we will pass the right textview in the onBindView(....) )
protected void myEventListener(TextView textView) {
if(itemPreferenceTextViewListener!=null)
itemPreferenceTextViewListener.onHandle(textView);
}
// ---------------------------------------------------------------------- \\
/**
* #param context
* #param attrs
*/
public CustomSwitchPreference(Context context, AttributeSet attrs) {
super(context, attrs);
setLayoutResource(R.layout.row_setting);
}
#Override
protected void onBindView(View view) {
super.onBindView(view);
// the TextView at the right of the switch, this one
// handles a listener to show the other page preference
text = (TextView)view.findViewById(R.id.buttonRowSetting);
// I called it buttonRowSetting because it will handle an event like a button
// I set the text of this TextView with the
// key preference of the related switch
if (this.getKey().equals("pref_key_classification"))
text.setText(R.string.title_activity_classification);
else if (this.getKey().equals("pref_key_matching"))
text.setText(R.string.title_activity_matching);
else if (this.getKey().equals("pref_key_intruder"))
text.setText(R.string.title_activity_intruder);
else if (this.getKey().equals("pref_key_semantic"))
text.setText(R.string.title_activity_semantic);
// AND HERE it's where it happens, simply make a basic listener
// on the textview, and inside the onClick method, handle your own
// listener, on the TextView you initialized just before)
text.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// just call
itemPreferenceTextViewListener.onHandle(text);
}
});
// ---------------------------------------------------------------------- \\
// to keep the Switch saved in the preferences
switcher = (Switch)view.findViewById(R.id.switchRowSetting);
Boolean value = this.getPersistedBoolean(false);
if (value){
switcher.setChecked(true);
} else {
switcher.setChecked(false);
}
switcher.setOnCheckedChangeListener(new OnCheckedChangeListener(){
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
setSwitchChecked(isChecked);
}
});
// ---------------------------------------------------------------------- \\
}
public void setSwitchChecked(boolean value) {
if (checked != value) {
checked = value;
persistBoolean(value);
notifyDependencyChange(shouldDisableDependents());
notifyChanged();
}
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getBoolean(index, false);
}
#Override
protected void onClick() {
super.onClick();
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue,
Object defaultValue) {
setSwitchChecked(restorePersistedValue
? getPersistedBoolean(checked) : (Boolean) defaultValue);
}
#Override
protected Parcelable onSaveInstanceState() {
return super.onSaveInstanceState();
}
#Override
protected void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
}
}
Hope this helps, it was my mistake I did not called the onHandle method inside the myTextView.onClickListener. Hope this will help one to understand well how the observer pattern works.

Android Preference Activity, show edittext dialog when tap listview item

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

show alert dialog when click item in listpreference-android

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.

Custom EditTextPreference and setOnPreferenceChangeListener not called

My listener is not getting called for some reason? This is what I have:
In Preference file I have a custom EditTextPreference:
<com.xxx.yyy.preference.PreferenceEditTextDialog
android:layout="#layout/preference_edit"
android:title="#string/title"
android:summary="#string/summary"
android:defaultValue=""
android:dialogTitle="#string/dialogTitle"
android:key="mypref"/>
I extend my class:
public class PreferenceEditTextDialog extends EditTextPreference {
Launching my Activity:
startActivity(new Intent(this, PrefsActivity.class));
Definition:
public class PrefsActivity extends PreferenceActivity implements
OnPreferenceClickListener, OnSharedPreferenceChangeListener {
In here I register my setOnPreferenceChangeListener (which is not called).
However changing my Preference file from:
<com.xxx.yyy.preference.PreferenceEditTextDialog
to default:
<EditTextPreference
it all works. Could someone help me to find the problem, somehow the listener is not propagated properly using my custom Preference.
Thanks!
#Sam Here my listener definition:
myfield = (EditTextPreference) getPreferenceScreen().findPreference(KEY_PREFERENCE);
myfield.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Boolean valid = true;
if(!validate(newValue.toString())) {
valid = false;
}
return valid;
}
});
Found a solution, in my custom EditTextPreference I added a call to callChangeListener(value):
#Override
public void onBindDialogView(View view) {
edittext = (EditText) view.findViewById(R.id.edittext);
edittext.setText(PreferenceManager.
getDefaultSharedPreferences(view.getContext()).
getString(getKey(), ""));
ok_button = (Button) view.findViewById(R.id.ok_button);
ok_button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String value = edittext.getText().toString();
if(callChangeListener(value)) {
Editor editor = getEditor();
editor.putString(getKey(), value);
editor.commit();
getDialog().dismiss();
}
}
});

Is it possible to combine an EditTextPreference with a CheckBoxPreference?

I have a PreferenceActivity with, among other things, a category including call forward options. What I want is a preference that:
Enables/Disables if the user presses a checkbox on the right.
Opens up the EditTextPreference dialog if the user presses the text(or anything else in the preference)
It's probably not of any use but here is a snippet of this particular preferencecategory :
<PreferenceCategory
android:title="#string/category_callforward">
<EditTextPreference
android:key="call_forward_always"
android:title="#string/call_forward_always"
android:summary="#string/call_forward_forwardto" />
</PreferenceCategory>
EDIT
I'd like to implement it in this method if possible:
// Locates the correct data from saved preferences and sets input type to numerics only
private void setCallForwardType()
{
ep1 = (EditTextPreference) findPreference("call_forward_always");
EditText et = (EditText) ep1.getEditText();
et.setKeyListener(DigitsKeyListener.getInstance());
}
EDIT2
If anyone is still wondering - this is what I want as a Preference:
EDIT3
I've searched around for a couple hours now and have come up with a single word: 'PreferenceGroupAdapter'. I have not, however, been able to find examples or tutorials showing me how to use it. Suggestions ? Is this even the correct path to go?
EDIT4
If this really isn't possibly I would very much like a suggestion to an alternative(user-friendly) solution that I can implement instead of the combined Edit- and Checkbox preference.
You can do this. First, create a class for preferences which should be extended from PreferenceActivity. Use like this:
// editbox ise your EditTextPreference, so set it.
checkbox = (CheckBoxPreference) findPreference("checkbox_preference");
checkbox.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object newValue) {
if(newValue.toString().equals("false")) {
PrefActivity.this.editbox.setEnabled(false);
} else if(newValue.toString().equals("true")) {
PrefActivity.this.editbox.setEnabled(true);
}
return true;
}
});
I hope it helps.
A bit late but I think I've managed to create something similar with a dialog that creates a layout with an edit text and a checkbox, it should be possible to do the same in a normal layout:
public class CheckEditTextPreference extends DialogPreference {
private static final String KEY_PROPERTY_DISABLED = "key_property_disabled";
private EditText editText;
private CheckBox checkBox;
private String text;
private boolean isDisabled;
private SharedPreferences mySharedPreferences = PreferenceManager.getDefaultSharedPreferences(getContext());
public CheckEditTextPreference(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#Override
protected View onCreateDialogView() {
return buildUi();
}
/**
* Build a dialog using an EditText and a CheckBox
*/
private View buildUi() {
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
layoutParams.setMargins(25, 0, 0, 0);
LinearLayout linearLayout = new LinearLayout(getContext());
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setLayoutParams(layoutParams);
checkBox = new CheckBox(getContext());
editText = new EditText(getContext());
editText.setLayoutParams(layoutParams);
checkBox.setLayoutParams(layoutParams);
checkBox.setText("Disabled");
FrameLayout dialogView = new FrameLayout(getContext());
linearLayout.addView(editText);
linearLayout.addView(checkBox);
dialogView.addView(linearLayout);
checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
editText.setEnabled(!isChecked);
}
});
return dialogView;
}
#Override
protected void onBindDialogView(View view) {
super.onBindDialogView(view);
checkBox.setChecked(isDisabled());
editText.setText(getText());
}
#Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String text = editText.getText().toString();
boolean isChecked = checkBox.isChecked();
if (callChangeListener(text)) {
setText(text);
}
if (callChangeListener(isChecked)) {
isDisabled(isChecked);
}
}
}
#Override
protected Object onGetDefaultValue(TypedArray a, int index) {
return a.getString(index);
}
#Override
protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
setText(restorePersistedValue ? getPersistedString("") : defaultValue.toString());
isDisabled(mySharedPreferences.getBoolean(KEY_PROPERTY_DISABLED, true));
}
public void setText(String value) {
this.text = value;
persistString(this.text);
}
public String getText() {
return this.text;
}
private void isDisabled(boolean value) {
this.isDisabled = value;
mySharedPreferences.edit().putBoolean(KEY_PROPERTY_DISABLED, this.isDisabled).apply();
}
public boolean isDisabled() {
return this.isDisabled;
}
}
And put this into your preferences screen:
<your.package.name.CheckEditTextPreference
android:key="chkEtPref"
android:title="Title"/>
Define a key in res/values/strings.xml for your CheckBoxPreference.
Give your CheckBoxPreference the XML attribute android:key="#string/THE_KEY_YOU_DEFINED" so that it will automatically save state in SharedPreferences.
Give your EditTextPreference the XML attribute android:dependency="#string/THE_KEY_YOU_DEFINED.
The EditTextPreference should then enable / disable depending on the state of the CheckBoxPreference.

Categories

Resources