如何创建使用android.support.v7。preference库定制preferences? [英] How do I create custom preferences using android.support.v7.preference library?

查看:3471
本文介绍了如何创建使用android.support.v7。preference库定制preferences?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想至少支持API 10,我希望能够很好地风格我的preferences,我希望能够有头(或显示 preferenceScreen S)。看来, preferenceActivity ,不能完全 AppCompat 的色彩支持,将不适合。所以我想用 AppCompatActivity preferenceFragmentCompat

公共类preFS延伸AppCompatActivity {     @覆盖     保护无效的onCreate(包savedInstanceState){         super.onCreate(savedInstanceState);         如果(savedInstanceState == NULL)             getSupportFragmentManager()的BeginTransaction()                     .replace(android.R.id.content,新的preferencesFragment())                     。承诺();     }     公共静态类preferencesFragment扩展preferenceFragmentCompat {         @覆盖公共无效的onCreate(最终捆绑savedInstanceState){             super.onCreate(savedInstanceState);             加preferencesFromResource(R.xml preferences。);         }         @覆盖         公共无效onDisplay preferenceDialog(preference preference){             //在对话以下调用结果示             super.onDisplay preferenceDialog(preference);         }         @覆盖公共无效onNavigateToScreen(preferenceScreen preferenceScreen){             //我也许可以用这个去到嵌套preference屏幕             // 我不确定...         }     } }

现在,我想创建一个自定义的preference,将提供一个字体的选择。随着 preferenceActivity ,我可以简单地做

进口安卓preference.Dialog preference。 公共类字体preference扩展对话框preference {     公共字体preference(上下文的背景下,ATTRS AttributeSet中){超(背景下,ATTRS);}     在prepareDialogBu​​ilder(生成器生成器)@覆盖保护无效{         super.on prepareDialogBu​​ilder(制造商);         //做一些与建设者,使一个很好的可爱的对话,例如,像这样         builder.setSingleChoiceItems(新FontAdapter(),0,NULL);     } }

和使用XML像这样来显示它

< my.app.Font preference机器人:标题=选择字体机器人:总结=不必要的摘要/>

但现在,没有在prepareDialogBu​​ilder android.support.v7。preference.Dialog preference 。相反,它被转移到 preferenceDialogFragmentCompat 。我发现很少谈到如何使用的东西,我不知道如何从XML去显示它。 V14 preference片段具有以下code:

公共无效onDisplay preferenceDialog(preference preference){     ...     最后DialogFragment F;     如果(preference的instanceof的EditText preference)         F =的EditText preferenceDialogFragment.newInstance(preference.getKey());     ...     f.show(getFragmentManager(),DIALOG_FRAGMENT_TAG); }

我试着子类 android.support.v7。preference.Dialog preference 并具有 onDisplay preferenceDialog 使用类似的一块code实例化一个虚拟的字体preferenceFragment ,但它失败,出现以下异常。

  java.lang.IllegalStateException:目标片段必须实现TargetFragment接口
 

在这一点上,我已经过深陷入困境,不希望进一步挖掘。谷歌知道任何有关此异常。不管怎么说,这种方法似乎过于复杂。那么,什么是使用android.support.v7创建自定义preferences的最佳途径。preference库?

解决方案
  

重要提示:   目前(v23.0.1的V7库)仍有大量的主题问题的'preferenceThemeOverlay'(见的这个问题)。在棒棒糖例如,你最终得到的全息风格类的标题。

有些令人沮丧小时后,我终于成功地创建自定义的V7 preference。创建自己的 preference 似乎比你想象的是需要更加努力。所以,一定要花费一些时间。

起初,你可能想知道为什么你会发现既有对话preference preferenceDialogFragmentCompat 每个preference类型。事实证明,第一个是实际的preference,二是 DialogFragment ,其中preference将显示在可悲的是,您需要子类的两个的人。

不要担心,你不需要改变任何一件code。你只需要搬迁一些方法:

  • 所有preference编辑方法(如的setTitle()一直存在*())可在对话框preference 类中。
  • 在所有对话框(-editing)方法( onBindDialogView(查看)&安培; onDialogClosed(布尔))已搬到 preferenceDialogFragmentCompat

您可能需要现有的类来扩展第一个,这样你就不必改变太多,我认为。自动完成可以帮助你找到丢失的方法。

当你完成上述步骤后,现在是时候这两个类绑定在一起。在XML文件中,您将参考​​preference部分。但是,Android不知道还该片段必须充气时,您的自定义preference需要的地方。因此,你需要重写 onDisplay preferenceDialog(preference)

  @覆盖
公共无效onDisplay preferenceDialog(preference preference){
    DialogFragment片段;
    如果(preference的instanceof LocationChooserDialog){
        片段= LocationChooserFragmentCompat.newInstance(preference);
        fragment.setTargetFragment(此,0);
        fragment.show(getFragmentManager(),
                。android.support.v7 preference preferenceFragment.DIALOG);
    }其他super.onDisplay preferenceDialog(preference);
}
 

和还您 DialogFragment 需要处理的钥匙:

 公共静态你的preferenceDialogFragmentCompat的newInstance(preference preference){
    您的preferenceDialogFragmentCompat片段=新你的preferenceDialogFragmentCompat();
    束束=新软件包(1);
    bundle.putString(钥匙,preference.getKey());
    fragment.setArguments(包);
    返回片段;
}
 

这是应该做的伎俩。如果遇到问题,可以尝试采取看看现有的子类,看看机器人是如何解决它(在Android的工作室:输入类的名称,preSS按Ctrl + B看到反编译的类)。希望它能帮助。

I want to support at least api 10, I want to be able to style my preferences nicely, I want to be able to have headers (or to show PreferenceScreens). It seems that PreferenceActivity, not fully supported by AppCompat's coloring, will not fit. So I'm trying to use AppCompatActivity and PreferenceFragmentCompat.

public class Prefs extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (savedInstanceState == null)
            getSupportFragmentManager().beginTransaction()
                    .replace(android.R.id.content, new PreferencesFragment())
                    .commit();
    }

    public static class PreferencesFragment extends PreferenceFragmentCompat {
        @Override public void onCreate(final Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            addPreferencesFromResource(R.xml.preferences);
        }

        @Override
        public void onDisplayPreferenceDialog(Preference preference) {
            // the following call results in a dialogue being shown
            super.onDisplayPreferenceDialog(preference);
        }

        @Override public void onNavigateToScreen(PreferenceScreen preferenceScreen) {
            // I can probably use this to go to to a nested preference screen
            // I'm not sure...
        }
    }
}

Now, I want to create a custom preference that will provide the choice of a font. With PreferenceActivity, I could simply do

import android.preference.DialogPreference;

public class FontPreference extends DialogPreference {

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

    @Override protected void onPrepareDialogBuilder(Builder builder) {
        super.onPrepareDialogBuilder(builder);
        // do something with builder and make a nice cute dialogue, for example, like this
        builder.setSingleChoiceItems(new FontAdapter(), 0, null);
    }
}

and use xml such as this to display it

<my.app.FontPreference android:title="Choose font" android:summary="Unnecessary summary" />

But now, there is no onPrepareDialogBuilder in android.support.v7.preference.DialogPreference. Instead, it's been moved to PreferenceDialogFragmentCompat. I found little information on how to use that thing, and I'm not sure how to go from xml to displaying it. v14 preference fragment has the following code:

public void onDisplayPreferenceDialog(Preference preference) {
    ...

    final DialogFragment f;
    if (preference instanceof EditTextPreference)
        f = EditTextPreferenceDialogFragment.newInstance(preference.getKey());
    ...
    f.show(getFragmentManager(), DIALOG_FRAGMENT_TAG);
}

I tried subclassing android.support.v7.preference.DialogPreference and having onDisplayPreferenceDialog use a similar piece of code to instantiate a dummy FontPreferenceFragment but it fails with the following exception.

java.lang.IllegalStateException: Target fragment must implement TargetFragment interface

At this point I'm already too deep into the mess and don't want to dig further. Google knows nothing about this exception. Anyways, this method seems to be overly complicated. So, what's the best way to create custom preferences using android.support.v7.preference library?

解决方案

Important note: Currently (v23.0.1 of the v7 library) there are still a lot of theme-issues with the 'PreferenceThemeOverlay'(see this issue). On Lollipop for example, you end up with Holo-styled category headers.

After some frustrating hours, I finally succeeded to create a custom v7 Preference. Creating your own Preference appears to be harder than you might think is needed. So make sure to take some time.

At first you might be wondering why you will find both a DialogPreference and a PreferenceDialogFragmentCompat for each preference type. As it turns out, the first one is the actual preference, the second is the DialogFragment where the preference would be displayed in. Sadly, you are required to subclass both of them.

Don't worry, you won't need to change any piece of code. You only need to relocate some methods:

  • All preference-editing methods (like setTitle() or persist*()) can be found in the DialogPreference class.
  • All dialog (-editing) methods (onBindDialogView(View) & onDialogClosed(boolean)) have been moved to PreferenceDialogFragmentCompat.

You might want your existing class to extend the first one, that way you don't have to change to much I think. Autocomplete should help you find missing methods.

When you have completed the above steps, it is time to bind these two classes together. In your xml file, you will refer to the preference-part. However, Android doesn't know yet which Fragment it must inflate when your custom preference needs to be. Therefore, you need to override onDisplayPreferenceDialog(Preference):

@Override
public void onDisplayPreferenceDialog(Preference preference) {
    DialogFragment fragment;
    if (preference instanceof LocationChooserDialog) {
        fragment = LocationChooserFragmentCompat.newInstance(preference);
        fragment.setTargetFragment(this, 0);
        fragment.show(getFragmentManager(),
                "android.support.v7.preference.PreferenceFragment.DIALOG");
    } else super.onDisplayPreferenceDialog(preference);
}

and also your DialogFragment needs to handle the 'key':

public static YourPreferenceDialogFragmentCompat newInstance(Preference preference) {
    YourPreferenceDialogFragmentCompat fragment = new YourPreferenceDialogFragmentCompat();
    Bundle bundle = new Bundle(1);
    bundle.putString("key", preference.getKey());
    fragment.setArguments(bundle);
    return fragment;
}

That should do the trick. If you encounter problems, try taking a look at existing subclasses and see how Android solved it (in Android Studio: type a class' name and press Ctrl+b to see the decompiled class). Hope it helps.

这篇关于如何创建使用android.support.v7。preference库定制preferences?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆