2011-06-24 14 views
21

私はlanguageとしてListPreferenceと表示されており、利用可能な言語リストを表示しています。 onCreateが呼び出されたときにリストを埋めることができますが、ユーザーがそれをクリックするとリストを埋めたいと思います。onPreferenceClickがトリガされたときにListPreferenceを動的に満たす方法を教えてください。

this is the java code

public class SettingsActivity extends PreferenceActivity implements OnPreferenceClickListener { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     try { 
      addPreferencesFromResource(R.xml.settings); 
     } catch (Exception e) { 

     } 

    } 

    @Override 
    public boolean onPreferenceClick(Preference preference) { 

     if((preference instanceof ListPreference) && (preference.getKey().equals("language"))){ 
      ListPreference lp = (ListPreference)preference; 
      CharSequence[] entries = { "English", "French" }; 
      CharSequence[] entryValues = {"1" , "2"}; 
      lp.setEntries(entries); 
      lp.setDefaultValue("1"); 
      lp.setEntryValues(entryValues); 
      return true; 
     } 
     return false; 

    } 
} 

と、これはあるsettings.xml(優先):私は検索が、何の結果が見つからなかっ

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen 
    xmlns:android="http://schemas.android.com/apk/res/android"> 
    <PreferenceCategory android:title="General Settings"> 
     <CheckBoxPreference android:key="enabled" android:title="Application Status" android:summary="Enable or disable the application" /> 
     <ListPreference 
     android:key="language" 
     android:title="Language" 
     android:dialogTitle="Application language" 
     android:summary="Select the Application language" 
     /> 
    </PreferenceCategory> 
</PreferenceScreen> 

!そのリストをクリックするたびに例外が発生します。

答えて

36

あなたListPreferenceオブジェクトが完全に初期化されていないため、例外を取得している - あなたのいずれかがあなたのXMLにentriesentryValues属性を設定またはonCreate()でプログラム的にそれを行う必要があります。

最初のListPreferenceオブジェクトが初期化された後に、リスト内の項目を動的に変更できるようにするには、OnPreferenceClickListenerを直接ListPreferenceオブジェクトに添付する必要があります。 XMLで指定したキーを使用して、環境設定のハンドルを取得します。

entriesentryValuesアレイを移入するためのコードはonCreate()およびonPreferenceClickの両方で実行する必要がありますので、別の方法にそれを抽出するために理にかなって - 重複を避けるために、setListPreferenceData()PreferenceFragment & JAVAセットキーを使用して

public class SettingsActivity extends PreferenceActivity { 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     try { 
      addPreferencesFromResource(R.xml.settings); 
     } catch (Exception e) { 

     } 

     final ListPreference listPreference = (ListPreference) findPreference("language"); 

     // THIS IS REQUIRED IF YOU DON'T HAVE 'entries' and 'entryValues' in your XML 
     setListPreferenceData(listPreference); 

     listPreference.setOnPreferenceClickListener(new OnPreferenceClickListener() { 
      @Override 
      public boolean onPreferenceClick(Preference preference) { 

       setListPreferenceData(listPreference); 
       return false; 
      } 
     }); 
    } 

    protected static void setListPreferenceData(ListPreference lp) { 
      CharSequence[] entries = { "English", "French" }; 
      CharSequence[] entryValues = {"1" , "2"}; 
      lp.setEntries(entries); 
      lp.setDefaultValue("1"); 
      lp.setEntryValues(entryValues); 
    } 
} 
+2

この回答は機能しますが、 setListPreferenceDataにonClick(onCReateではなく)だけを実行させると、ちょっとバグがあります。これは、 です。なぜなら、setListPreferenceDataメソッドでは、1秒未満の小計 が必要な場合、データが設定される前にデフォルトリストが表示され、 ユーザーは強制的にキャンセルして再度環境設定を開くためです。 既に表示されているlistPreferenceを更新する方法はありますか? setListPreferenceDataの終了後に? – Malabarba

+3

カスタムビヘイビアが必要な場合は、おそらく 'ListPreference'や' Preference'を拡張するのがベストでしょう。純粋に「ソーシャル」の回避策は、デフォルトのリストアイテムの値を ccpizza

+1

のように設定することです。ええ、私は自分自身でlistpreferenceを拡張する必要がありました。しかし、それほど悪くはありませんでした。 onCreateは、オーバーロードが必要な唯一のメソッドでした。 – Malabarba

2

ではなく、 PreferenceActivity & XML この回答が基づいているhttps://stackoverflow.com/a/13828912/1815624に示すよう、:

何をしたいことにある場合最初のListPreferenceオブジェクトが初期化された後にリスト内の項目を動的に変更できるようにするには、 OnPreferenceClickListenerを直接ListPreferenceオブジェクトに追加します。 JAVAソース(CUSTOM_LIST)に指定されたのキーを使用して、環境設定のハンドルを取得します。

entriesentryValuesアレイを移入するためのコードはonCreate()およびonPreferenceClickの両方で実行する必要がありますので、別の方法にそれを抽出するために理にかなって - 重複を避けるために、setListPreferenceData()

/** 
* This fragment shows data and sync preferences only. It is used when the 
* activity is showing a two-pane settings UI. 
*/ 
@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
public static class myCustomPreferenceFragment extends PreferenceFragment { 

    final private String CUSTOM_LIST= "custom_list"; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     addPreferencesFromResource(R.xml.pref_custom_frag); 

     PreferenceCategory targetCategory = (PreferenceCategory) findPreference("CUSTOM_FRAG"); 

     final ListPreference lp = setListPreferenceData((ListPreference) findPreference(CUSTOM_LIST), getActivity()); 

     lp.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 
      @Override 
      public boolean onPreferenceClick(Preference preference) { 

       setListPreferenceData(lp, getActivity()); 
       return false; 
      } 
     }); 
     setHasOptionsMenu(true); 
     targetCategory.addPreference(lp); 

     bindPreferenceSummaryToValue(targetCategory); 
     bindPreferenceSummaryToValue(lp); 
    } 

    protected ListPreference setListPreferenceData(ListPreference lp, Activity mActivity) { 
     CharSequence[] entries = { "One", "Two", "Three" }; 
     CharSequence[] entryValues = { "1", "2", "3" }; 
     if(lp == null) 
      lp = new ListPreference(mActivity); 
     lp.setEntries(entries); 
     lp.setDefaultValue("1"); 
     lp.setEntryValues(entryValues); 
     lp.setTitle("Number Of blahs"); 
     lp.setSummary(lp.getEntry()); 
     lp.setDialogTitle("Number of Blah objects"); 
     lp.setKey(CUSTOM_LIST); 
     return lp; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     int id = item.getItemId(); 
     if (id == android.R.id.home) { 
      startActivity(new Intent(getActivity(), SettingsActivity.class)); 
      return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 
} 

XMLレイアウト:

<?xml version="1.0" encoding="utf-8"?> 
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> 
    <PreferenceCategory 
     android:key="CUSTOM_FRAG" 
     android:title="Some Options"> 

    </PreferenceCategory> 
</PreferenceScreen> 
0

私は問題に私がListPreferenceを拡張を解決しました。とてもシンプルでした。

public class DListPref extends ListPreference 
{ 
    public interface LoadingListener 
    { 
     void setData(ListPreference lp); 
    } 

    LoadingListener TheLL; 

    public void setLoadingListener(LoadingListener l) 
    { 
     TheLL = l; 
    } 

    @Override 
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) 
    { 
     if(TheLL!=null) 
     { 
      TheLL.setData(this); 
     } 
     super.onPrepareDialogBuilder(builder); 
    } 

    //Do not mind the rest of this class, as they are auto-generated boilerplate code. 
    public DListPref(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) 
    { 
     super(context, attrs, defStyleAttr, defStyleRes); 
    } 

    public DListPref(Context context, AttributeSet attrs, int defStyleAttr) 
    { 
     super(context, attrs, defStyleAttr); 
    } 

    public DListPref(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 

    public DListPref(Context context) 
    { 
     super(context); 
    } 
} 

そして、XMLのクラスに名前を変更しました。

<my.company.DListPref 
    android:defaultValue="-1" 
    android:key="damn" 
    android:title="vegetables"/> 

次に、私は単にonCreateでこれを行いました。

 DListPref lp = (DListPref) findPreference("damn"); 

     lp.setLoadingListener(new DListPref.LoadingListener() 
     { 
      @Override 
      public void setData(ListPreference lp) 
      { 
       lp.setEntries(new String[]{"doge", "wow"}); 
       lp.setEntryValues(new String[] {"1", "2"}); 
       lp.setDefaultValue("1"); 
      } 
     }); 

すぐに作業しました。実際、私はそれがとても簡単になるとは決して考えなかった。

関連する問題