2011-06-24 39 views
21

Tôi có hoạt động tùy chọn có languageListPreference hiển thị danh sách ngôn ngữ khả dụng. Tôi có thể điền vào danh sách khi onCreate được gọi, nhưng tôi muốn điền vào danh sách khi người dùng nhấp vào nó.Làm thế nào để điền ListPreference tự động khi onPreferenceClick được kích hoạt?

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; 

    } 
} 

và đây là settings.xml (ưu tiên):

<?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> 

Tôi đã tìm kiếm nhưng không tìm thấy kết quả! Một ngoại lệ xảy ra mỗi khi tôi nhấp vào danh sách đó.

Trả lời

36

Bạn đang nhận ngoại lệ vì đối tượng ListPreference của bạn chưa được khởi tạo đầy đủ - bạn cần đặt thuộc tính entriesentryValues trong XML của bạn hoặc thực hiện theo chương trình trong onCreate().

Nếu những gì bạn muốn là có thể thay đổi các mục trong danh sách động sau khi đối tượng ListPreference ban đầu đã được khởi tạo thì bạn sẽ cần đính kèm trực tiếp OnPreferenceClickListener vào đối tượng ListPreference. Sử dụng khóa bạn đã chỉ định trong XML để có được một xử lý cho sở thích.

Kể từ mã để cư entriesentryValues mảng sẽ phải chạy cả trong onCreate() và trong onPreferenceClick, nó làm cho tinh thần để giải nén nó vào một phương pháp riêng biệt - setListPreferenceData() để tránh trùng lặp.

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

Câu trả lời này có hiệu quả nhưng có một chút lỗi nếu bạn cho phép setListPreferenceData chỉ chạy trên Click (và không onCReate). Đó là vì nếu phương thức setListPreferenceData mất nhiều hơn một phần trong một giây thì danh sách mặc định được hiển thị trước khi dữ liệu được đặt và người dùng buộc phải hủy rồi mở lại tùy chọn. Có cách cập nhật danh sáchPreference đã được hiển thị sau khi bạn setListPreferenceData kết thúc không? – Malabarba

+3

Nếu bạn cần hành vi tùy chỉnh, đặt cược tốt nhất của bạn có thể sẽ mở rộng 'ListPreference' hoặc' Preference'. Cách giải quyết hoàn toàn 'xã hội' sẽ là đặt giá trị mục danh sách mặc định thành một cái gì đó như là ccpizza

+1

Vâng, tôi phải tự mở rộng listpreference. Nhưng nó không quá tệ. onCreate là phương thức duy nhất cần quá tải. – Malabarba

2

Sử dụng PreferenceFragment & JAVA bộ chủ chốt chứ không phải PreferenceActivity & XML như trong https://stackoverflow.com/a/13828912/1815624, mà câu trả lời này được dựa trên:

Nếu những gì bạn muốn là có thể thay đổi các mục trong danh sách động sau khi đối tượng ListPreference ban đầu đã được khởi tạo sau đó bạn sẽ cần phải đính kèm OnPreferenceClickListener trực tiếp đối tượng ListPreference. Sử dụng phím bạn có được chỉ định trong nguồn JAVA (dưới dạng CUSTOM_LIST) để xử lý tùy chọn.

Kể từ mã để cư entriesentryValues mảng sẽ phải chạy cả trong onCreate() và trong onPreferenceClick, nó làm cho tinh thần để giải nén nó vào một phương pháp riêng biệt - setListPreferenceData() để tránh trùng lặp.

/** 
* 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 layout:

<?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

tôi đã giải quyết được vấn đề của tôi kéo dài ListPreference. Nó rất đơn giản.

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); 
    } 
} 

Và sau đó tôi vừa đổi tên thành lớp của mình trong XML.

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

Và sau đó tôi chỉ cần thực hiện việc này tại 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"); 
      } 
     }); 

Đã làm việc ngay lập tức. Trên thực tế, tôi không bao giờ mong đợi nó sẽ được thực hiện dễ dàng như vậy.

Các vấn đề liên quan