简体   繁体   中英

How do you show a DialogPreference

  • Here is a random layout called some_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>
  • Here is a class SomeDialog .java that extends DialogPreference:

     import android.content.Context; import androidx.preference.DialogPreference; public class SomeDialog extends DialogPreference { public SomeDialog(Context context) { super(context); } @Override public int getDialogLayoutResource() { return R.layout.some_layout; } }
  • And here's the preference screen:

     <?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>

Relevant part of crash error. The line at which MainActivty crashes is PreferenceManager.setDefaultValues(this, R.xml.preferences, false); :

java.lang.RuntimeException: Unable to start activity ComponentInfo{android.example.perappbrightness/android.example.perappbrightness.MainActivity}: android.view.InflateException: Binary XML file line #36: Error inflating class android.example.perappbrightness.SomeDialog
    Caused by: android.view.InflateException: Binary XML file line #36: Error inflating class android.example.perappbrightness.SomeDialog
android.example.perappbrightness.MainActivity.onCreate(MainActivity.java:72)

SettingsActivity .java is an untouched. It's from the template of Android Studio.

What am I doing wrong?

First, you need to add more constructors to SomeDialog . The Context constructor is not enough since the Preference will be inflated from xml . Having the following three constructors is usually sufficient:

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

In addition to that, the SettingsFragment in your SettingsActivity needs to implement onDisplayPreferenceDialog(Preference preference) to show a custom dialog for the custom Preference .

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

And, last not least, you also have to provide the custom dialog itself. This is done via a class extending DialogFragment .

My very simple DialogFragment has a TextView inside a FrameLayout , just to show it works

显示首选项键的非常丑陋的对话框

MyDialogFragment code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM