如何创建使用android.support.v7。preference库定制preferences? [英] How do I create custom preferences using android.support.v7.preference library?
问题描述
我想至少支持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);}
在prepareDialogBuilder(生成器生成器)@覆盖保护无效{
super.on prepareDialogBuilder(制造商);
//做一些与建设者,使一个很好的可爱的对话,例如,像这样
builder.setSingleChoiceItems(新FontAdapter(),0,NULL);
}
}
和使用XML像这样来显示它
< my.app.Font preference机器人:标题=选择字体机器人:总结=不必要的摘要/>
但现在,没有在prepareDialogBuilder
在 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 PreferenceScreen
s). 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()
orpersist*()
) can be found in theDialogPreference
class. - All dialog (-editing) methods (
onBindDialogView(View)
&onDialogClosed(boolean)
) have been moved toPreferenceDialogFragmentCompat
.
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屋!