Skip to content

Most visited

Recently visited

navigation

ダイアログ

ダイアログは、ユーザーによる意思決定や追加情報の入力用に表示される小さなウィンドウです。 ダイアログは全画面に表示されることはなく、通常はユーザーが処理を続ける前にアクションを起こす必要があるモーダル イベントに使用されます。

ダイアログ デザイン

ダイアログをデザインする方法について(言語に対する推奨を含む)は、ダイアログ デザインのガイドをお読みください。

Dialog クラスは、ダイアログの基本クラスですが、Dialog ディレクトリのインスタンスを作成することは避けてください。代わりに、次のいずれかのサブクラスを使用します。

AlertDialog
タイトル、最大 3 つのボタン、選択可能なアイテムやカスタム レイアウトのリストを表示できるダイアログ。
DatePickerDialog または TimePickerDialog
ユーザーが日付または時刻を選択できるようにあらかじめ定義された UI を含むダイアログ。

これらのクラスでは、ダイアログのスタイルと構造が定義されますが、ダイアログのコンテナとして DialogFragment を使用してください。DialogFragment クラスでは、Dialog オブジェクトでメソッドを呼び出す代わりに、ダイアログの作成と表示の管理に必要なすべてのコントロールが提供されます。

DialogFragment を使ってダイアログを管理すると、ライフサイクル イベント(「戻る」ボタンを選択したときや画面を回転したときなど)が正しく処理されます。 DialogFragment クラスを使用すると、従来の Fragment のように、大きな UI で埋め込み可能なコンポーネントとしてダイアログの UI を再利用することもできます(ダイアログ UI を大小の画面で異なって表示させる場合など)。

このガイドの次のセクションでは、AlertDialog オブジェクトと組み合わせて DialogFragment を使用する方法について説明します。 日付や時刻ピッカーを作成する場合は、Pickers のガイドをご覧ください。

注: DialogFragment クラスは 元々 Android 3.0(API レベル 11)で追加されたため、このドキュメントではサポート ライブラリと一緒に提供される DialogFragment クラスの使用方法について説明します。 アプリにこのライブラリを追加すると、Android 1.6 以降を実行する端末で、DialogFragment とその他のさまざまな API を使うことができます。 アプリでサポートする最小バージョンが API レベル 11 以上の場合、DialogFragment のフレームワーク バージョンを使用できますが、このドキュメントのリンクはサポート ライブラリ API 向けであることにご注意ください。 サポート ライブラリを使用するときは、android.app.DialogFragment ではなく、android.support.v4.app.DialogFragment クラス をインポートしてください。

Dialog Fragment を作成する

DialogFragment を拡張して onCreateDialog() コールバック メソッドで AlertDialog を作成することで、さまざまなダイアログ デザイン(カスタム レイアウトやダイアログのデザインガイドで説明されているものを含む)を実現できます。

DialogFragment で管理される基本的な AlertDialog を次に示します。

public class FireMissilesDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Use the Builder class for convenient dialog construction
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // FIRE ZE MISSILES!
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // User cancelled the dialog
                   }
               });
        // Create the AlertDialog object and return it
        return builder.create();
    }
}

図 1 メッセージと 2 つのアクション ボタンを含むダイアログ

このクラスのインスタンスを作成して、オブジェクトで show() を呼び出すと、図 1 のようなダイアログが表示されます。

次のセクションでは、AlertDialog.Builder API を使ったダイアログの作成について詳細を説明します。

ダイアログの複雑さに応じて、DialogFragment ですべての基本的なフラグメントのライフサイクル メソッドを含む、他のさまざまなコールバック メソッドを実装できます。

アラート ダイアログをビルドする

AlertDialog クラスを使って、さまざまなダイアログ デザインをビルドできます。ほとんどの場合、必要なダイアログ クラスはこれだけです。図 2 のように、アラート ダイアログには 3 つの領域があります。

図 2 ダイアログのレイアウト

  1. タイトル

    この領域は省略可能で、コンテンツ エリアが詳細メッセージ、リスト、カスタム レイアウトで占有されている場合にのみ使う必要があります。 単純なメッセージや質問(図 1 にあるダイアログなど)を記述する場合は、タイトルは必要ありません。

  2. コンテンツ エリア

    メッセージ、リスト、その他のカスタム レイアウトを表示できます。

  3. アクション ボタン

    1 つのダイアログ内に置くアクション ボタンは、3 つ以内にする必要があります。

AlertDialog.Builder クラスで提供される API を使用すると、カスタム レイアウトなど、これらの種類のコンテンツを含む AlertDialog を作成できます。

AlertDialog をビルドするには:

// 1. Instantiate an AlertDialog.Builder with its constructor
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());

// 2. Chain together various setter methods to set the dialog characteristics
builder.setMessage(R.string.dialog_message)
       .setTitle(R.string.dialog_title);

// 3. Get the AlertDialog from create()
AlertDialog dialog = builder.create();

次のトピックでは、AlertDialog.Builder クラスを使ってさまざまなダイアログの属性を定義する方法を示します。

ボタンを追加する

図 2 のようなアクション ボタンを追加するには、setPositiveButton()setNegativeButton() メソッドを呼び出します。

AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Add the buttons
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User clicked OK button
           }
       });
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
           public void onClick(DialogInterface dialog, int id) {
               // User cancelled the dialog
           }
       });
// Set other dialog properties
...

// Create the AlertDialog
AlertDialog dialog = builder.create();

set...Button() メソッドには、ボタンのタイトル(文字列リソースで指定)と、ユーザーがボタンを押したときに実行するアクションを定義する DialogInterface.OnClickListener が必要です。

追加できるアクション ボタンは、次の 3 つです。

Positive
アクションを受け入れて続ける場合に使います(「OK」アクション)。
Negative
アクションをキャンセルする場合に使います。
Neutral
ユーザーがアクションを続けたくない可能性があり、キャンセルしたいとは限らない場合に使います。 ポジティブ ボタンとネガティブ ボタンの間に表示されます。 たとえば、「後で通知する」のようなアクションの場合です。

各ボタンタイプのいずれか 1 つのみを AlertDialog に追加できます。つまり、2 つ以上の「ポジティブ」ボタンを置くことはできません。

図 3 タイトルとリストを含むダイアログ

リストを追加する

AlertDialog API で使用できるリストは次の 3 種類です。

図 3 のように、排他的選択リストを作成するには、setItems() メソッドを使います。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    builder.setTitle(R.string.pick_color)
           .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int which) {
               // The 'which' argument contains the index position
               // of the selected item
           }
    });
    return builder.create();
}

リストは、ダイアログのコンテンツ エリアに表示されるため、ダイアログにはメッセージとリストの両方は表示できません。setTitle() でダイアログのタイトルを設定してください。リストのアイテムを指定するには、setItems() を呼び出して配列を渡します。setAdapter() を使ってリストを指定することもできます。 こうすることで、ListAdapter を使って、データベースからなど、ダイナミック データを含むリストを返すことができます。

ListAdapter を使ってリストを返すことを選択する場合は、必ず Loader を使ってコンテンツが非同期で読み込まれるようにします。 この詳細については、Building Layouts with an Adapterローダのガイドをご覧ください。

注: デフォルトでは、次の固定選択リストのいずれかを使っていない場合、リストアイテムをタップするとダイアログが閉じられます。

図 4 複数選択アイテムのリスト

固定の複数選択または排他的選択リストを追加する

複数選択アイテム(チェックボックス)または排他的選択アイテム(ラジオボタン)のリストを追加するには、setMultiChoiceItems() または setSingleChoiceItems() メソッドをそれぞれ使用します。

ArrayList で選択されたアイテムを保存する、図 4 にあるような複数選択リストを作成する方法を次に示します。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    mSelectedItems = new ArrayList();  // Where we track the selected items
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Set the dialog title
    builder.setTitle(R.string.pick_toppings)
    // Specify the list array, the items to be selected by default (null for none),
    // and the listener through which to receive callbacks when items are selected
           .setMultiChoiceItems(R.array.toppings, null,
                      new DialogInterface.OnMultiChoiceClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int which,
                       boolean isChecked) {
                   if (isChecked) {
                       // If the user checked the item, add it to the selected items
                       mSelectedItems.add(which);
                   } else if (mSelectedItems.contains(which)) {
                       // Else, if the item is already in the array, remove it
                       mSelectedItems.remove(Integer.valueOf(which));
                   }
               }
           })
    // Set the action buttons
           .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // User clicked OK, so save the mSelectedItems results somewhere
                   // or return them to the component that opened the dialog
                   ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   ...
               }
           });

    return builder.create();
}

従来のリストとラジオボタンを含むリストでは、ともに「排他的選択」アクションが提供されますが、ユーザーの選択内容を保持したい場合は、setSingleChoiceItems() を使用してください。つまり、ダイアログを後でもう一度開く場合は、ユーザーによって現在選択されているアイテムを示し、ラジオボタンを含むリストを作成します。

カスタム レイアウトを作成する

図 5 カスタム ダイアログのレイアウト

ダイアログでカスタム レイアウトが必要な場合は、レイアウトを作成し、AlertDialog.Builder オブジェクトで setView() を呼び出して AlertDialog にそのレイアウトを追加します。

デフォルトでは、カスタム レイアウトは、ダイアログ ウィンドウ全体に表示されますが、AlertDialog.Builder メソッドを使ってボタンとタイトルを追加できます。

以下は、図 5 にあるダイアログのレイアウト ファイルです。

res/layout/dialog_signin.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">
    <ImageView
        android:src="@drawable/header_logo"
        android:layout_width="match_parent"
        android:layout_height="64dp"
        android:scaleType="center"
        android:background="#FFFFBB33"
        android:contentDescription="@string/app_name" />
    <EditText
        android:id="@+id/username"
        android:inputType="textEmailAddress"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="4dp"
        android:hint="@string/username" />
    <EditText
        android:id="@+id/password"
        android:inputType="textPassword"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="4dp"
        android:layout_marginLeft="4dp"
        android:layout_marginRight="4dp"
        android:layout_marginBottom="16dp"
        android:fontFamily="sans-serif"
        android:hint="@string/password"/>
</LinearLayout>

ヒント: デフォルトでは、"textPassword" 入力タイプを使うために、EditText 要素を設定すると、フォント ファミリーが monospace に設定されます。よって、フォント ファミリーを "sans-serif" に変えて、両方のテキスト フィールドで同じフォント スタイルが使用されるようにしてください。

DialogFragment でレイアウトをインフレートするには、getLayoutInflater()LayoutInflater を取得して inflate() を呼び出します。最初のパラメータは、レイアウト リソース ID で、2 番目のパラメータはレイアウトの親ビューです。その後、setView() を呼び出してダイアログのレイアウトを配置できます。

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
    AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
    // Get the layout inflater
    LayoutInflater inflater = getActivity().getLayoutInflater();

    // Inflate and set the layout for the dialog
    // Pass null as the parent view because its going in the dialog layout
    builder.setView(inflater.inflate(R.layout.dialog_signin, null))
    // Add action buttons
           .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
               @Override
               public void onClick(DialogInterface dialog, int id) {
                   // sign in the user ...
               }
           })
           .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
               public void onClick(DialogInterface dialog, int id) {
                   LoginDialogFragment.this.getDialog().cancel();
               }
           });
    return builder.create();
}

ヒント: カスタム ダイアログが必要な場合は、Dialog API を使う代わりに、Activity をダイアログとして表示できます。 アクティビティを作成し、<activity> マニフェスト要素でそのテーマを Theme.Holo.Dialog に設定します。

<activity android:theme="@android:style/Theme.Holo.Dialog" >

これだけです。これで、アクティビティは全画面でなく、ダイアログ ウィンドウに表示されるようになります。

ダイアログのホストにイベントを渡す

ユーザーがダイアログのアクション ボタンのいずれかをタップするか、そのリストからアイテムを選択すると、DialogFragment によって必要なアクションが実行される場合がありますが、ダイアログを開くアクティビティやフラグメントにイベントを配信したい場合もよくあります。 これを行うには、クリック イベントの各タイプのメソッドでインターフェースを定義します。次に、ダイアログからアクション イベントを受け取るホスト コンポーネントでインターフェースを実装します。

ホスト アクティビティにイベントを配信するインターフェースを定義する DialogFragment を次に示します。

public class NoticeDialogFragment extends DialogFragment {

    /* The activity that creates an instance of this dialog fragment must
     * implement this interface in order to receive event callbacks.
     * Each method passes the DialogFragment in case the host needs to query it. */
    public interface NoticeDialogListener {
        public void onDialogPositiveClick(DialogFragment dialog);
        public void onDialogNegativeClick(DialogFragment dialog);
    }

    // Use this instance of the interface to deliver action events
    NoticeDialogListener mListener;

    // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        // Verify that the host activity implements the callback interface
        try {
            // Instantiate the NoticeDialogListener so we can send events to the host
            mListener = (NoticeDialogListener) activity;
        } catch (ClassCastException e) {
            // The activity doesn't implement the interface, throw exception
            throw new ClassCastException(activity.toString()
                    + " must implement NoticeDialogListener");
        }
    }
    ...
}

ダイアログをホスティングするアクティビティによって、ダイアログ フラグメントのコンストラクタを使ってダイアログのインスタンスが作成され、NoticeDialogListener インターフェースの実装によってダイアログのイベントが受信されます。

public class MainActivity extends FragmentActivity
                          implements NoticeDialogFragment.NoticeDialogListener{
    ...

    public void showNoticeDialog() {
        // Create an instance of the dialog fragment and show it
        DialogFragment dialog = new NoticeDialogFragment();
        dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
    }

    // The dialog fragment receives a reference to this Activity through the
    // Fragment.onAttach() callback, which it uses to call the following methods
    // defined by the NoticeDialogFragment.NoticeDialogListener interface
    @Override
    public void onDialogPositiveClick(DialogFragment dialog) {
        // User touched the dialog's positive button
        ...
    }

    @Override
    public void onDialogNegativeClick(DialogFragment dialog) {
        // User touched the dialog's negative button
        ...
    }
}

ホスト アクティビティによって(上記の onAttach() コールバック メソッドで適用される)NoticeDialogListener が実装されるため、ダイアログ フラグメントではインターフェース コールバック メソッドを使ってアクティビティにクリック イベントを配信できます。

public class NoticeDialogFragment extends DialogFragment {
    ...

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // Build the dialog and set up the button click handlers
        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setMessage(R.string.dialog_fire_missiles)
               .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the positive button event back to the host activity
                       mListener.onDialogPositiveClick(NoticeDialogFragment.this);
                   }
               })
               .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
                   public void onClick(DialogInterface dialog, int id) {
                       // Send the negative button event back to the host activity
                       mListener.onDialogNegativeClick(NoticeDialogFragment.this);
                   }
               });
        return builder.create();
    }
}

ダイアログを表示する

ダイアログを表示する場合、DialogFragment のインスタンスを作成して show() を呼び出し、FragmentManager とダイアログ フラグメントのタグ名を渡します。

FragmentActivity から getSupportFragmentManager() を、または Fragment から getFragmentManager() を呼び出して FragmentManager を取得できます。 次に例を示します。

public void confirmFireMissiles() {
    DialogFragment newFragment = new FireMissilesDialogFragment();
    newFragment.show(getSupportFragmentManager(), "missiles");
}

2 番目の引数 "missiles" は、固有のタグ名で、システムはこれを使って必要な時にフラグメントの状態を保存して復元します。 そのタグを使って、findFragmentByTag() を呼び出してフラグメントを操作することもできます。

全画面でまたは埋め込まれたフラグメントとしてダイアログを表示する

場合によっては、UI の一部をダイアログとして表示させ、それ以外の場合には、たとえば端末の画面の大小に応じて、全画面や埋め込まれたフラグメントとして表示させるよう UI を設計できます。 DialogFragment クラスは、埋め込み可能な Fragment として動作できるため、この柔軟性を実現できます。

ただし、この場合は、AlertDialog.Builder やその他の Dialog オブジェクトを使ってダイアログをビルドできません。 DialogFragment を埋め込み可能にする場合、レイアウトでダイアログの UI を定義し、onCreateView() コールバックでレイアウトを読み込んでください。

ダイアログまたは埋め込み可能なフラグメントのいずれかとして(purchase_items.xml という名前のレイアウトを使って)表示できる DialogFragment の例を次に示します。

public class CustomDialogFragment extends DialogFragment {
    /** The system calls this to get the DialogFragment's layout, regardless
        of whether it's being displayed as a dialog or an embedded fragment. */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        // Inflate the layout to use as dialog or embedded fragment
        return inflater.inflate(R.layout.purchase_items, container, false);
    }

    /** The system calls this only when creating the layout in a dialog. */
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        // The only reason you might override this method when using onCreateView() is
        // to modify any dialog characteristics. For example, the dialog includes a
        // title by default, but your custom layout might not need it. So here you can
        // remove the dialog title, but you must call the superclass to get the Dialog.
        Dialog dialog = super.onCreateDialog(savedInstanceState);
        dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
        return dialog;
    }
}

画面サイズに基づいて、フラグメントをダイアログとしてまたは全画面の UI として表示するかどうかを決めるコードの一例も示します。

public void showDialog() {
    FragmentManager fragmentManager = getSupportFragmentManager();
    CustomDialogFragment newFragment = new CustomDialogFragment();

    if (mIsLargeLayout) {
        // The device is using a large layout, so show the fragment as a dialog
        newFragment.show(fragmentManager, "dialog");
    } else {
        // The device is smaller, so show the fragment fullscreen
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        // For a little polish, specify a transition animation
        transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        // To make it fullscreen, use the 'content' root view as the container
        // for the fragment, which is always the root view for the activity
        transaction.add(android.R.id.content, newFragment)
                   .addToBackStack(null).commit();
    }
}

フラグメントのトランザクション実行の詳細については、フラグメントのガイドをご覧ください。

この例では、mIsLargeLayout ブール値によって、現在の端末でアプリの大きなレイアウト デザインを使う(その結果、全画面でなく、このフラグメントをダイアログとして表示する)かどうかが指定されます。 この種のブール値を設定する最良の方法は、異なる画面サイズに対して別のリソース値ブールリソース値を宣言することです。 次に、異なる画面サイズのブールリソースを 2 種類示します。

res/values/bools.xml

<!-- Default boolean values -->
<resources>
    <bool name="large_layout">false</bool>
</resources>

res/values-large/bools.xml

<!-- Large screen boolean values -->
<resources>
    <bool name="large_layout">true</bool>
</resources>

アクティビティの onCreate() メソッド中に、mIsLargeLayout 値を初期化できます。

boolean mIsLargeLayout;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
}

大画面でアクティビティをダイアログとして表示する

小画面のときにダイアログを全画面の UI として表示するのではなく、大画面のときに Activity をダイアログとして表示することで、同じ結果を得ることができます。 どちらの方法を選択するかはアプリのデザインによって異なりますが、アプリが小画面で設計されていて、存在期間が短いアクティビティをダイアログとして示すことでタブレットでの使用感を改善するときには、ほとんどの場合、アクティビティをダイアログとして表示する方法が役立ちます。

大画面のときにのみ、アクティビティをダイアログとして表示するには、Theme.Holo.DialogWhenLarge テーマを <activity> マニフェスト要素に適用します。

<activity android:theme="@android:style/Theme.Holo.DialogWhenLarge" >

テーマを使ったアクティビティのスタイル指定についての詳細は、スタイルとテーマをご覧ください。

ダイアログを閉じる

AlertDialog.Builder で作成したアクション ボタンのいずれかがタップされると、システムはダイアログを閉じます。

また、リストでラジオボタンやチェックボックスが使われている場合を除き、ダイアログ リストでアイテムがタップされると、ダイアログが閉じます。 それ以外の場合は、DialogFragmentdismiss() を呼び出すとダイアログを手動で閉じることができます。

ダイアログが閉じるときに、特定のアクションを実行する必要がある場合は、DialogFragmentonDismiss() メソッドを実装できます。

ダイアログをキャンセルすることもできます。これは、ユーザーがタスクを完了せずに、明示的にダイアログを離れたことを示す特別なイベントです。 この状況が発生するのは、ユーザーが [戻る] ボタンを押す、ダイアログ領域外の画面をタップする、または開発者が Dialog で明示的に cancel() を呼び出す(ダイアログの [キャンセル] ボタンに応じてなど)場合です。

上記の例のように、DialogFragment クラスで onCancel() を実装するとキャンセル イベントに対応できます。

注: システムによって、onCancel() コールバックを呼び出す各イベントで onDismiss() が呼び出されます。 ただし、Dialog.dismiss()DialogFragment.dismiss() を呼び出す場合、システムによって onDismiss() が呼び出されますが、onCancel() は呼び出されません。 通常は、ユーザーがダイアログのポジティブボタンを押すときに、dismiss() を呼び出して、ビューからダイアログが削除されるようにしてください。

This site uses cookies to store your preferences for site-specific language and display options.

Get the latest Android developer news and tips that will help you find success on Google Play.

* Required Fields

Hooray!

Browse this site in ?

You requested a page in , but your language preference for this site is .

Would you like to change your language preference and browse this site in ? If you want to change your language preference later, use the language menu at the bottom of each page.

This class requires API level or higher

This doc is hidden because your selected API level for the documentation is . You can change the documentation API level with the selector above the left navigation.

For more information about specifying the API level your app requires, read Supporting Different Platform Versions.

Take a short survey?
Help us improve the Android developer experience.
(Sep 2017 survey)