Java 如何显示对话框首选项

Java 如何显示对话框首选项,java,android,android-studio,Java,Android,Android Studio,下面是一个名为some\u layout.xml的随机布局: <?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://

下面是一个名为some\u layout.xml的随机布局:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"">

    <!-- Some views in here -->

</androidx.constraintlayout.widget.ConstraintLayout>
  • 这是首选项屏幕:

    <?xml version="1.0" encoding="utf-8"?>
    <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    
        <android.example.perappbrightness.SomeDialog
                android:title="@string/rate_app"
                android:summary="@string/rate_summary"
                android:key="rate_app"/>
    
    </PreferenceScreen>
    

    设置活动。java是一个未被触及的工具。它来自Android Studio的模板


    我做错了什么?

    首先,您需要向
    SomeDialog
    添加更多构造函数。
    上下文
    构造函数是不够的,因为
    首选项
    将从
    xml
    中膨胀。拥有以下三名施工人员通常就足够了:

    public SomeDialog(Context context) {
        super(context);
    }
    
    public SomeDialog(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    
    public SomeDialog(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    
    除此之外,
    设置活动
    中的
    设置片段
    需要实现显示首选项对话框(首选项)以显示自定义首选项的自定义对话框

    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
        }
    
        @Override
        public void onDisplayPreferenceDialog(Preference preference) {
            if (preference instanceof SomeDialog) {
                MyDialogFragment dialogFragment = new MyDialogFragment();
                Bundle b = new Bundle();
                b.putString(MyDialogFragment.KEY, preference.getKey());
                b.putInt(MyDialogFragment.KEY_LAYOUT_RES_ID,  ((SomeDialog) preference).getDialogLayoutResource());
    
                dialogFragment.setArguments(b);
                dialogFragment.setTargetFragment(this, 0);
                dialogFragment.show(getFragmentManager(), null);
            } else super.onDisplayPreferenceDialog(preference);
        }
    }
    
    最后,您还必须提供自定义对话框本身。这是通过扩展DialogFragment的类来完成的

    我的非常简单的
    DialogFragment
    FrameLayout
    中有一个
    TextView
    ,只是为了说明它是有效的

    MyDialogFragment代码:

    public class MyDialogFragment extends DialogFragment {
    
        public static final String KEY = "key";
        public static final String KEY_LAYOUT_RES_ID = "resid";
    
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                    return inflater.inflate(requireArguments().getInt(KEY_LAYOUT_RES_ID), container, false);
    
        }
    
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            TextView textView = view.findViewById(R.id.textView);
            textView.setText(requireArguments().getString(KEY));
        }
    }
    

    请添加错误消息的其余部分以及实际使用PreferenceScreen资源的代码。理想情况下,尽可能多的代码来重现这个问题。@BömachtBlau嗨。我的设置活动是不变的,就像Android Studio默认生成的一样。不过我还是会发的。是的,谢谢。我的Android Studio抱怨说,PreferenceScreen中不允许使用…SomeDialog元素。不管怎样,当我启动应用程序时,它会崩溃,并显示与我试图找出的相同的消息-或者更确切地说,我试图找出您的设置中缺少的内容(我不是每周都做首选项屏幕;-)。。。。问题似乎是,对于SomeDialog,您只有带有参数上下文的构造函数。如果我添加除SomeDialog(上下文上下文、AttributeSet attrs、int-defStyleAttr、int-defStyleRes)之外的所有构造函数,那么应用程序就不会再崩溃。这似乎是任何可能从xml膨胀的内容(视图)的情况。如果您编写了一个自定义视图类,并且确定只以编程方式创建它,那么上下文构造函数就可以了。
    public static class SettingsFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            setPreferencesFromResource(R.xml.root_preferences, rootKey);
        }
    
        @Override
        public void onDisplayPreferenceDialog(Preference preference) {
            if (preference instanceof SomeDialog) {
                MyDialogFragment dialogFragment = new MyDialogFragment();
                Bundle b = new Bundle();
                b.putString(MyDialogFragment.KEY, preference.getKey());
                b.putInt(MyDialogFragment.KEY_LAYOUT_RES_ID,  ((SomeDialog) preference).getDialogLayoutResource());
    
                dialogFragment.setArguments(b);
                dialogFragment.setTargetFragment(this, 0);
                dialogFragment.show(getFragmentManager(), null);
            } else super.onDisplayPreferenceDialog(preference);
        }
    }
    
    public class MyDialogFragment extends DialogFragment {
    
        public static final String KEY = "key";
        public static final String KEY_LAYOUT_RES_ID = "resid";
    
    
        @Nullable
        @Override
        public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
                    return inflater.inflate(requireArguments().getInt(KEY_LAYOUT_RES_ID), container, false);
    
        }
    
    
        @Override
        public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
            super.onViewCreated(view, savedInstanceState);
            TextView textView = view.findViewById(R.id.textView);
            textView.setText(requireArguments().getString(KEY));
        }
    }