【问题标题】:Concise way of writing new DialogPreference classes?编写新 DialogPreference 类的简洁方式?
【发布时间】:2010-12-22 03:09:59
【问题描述】:

我正在通过扩展DialogPreference 类在Android 中编写一些自定义首选项对话框。但是,我有点担心为此所需的样板代码量,因为似乎有很多行为需要测试。

例如,这个数字偏好对话框的例子是相当典型的: http://svn.jimblackler.net/jimblackler/trunk/workspace/NewsWidget/src/net/jimblackler/newswidget/NumberPreference.java

尤其是onSave()/RestoreInstanceState() 方法和“class SavedState”部分,它们是必需的,以便在方向更改时保留对话框的当前更改,非常冗长和复杂。

有没有人有任何关于以更简洁的方式编写 DialogPreference 类的提示?

【问题讨论】:

    标签: java android mobile


    【解决方案1】:

    最低限度是:

    1. MyCustomDialogPreference(Context context, AttributeSet attrs) 构造函数。
      • 别忘了致电super(context, attrs)
      • 调用 setPersistent(false) 向超级 Preference 类指示您自己保留首选项值。
      • 如果您想从资源中扩充对话框面板布局,请同时调用setDialogLayoutResource(int dialogLayoutResId)
    2. onBindDialogView(View view) - 使用您偏好的值更新视图。
      • 别忘了致电super.onBindDialogView(view)
    3. onDialogClosed(boolean positiveResult) - 如果 positiveResult 为真,则将值从您的视图保存到 SharedPreferences。
      • 别忘了致电super.onDialogClosed(positiveResult)

    这是最低限度的,它假设:

    • 您的自定义 DialogPreference 管理单个首选项键/值对。
    • 您有责任保留首选项值。
    • 您正在从资源中扩充对话框面板布局。

    现在提供一些其他选项:

    (a) 如果您想以编程方式创建对话框面板布局,请同时实现 onCreateDialogView(),而不是在构造函数中调用 setDialogLayoutResource()

    (b) 如果您的偏好仅支持单个键/值对,那么当您在 onDialogClosed() 中保留更改的偏好值时,您可以使用帮助程序保存方法 persistBoolean(boolean), persistFloat(float), persistInt(int), persistLong(long), persistString(String)。否则,您需要使用getEditor() 方法,如下所示:

    private MyCustomView myView;
    
    @Override
    protected void onBindDialogView(View view) {
        super.onBindDialogView(view);
    
        // the view was created by my custom onCreateDialogView()
        myView = (MyCustomView)view;
    
        SharedPreferences sharedPreferences = getSharedPreferences();
        myView.setValue1(sharedPreferences.getString(myKey1, myDefaultValue1));
        myView.setValue2(sharedPreferences.getString(myKey2, myDefaultValue2));
    }
    
    @Override
    protected void onDialogClosed(boolean positiveResult) {
        super.onDialogClosed(positiveResult);
    
        if (positiveResult) {
            Editor editor = getEditor();
            editor.putString(myKey1, myView.getValue1());
            editor.putString(myKey2, myView.getValue2());
            editor.commit();
        }
    }
    

    (c) 如果您打算从膨胀的 xml 中提供默认值,那么您还需要实现 onGetDefaultValue(TypedArray a, int index) 方法。


    @RichardNewton,我知道你问这个问题已经一个月了。我希望你仍然可以使用它。

    【讨论】:

    • 哦,关于 onSave/RestoreInstanceState 方法:如果您的自定义对话框面板没有任何要持久的状态,并且您正在自己处理首选项值的持久化,则无需覆盖 onSave/RestoreInstanceState 方法。
    • persistBoolean 和其他类似方法是否会使用提供给 android:key 的密钥存储方法?如果没有提供密钥怎么办?
    • 是的,它将使用提供的 android:key 持续存在。如果没有提供密钥,它将抛出 IllegalStateException("Preference does not have a key assigned.")
    • 你错过了一件事:如果你需要默认值,你需要实现onSetInitialValue()。否则,setDefaultValue()onGetDefaultValue() 都不会保留默认值!
    • 好帖子,谢谢!不过,有一个问题,您展示了如何使用 persist*() 方法保留值,但是反过来呢?换句话说,您如何获得首选项的值——例如在初始化期间,以便可以预先填充对话框中的任何字段?我看到有 getSharedPreferences().getString() 但需要一个键,因此暗示我们知道首选项键是什么,但情况可能并非如此——例如,如果首选项是从 XML (preferences.xml) 添加的。
    猜你喜欢
    • 1970-01-01
    • 2012-09-12
    • 1970-01-01
    • 1970-01-01
    • 2015-09-27
    • 2010-12-06
    • 2014-10-02
    • 2014-01-26
    相关资源
    最近更新 更多