1 /* 2 * Copyright (C) 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.car.ui.paintbooth.dialogs; 18 19 import android.Manifest; 20 import android.app.Activity; 21 import android.app.AlertDialog; 22 import android.content.pm.PackageManager; 23 import android.os.Bundle; 24 import android.util.Pair; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.widget.Button; 29 import android.widget.Toast; 30 31 import androidx.annotation.NonNull; 32 import androidx.recyclerview.widget.RecyclerView; 33 34 import com.android.car.ui.AlertDialogBuilder; 35 import com.android.car.ui.FocusArea; 36 import com.android.car.ui.baselayout.Insets; 37 import com.android.car.ui.baselayout.InsetsChangedListener; 38 import com.android.car.ui.core.CarUi; 39 import com.android.car.ui.paintbooth.R; 40 import com.android.car.ui.recyclerview.CarUiContentListItem; 41 import com.android.car.ui.recyclerview.CarUiListItemAdapter; 42 import com.android.car.ui.recyclerview.CarUiRadioButtonListItem; 43 import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter; 44 import com.android.car.ui.recyclerview.CarUiRecyclerView; 45 import com.android.car.ui.toolbar.NavButtonMode; 46 import com.android.car.ui.toolbar.ToolbarController; 47 48 import java.util.ArrayList; 49 import java.util.List; 50 51 /** 52 * Activity that shows different dialogs from the device default theme. 53 */ 54 public class DialogsActivity extends Activity implements InsetsChangedListener { 55 56 private final List<Pair<Integer, View.OnClickListener>> mButtons = new ArrayList<>(); 57 58 @Override onCreate(Bundle savedInstanceState)59 protected void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 setContentView(R.layout.car_ui_recycler_view_activity); 62 ToolbarController toolbar = CarUi.requireToolbar(this); 63 toolbar.setTitle(getTitle()); 64 toolbar.setNavButtonMode(NavButtonMode.BACK); 65 66 mButtons.add(Pair.create(R.string.dialog_show_dialog, 67 v -> showDialog())); 68 mButtons.add(Pair.create(R.string.dialog_show_dialog_icon, 69 v -> showDialogWithIcon())); 70 mButtons.add(Pair.create(R.string.dialog_show_dialog_edit, 71 v -> showDialogWithTextBox())); 72 mButtons.add(Pair.create(R.string.dialog_show_dialog_only_positive, 73 v -> showDialogWithOnlyPositiveButton())); 74 mButtons.add(Pair.create(R.string.dialog_show_dialog_no_button, 75 v -> showDialogWithNoButtonProvided())); 76 mButtons.add(Pair.create(R.string.dialog_show_dialog_checkbox, 77 v -> showDialogWithCheckbox())); 78 mButtons.add(Pair.create(R.string.dialog_show_dialog_no_title, 79 v -> showDialogWithoutTitle())); 80 mButtons.add(Pair.create(R.string.dialog_show_toast, 81 v -> showToast())); 82 mButtons.add(Pair.create(R.string.dialog_show_subtitle, 83 v -> showDialogWithSubtitle())); 84 mButtons.add(Pair.create(R.string.dialog_show_subtitle_and_icon, 85 v -> showDialogWithSubtitleAndIcon())); 86 mButtons.add(Pair.create(R.string.dialog_show_long_subtitle_and_icon, 87 v -> showDialogWithLongSubtitleAndIcon())); 88 mButtons.add(Pair.create(R.string.dialog_show_single_choice, 89 v -> showDialogWithSingleChoiceItems())); 90 mButtons.add(Pair.create(R.string.dialog_show_list_items_without_default_button, 91 v -> showDialogWithListItemsWithoutDefaultButton())); 92 mButtons.add(Pair.create(R.string.dialog_show_unfocusable_list_items, 93 v -> showDialogWithUnfocusableListItems())); 94 mButtons.add(Pair.create(R.string.dialog_show_empty_list_items, 95 v -> showDialogWithEmptyList())); 96 mButtons.add(Pair.create(R.string.dialog_show_permission_dialog, 97 v -> showPermissionDialog())); 98 mButtons.add(Pair.create(R.string.dialog_show_multi_permission_dialog, 99 v -> showMultiPermissionDialog())); 100 mButtons.add(Pair.create(R.string.dialog_show_foreground_permission_dialog, 101 v -> showForegroundPermissionDialog())); 102 mButtons.add(Pair.create(R.string.dialog_show_background_permission_dialog, 103 v -> showBackgroundPermissionDialog())); 104 105 CarUiRecyclerView recyclerView = requireViewById(R.id.list); 106 recyclerView.setAdapter(mAdapter); 107 } 108 showDialog()109 private void showDialog() { 110 new AlertDialogBuilder(this) 111 .setTitle(getString(R.string.standard_alert_dialog)) 112 .setMessage(getString(R.string.my_message)) 113 .setNeutralButton(getString(R.string.neutral), (dialogInterface, which) -> { 114 }) 115 .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> { 116 }) 117 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 118 }) 119 .show(); 120 } 121 showDialogWithIcon()122 private void showDialogWithIcon() { 123 new AlertDialogBuilder(this) 124 .setTitle(getString(R.string.alert_dialog_with_icon)) 125 .setMessage(getString(R.string.my_message)) 126 .setIcon(R.drawable.ic_tracklist) 127 .show(); 128 } 129 showDialogWithNoButtonProvided()130 private void showDialogWithNoButtonProvided() { 131 new AlertDialogBuilder(this) 132 .setTitle(getString(R.string.standard_alert_dialog)) 133 .show(); 134 } 135 showDialogWithCheckbox()136 private void showDialogWithCheckbox() { 137 new AlertDialogBuilder(this) 138 .setTitle(R.string.custom_dialog_box) 139 .setMultiChoiceItems( 140 new CharSequence[]{"I am a checkbox"}, 141 new boolean[]{false}, 142 (dialog, which, isChecked) -> { 143 }) 144 .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> { 145 }) 146 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 147 }) 148 .show(); 149 } 150 showDialogWithTextBox()151 private void showDialogWithTextBox() { 152 new AlertDialogBuilder(this) 153 .setTitle(R.string.standard_alert_dialog) 154 .setEditBox(getString(R.string.edit_me_please), null, null) 155 .setAutoDescUpdateForWidescreen(true) 156 .setEditTextTitleAndDescForWideScreen("title", "desc from app") 157 .setPositiveButton("OK", (dialogInterface, i) -> { 158 }) 159 .show(); 160 } 161 showDialogWithOnlyPositiveButton()162 private void showDialogWithOnlyPositiveButton() { 163 new AlertDialogBuilder(this) 164 .setTitle(R.string.standard_alert_dialog) 165 .setMessage(getString(R.string.my_message)) 166 .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> { 167 }) 168 .show(); 169 } 170 showDialogWithoutTitle()171 private void showDialogWithoutTitle() { 172 new AlertDialogBuilder(this) 173 .setMessage(R.string.no_title_message) 174 .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> { 175 }) 176 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 177 }) 178 .show(); 179 } 180 showToast()181 private void showToast() { 182 Toast.makeText(this, "Toast message looks like this", Toast.LENGTH_LONG).show(); 183 } 184 showDialogWithSubtitle()185 private void showDialogWithSubtitle() { 186 new AlertDialogBuilder(this) 187 .setTitle(R.string.my_title) 188 .setSubtitle(R.string.my_subtitle) 189 .setMessage(getString(R.string.my_message)) 190 .show(); 191 } 192 showDialogWithSingleChoiceItems()193 private void showDialogWithSingleChoiceItems() { 194 ArrayList<CarUiRadioButtonListItem> data = new ArrayList<>(); 195 196 CarUiRadioButtonListItem item = new CarUiRadioButtonListItem(); 197 item.setTitle(getString(R.string.first_item)); 198 data.add(item); 199 200 item = new CarUiRadioButtonListItem(); 201 item.setTitle(getString(R.string.second_item)); 202 data.add(item); 203 204 item = new CarUiRadioButtonListItem(); 205 item.setTitle(getString(R.string.third_item)); 206 data.add(item); 207 208 new AlertDialogBuilder(this) 209 .setTitle(R.string.select_one_option) 210 .setSubtitle(R.string.select_one_option_at_a_time) 211 .setSingleChoiceItems(new CarUiRadioButtonListItemAdapter(data), null) 212 .show(); 213 } 214 showDialogWithListItemsWithoutDefaultButton()215 private void showDialogWithListItemsWithoutDefaultButton() { 216 ArrayList<CarUiContentListItem> data = new ArrayList<>(); 217 AlertDialog[] dialog = new AlertDialog[1]; 218 219 CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 220 item.setTitle("First item"); 221 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 222 data.add(item); 223 224 225 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 226 item.setTitle("Second item"); 227 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 228 data.add(item); 229 230 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 231 item.setTitle("Third item"); 232 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 233 data.add(item); 234 235 dialog[0] = new AlertDialogBuilder(this) 236 .setTitle("Select one option.") 237 .setSubtitle("Ony one option may be selected at a time") 238 .setAdapter(new CarUiListItemAdapter(data)) 239 .setAllowDismissButton(false) 240 .show(); 241 } 242 showDialogWithUnfocusableListItems()243 private void showDialogWithUnfocusableListItems() { 244 List<CarUiContentListItem> data = new ArrayList<>(); 245 246 CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 247 item.setTitle("First item"); 248 data.add(item); 249 250 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 251 item.setTitle("Second item"); 252 data.add(item); 253 254 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 255 item.setTitle("Third item"); 256 data.add(item); 257 258 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 259 item.setTitle("Fourth item"); 260 data.add(item); 261 262 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 263 item.setTitle("Fifth item"); 264 data.add(item); 265 266 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 267 item.setTitle("Sixth item"); 268 data.add(item); 269 270 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 271 item.setTitle("Seventh item"); 272 data.add(item); 273 274 new AlertDialogBuilder(this) 275 .setTitle("Unfocusable items") 276 .setAdapter(new CarUiListItemAdapter(data)) 277 .show(); 278 } 279 showDialogWithEmptyList()280 private void showDialogWithEmptyList() { 281 new AlertDialogBuilder(this) 282 .setTitle("Empty list") 283 .setAdapter(new CarUiListItemAdapter(new ArrayList<CarUiContentListItem>())) 284 .show(); 285 } 286 showDialogWithSubtitleAndIcon()287 private void showDialogWithSubtitleAndIcon() { 288 new AlertDialogBuilder(this) 289 .setTitle(R.string.my_title) 290 .setSubtitle(R.string.my_subtitle) 291 .setMessage(getString(R.string.my_message)) 292 .setIcon(R.drawable.ic_tracklist) 293 .show(); 294 } 295 showDialogWithLongSubtitleAndIcon()296 private void showDialogWithLongSubtitleAndIcon() { 297 new AlertDialogBuilder(this) 298 .setTitle(getString(R.string.long_title)) 299 .setSubtitle(R.string.long_subtitle) 300 .setMessage(getString(R.string.my_message)) 301 .setIcon(R.drawable.ic_tracklist) 302 .show(); 303 } 304 showPermissionDialog()305 private void showPermissionDialog() { 306 if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 307 Toast.makeText(this, "Permission already granted. Remove CAMERA permission from " 308 + "Settings > All apps > PaintBooth", Toast.LENGTH_SHORT).show(); 309 return; 310 } 311 requestPermissions(new String[]{Manifest.permission.CAMERA}, 1); 312 } 313 showMultiPermissionDialog()314 private void showMultiPermissionDialog() { 315 if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED 316 && checkSelfPermission(Manifest.permission.SEND_SMS) 317 == PackageManager.PERMISSION_GRANTED 318 && checkSelfPermission(Manifest.permission.READ_CONTACTS) 319 == PackageManager.PERMISSION_GRANTED) { 320 Toast.makeText(this, "Permissions are already granted. Remove CAMERA, SEND_SMS or " 321 + "READ_CONTACTS permission from Settings > All apps > PaintBooth", 322 Toast.LENGTH_SHORT).show(); 323 return; 324 } 325 requestPermissions(new String[]{Manifest.permission.CAMERA, 326 Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS}, 1); 327 } 328 showForegroundPermissionDialog()329 private void showForegroundPermissionDialog() { 330 requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); 331 } 332 showBackgroundPermissionDialog()333 private void showBackgroundPermissionDialog() { 334 requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1); 335 } 336 337 @Override onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)338 public void onRequestPermissionsResult(int requestCode, String[] permissions, 339 int[] grantResults) { 340 StringBuilder sb = new StringBuilder(); 341 sb.append("Permission "); 342 for (int i = 0; i < permissions.length; i++) { 343 sb.append(permissions[i]); 344 sb.append("="); 345 sb.append(grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"); 346 sb.append("\n"); 347 } 348 Toast.makeText(this, sb.toString(), Toast.LENGTH_SHORT).show(); 349 } 350 351 private static class ViewHolder extends RecyclerView.ViewHolder { 352 353 private final Button mButton; 354 ViewHolder(View itemView)355 ViewHolder(View itemView) { 356 super(itemView); 357 mButton = itemView.requireViewById(R.id.button); 358 } 359 bind(Integer title, View.OnClickListener listener)360 public void bind(Integer title, View.OnClickListener listener) { 361 mButton.setText(title); 362 mButton.setOnClickListener(listener); 363 } 364 } 365 366 private final RecyclerView.Adapter<ViewHolder> mAdapter = 367 new RecyclerView.Adapter<ViewHolder>() { 368 @Override 369 public int getItemCount() { 370 return mButtons.size(); 371 } 372 373 @Override 374 public ViewHolder onCreateViewHolder(ViewGroup parent, int position) { 375 View item = 376 LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, 377 parent, false); 378 return new ViewHolder(item); 379 } 380 381 @Override 382 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 383 Pair<Integer, View.OnClickListener> pair = mButtons.get(position); 384 holder.bind(pair.first, pair.second); 385 } 386 }; 387 388 @Override onCarUiInsetsChanged(@onNull Insets insets)389 public void onCarUiInsetsChanged(@NonNull Insets insets) { 390 FocusArea focusArea = requireViewById(R.id.focus_area); 391 focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom()); 392 focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom()); 393 requireViewById(R.id.list) 394 .setPadding(0, insets.getTop(), 0, insets.getBottom()); 395 requireViewById(android.R.id.content) 396 .setPadding(insets.getLeft(), 0, insets.getRight(), 0); 397 } 398 } 399