1

I'm testing the app in the new Android N Preview version and I'm having one problem with the preference activity (in MarshMallow - Android 6.0 and lower versions is working fine).

I'm using: 'com.android.support:appcompat-v7:22.2.1' 'com.android.support:design:22.2.1'

This is the error:

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)

This is the code that is pointing the error:

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();
                }
            });

        }
    }
S.P.
  • 2,274
  • 4
  • 26
  • 57

2 Answers2

1

Try like below to fix issue in android N (API level 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
}
Priyank Patel
  • 12,244
  • 8
  • 65
  • 85
0

From what I see, you have no reason to cast the result of your findViewById to LineraLayout. Just cast it to ViewGroup instead:

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

That said, what is the actual problem you are trying to solve? Do you really want to add a custom component to a system-generated dialog?

EDIT: Based on the additional comments...

The solution in linked question is really a hack, which relies on a private, unpublished implementation of some internal android classes. Most likely, the new version of Android has changed the internal implementation. There's nothing you can do about it. You can try adopting the solution to work on Android N, but then the next version of android may break it again.

If you want a specific layout, you should create your own layout. The easiest thing to do is to move all your Preferences into a PreferenceFragment, then create a regular Activity from an XML with your top view and a placeholder, which you then replace with your Fragment.

This is a lot less work than it seems - I did this with my app recently, took me only about an hour to get everything working.

Aleks G
  • 56,435
  • 29
  • 168
  • 265
  • Is not a good solution 100%. Of course, the app don't crash, but the Toolbar hide the first PreferenceCategory ot the screen if I add ViewGroup – S.P. May 19 '16 at 14:54
  • @DO What are you actually trying to do? – Aleks G May 19 '16 at 14:55
  • test the app in android N. Is working perfectly in the other version. Take a look at this link (http://stackoverflow.com/questions/26564400/creating-a-preference-screen-with-support-v21-toolbar) I'm using the solution of David Passmore of his NESTED PREFERENCE SCREENS – S.P. May 19 '16 at 14:57