是否故意将PreferenceFragment排除在兼容性包之外?

Jam*_*mes 153 compatibility android android-3.0-honeycomb

我正在寻找可以应用于3.0和3.0之前的设备的首选项.发现PreferenceActivity包含已弃用的方法(虽然这些方法在随附的示例代码中使用),我查看PreferenceFragement了兼容性包以解决我的困境.

但是,它似乎PreferenceFragment不在兼容包中.谁能告诉我这是否是故意的?如果是这样,我可以轻松定位一系列设备(即<3.0和> = 3.0)还是我必须跳过篮球?如果没有故意排除,我们是否可以期待兼容包的新版本?或者是否有另一种可以安全使用的解决方法?

干杯

詹姆士

Com*_*are 90

发现PreferenceActivity包含已弃用的方法(尽管这些方法在随附的示例代码中使用)

从Android 3.0开始,不推荐使用已弃用的方法.它们适用于所有Android版本,但方向是PreferenceFragment在Android 3.0及更高版本上使用.

谁能告诉我这是否是故意的?

我的猜测是工程时间问题,但这只是猜测.

如果是这样,我可以轻松定位一系列设备(即<3.0和> = 3.0)还是我必须跳过篮球?

我认为这是"轻松"完成的.有两个单独的PreferenceActivity实现,一个使用首选项标头PreferenceFragments,另一个使用原始方法.在您需要的位置选择正确的(例如,当用户点击选项菜单项时).这是一个示例项目.或者,有一个PreferenceActivity处理这两种情况的单一内容,如此示例项目中所示.

如果没有故意排除,我们是否可以期待兼容包的新版本?

你会发现我们其他人何时发现,也就是说,它何时何地发货.

或者是否有另一种可以安全使用的解决方法?

往上看.

  • @JustinBuser为了记录,Mark确实回答了我的问题.从我接受他的回答中可以看出这一点. (9认同)
  • @JustinBuser:"问题在于遗漏是否是故意的" - 唯一可以回答Google工作的人.欢迎您在Google找到一份工作,试图找出答案."没有办法按照你所描述的方式扩展PreferenceActivity" - 欢迎你下载我链接的代码. (8认同)
  • 对不起,但我不确定你要在这里做点什么.您根本不回答任何问题,只是评论/猜测/引用与问题无关的无关外部链接.问题是遗漏是否是有意的,_outout_兼容版本的PreferenceFragment没有办法以你描述的方式扩展PreferenceActivity,因为如果PreferenceFragment不存在那么getSupportFragmentManager()或任何其他方法都没有首先需要使用碎片. (7认同)

Ten*_*ous 21

@CommonsWare答案的微妙含义是 - 您的应用必须在兼容性API或内置片段API之间进行选择(自SDK 11以来).事实上,这就是"轻松"推荐所做的事情.换句话说,如果您想使用PreferenceFragment,您的应用需要使用内置片段API并处理PreferenceActivity上不推荐使用的方法.相反,如果您的应用程序使用compat很重要.您将面临的API根本没有PreferenceFragment类.因此,定位设备不是问题,但是当您必须选择一个或另一个API并因此将您的设计提交给无法预见的变通方法时,会发生跳跃.我需要compat.API所以我将创建自己的PreferenceFragment类,看看它是如何工作的.在最糟糕的情况下,我将创建一个普通(片段)布局并手动将视图组件绑定到sharedprefs ...呃.

编辑:尝试并查看http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/preference/PreferenceFragment.java上的代码后? av = h - 创建我自己的PreferenceFragment不会发生.似乎在PreferenceManager中自由使用package-private而不是'protected'是主要阻止程序.它真的看起来没有任何安全性或真正良好的动力来完成它并且它对于单元测试来说并不是很好但是哦......好吧打字我猜...

编辑v2:实际上确实发生了它并且有效.使代码与兼容性API JAR一起工作绝对令人头疼.我不得不将大约70%的com.android.preference软件包从SDK复制到我的应用程序,然后在Android中与典型的中等质量Java代码搏斗.我使用了v14的SDK.对于一个Goog工程师来说,做我做的事情要容易得多,这与我听到一些Android工程师对这个话题所说的相反.

顺便说一句 - 我说"定位设备不是问题"吗?它完全是......如果你使用com.android.preference,你将无法在没有重大重构的情况下更换兼容性API.有趣的日志!

  • 你愿意分享你是怎么做到的吗?我遇到了完全相同的问题,只有我的PreferenceActivity必须使用Loaders,因此我必须**使用兼容性库. (4认同)
  • @Tenacious我喜欢你的调查 - 干得好.但是,我觉得有人应该在你的第一个评论中直接记录--Commonsware的代码将用于HC设备的前后 - 在做出类似评论之前先尝试一下.您需要意识到的是在运行时使用的后期绑定来支持以前的设备.运行时的版本检查负责支持两个操作系统系列 - 这是一个常见的Android模式(不是我喜欢的模式 - 但对于Android开发人员学习和熟悉的重要模式)...所以对于未来的读者 - 不要不要采取任何一种做法. (3认同)

Unc*_*key 16

基于CommonsWare的答案以及顽强的观察,我提出了一个单一的后代类解决方案,能够以最小的麻烦和没有代码或资源重复的方式针对所有当前的Android API版本.请在此处查看我对相关问题的回答: PreferenceActivity Android 4.0及更早版本

或者在我的博客上:http: //www.blackmoonit.com/2012/07/all_api_prefsactivity/

测试了运行4.0.3和4.0.4的两个平板电脑以及运行4.0.4和2.3.3的手机以及运行1.6的模拟器.


the*_*ang 10

请参阅Machinarius的PreferenceFragment-Compat.很容易用gradle进入,我忘了它甚至在那里.

compile 'com.github.machinarius:preferencefragment:0.1.1'

重要更新:最新版本v7 support library现在有一个本地PreferenceFragmentCompat.


Gab*_*tti 10

2015年8月,Google发布了新的Preference Support Library v7.

现在,您可以将PreferenceFragmentCompat与任何Activity或使用AppCompatActivity

public static class PrefsFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Load the preferences from an XML resource
        addPreferencesFromResource(R.xml.preferences);
    }
}
Run Code Online (Sandbox Code Playgroud)

你必须preferenceTheme在你的主题中设置:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  ...
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以自定义preferenceTheme用于为每种首选项类型设置的布局样式,而不会影响Activity的其他部分.


mhs*_*ith 7

顽强的回答是正确的,但这里有更多细节.

您无法"创建正常布局并将视图组件手动绑定到sharedprefs"的原因是android.preferences API中存在一些令人惊讶的遗漏.PreferenceActivity和PreferenceFragment都可以访问关键的非公共PreferenceManager方法,没有这些方法,您就无法实现自己的首选项UI.

特别是,要从XML文件构造Preference层次结构,您需要使用PreferenceManager,但PreferenceManager的所有构造函数都是包私有或隐藏的.将Preference onClick侦听器附加到您的活动的方法也是package-private.

你不能通过偷偷把你的实现放在android.preferences包中解决这个问题,因为Android中的非公共方法实际上是从SDK中省略的.通过一些涉及反射和动态代理的创造力,您仍然可以获得它们.正如Tenacious所说,唯一的选择是分叉整个android.preference包,包括至少15个类,5个布局,以及类似数量的style.xml和attrs.xml元素.

因此,为了回答原始问题,谷歌在兼容性软件包中没有包含PreferenceFragment的原因是他们会遇到与Tenacious和我一样的难度.甚至谷歌也无法及时回归并在旧平台上公开这些方法(尽管我希望他们在未来的版本中这样做).