Alertdialog.Builder setview: Call requires API level 21

7.7k views Asked by At

I am trying to get a radius NumberPicker running in a class that extends DialogPreference, and I am having a lot of trouble getting setView() to work. Let's start with some code:

public class RadiusPickerPreference extends DialogPreference{
    public RadiusPickerPreference(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    @Override
    protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder builder) {
        builder.setTitle(R.string.set_radius_dialog_fragment_title);
        builder.setView(R.layout.dialog_radius_picker);
        builder.setPositiveButton(android.R.string.ok, null);
        builder.setNegativeButton(android.R.string.cancel, null);
    }
}

This gives me an error on builder.setView saying "Call requires API 21 (current min is 15)." I want to support devices with APIs 15+, so changing this is not an option. Now, if I try to override

protected void onPrepareDialogBuilder(android.support.v7.app.AlertDialog.Builder builder)

instead, it says "Method does not override method from its superclass."

Question is, how can I set the view? It doesn't necessarily have to be in onPrepareDialogBuilder(), as long as it supports API 15+. Thanks!

PS: Let me know if you need more code. To get it displayed in XML, just add this to a <PreferenceScreen>:

<com.example.project.RadiusPickerPreference
    android:id="@+id/radPickerPref"
    android:key="@string/pref_key_default_radius"
    android:title="@string/pref_title_default_radius"/>
3

There are 3 answers

2
T3KBAU5 On BEST ANSWER

What you're trying to do here is call a function that was added in API 21 instead of the one added in API 1. As per the documentation, you want setView(View view) instead of setView(int layoutResId). To get a View from a layout, you need a LayoutInflater. To get an instance of LayoutInflater, you will need a context object. When you create your dialog, I would recommend storing your Context as a variable in the class for future use. Then, in onPrepareDialogBuilder, you can use (as per the docs):

LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE)

Now, you can use inflater to get a View from your layout and set your dialog's View as follows:

 View v = inflater.inflate(R.layout.dialog_radius_picker, null);

So, your code could look like:

@Override
protected void onPrepareDialogBuilder(android.app.AlertDialog.Builder builder) {
    LayoutInflater inflater = (LayoutInflater)context.getSystemService (Context.LAYOUT_INFLATER_SERVICE);
    builder.setTitle(R.string.set_radius_dialog_fragment_title);
    View v = inflater.inflate(R.layout.dialog_radius_picker, null);
    builder.setView(v);
    builder.setPositiveButton(android.R.string.ok, null);
    builder.setNegativeButton(android.R.string.cancel, null);
}

Hopefully that helps!

1
scubasteve623 On

I've had some not so fun experiences trying to customize alert dialogs, and would recommend just bypassing that idea when you really need to have a detailed pop up. Here's some code for a dialog fragment if you'd like to try that route instead...

public class AboutUs extends DialogFragment {



public interface DialogListener {
    void onDialogFinish();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_about_us, container,
            false);
    getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);

    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point(); display.getSize(size);
    int width=size.x; int height=size.y;  //change these to make your dialog the size you wish

    WindowManager.LayoutParams wmlp = getDialog().getWindow().getAttributes();
    wmlp.height=height; wmlp.width=width;

    getDialog().getWindow().setAttributes(wmlp);
    WindowManager.LayoutParams lp = getDialog().getWindow().getAttributes();
    lp.dimAmount=0.4f;
    getDialog().getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
    getDialog().setCanceledOnTouchOutside(true);



    return rootView;
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setStyle(DialogFragment.STYLE_NO_FRAME, android.support.v7.appcompat.R.style.Theme_AppCompat_Light);

}


public AboutUs()
{
}


}




\\to call fragment from activity

AboutUs aboutUs = new AboutUs();
aboutUs.show(getSupportFragmentManager(), "Dialog Fragment");
0
Gabriel Huff On

Instead of calling setView(int resourceId), which requires API21+ just create a View object, inflate the resource and call setView(View view) passing this view.