使用Android N预览的PreferenceActivity中的ClassCastException

时间:2016-05-19 14:34:21

标签: android

我在新的Android N预览版中测试了该应用,并且我对首选项活动有一个问题(在MarshMallow中 - Android 6.0及更低版本工作正常)。

我正在使用: ' com.android.support:程序兼容性-V7:22.2.1' ' com.android.support:设计:22.2.1'

这是错误:

java.lang.ClassCastException: android.widget.FrameLayout cannot be cast to android.widget.LinearLayout
   at com.myApp.PreferenceActivity.setUpNestedScreen(PreferenceActivity.java:1606)
   at com.myApp.PreferenceActivity.onPreferenceTreeClick(PreferenceActivity.java:1594)
   at android.preference.Preference.performClick(Preference.java:1005)
   at android.preference.PreferenceScreen.onItemClick(PreferenceScreen.java:214)
   at android.widget.AdapterView.performItemClick(AdapterView.java:310)
   at android.widget.AbsListView.performItemClick(AbsListView.java:1155)
   at android.widget.AbsListView$PerformClick.run(AbsListView.java:3087)
   at android.widget.AbsListView$3.run(AbsListView.java:4002)
   at android.os.Handler.handleCallback(Handler.java:739)
   at android.os.Handler.dispatchMessage(Handler.java:95)
   at android.os.Looper.loop(Looper.java:148)
   at android.app.ActivityThread.main(ActivityThread.java:6066)
   at java.lang.reflect.Method.invoke(Native Method)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:770)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:660)

这是指向错误的代码:

public void setUpNestedScreen(PreferenceScreen preferenceScreen) {
        final Dialog dialog = preferenceScreen.getDialog();

        Toolbar bar;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent(); //Here is the line 1606
            View topView = LayoutInflater.from(this).inflate(R.layout.preference_toolbar, root, false);
            root.addView(topView, 0); // insert at top
            bar = (Toolbar) topView.findViewById(R.id.toolbar);

            bar.setTitle(preferenceScreen.getTitle());

            bar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    dialog.dismiss();
                }
            });

        }
    }

2 个答案:

答案 0 :(得分:1)

尝试以下方法修复android N(API级别24)中的问题

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // For API level 24 - Android N 
    LinearLayout root = (LinearLayout) dialog.findViewById(android.R.id.list).getParent().getParent();
    View topView = LayoutInflater.from(this).inflate(R.layout.preference_toolbar, root, false);
    root.addView(topView, 0); // insert at top
}

答案 1 :(得分:0)

从我看到的情况来看,您没有理由将findViewById的结果转换为LineraLayout。只需将其转换为ViewGroup

ViewGroup root = (ViewGroup) dialog.findViewById(android.R.id.list).getParent();
View topView = LayoutInflater.from(this).inflate(R.layout.preference_toolbar, root, false);
root.addView(topView, 0); // insert at top

那就是说,你想解决的实际问题是什么?您真的想将自定义组件添加到系统生成的对话框中吗?

编辑:根据其他评论...

链接问题中的解决方案实际上是一个黑客,它依赖于某些内部安卓类的私有的,未发布的实现。最有可能的是,Android的新版本已经改变了内部实现。你无能为力。您可以尝试使用该解决方案在Android N上运行,但是下一个版本的Android可能会再次破坏它。

如果您想要特定的布局,则应创建自己的布局。最简单的方法是将所有首选项移动到PreferenceFragment中,然后使用顶视图和占位符从XML创建常规Activity,然后将其替换为Fragment。

这比看起来要少得多 - 我最近用我的应用做了这个,花了大约一个小时让一切正常。