1 /* 2 * Copyright (C) 2020 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.settings.network.telephony; 18 19 import android.app.Dialog; 20 import android.content.DialogInterface; 21 import android.os.Bundle; 22 import android.text.TextUtils; 23 import android.util.Log; 24 import android.view.LayoutInflater; 25 import android.view.View; 26 import android.widget.AdapterView; 27 import android.widget.ArrayAdapter; 28 import android.widget.LinearLayout; 29 import android.widget.ListView; 30 import android.widget.TextView; 31 32 import androidx.appcompat.app.AlertDialog; 33 import androidx.fragment.app.FragmentActivity; 34 35 import com.android.settings.R; 36 37 import java.util.ArrayList; 38 39 /** Fragment to show a confirm dialog. The caller should implement onConfirmListener. */ 40 public class ConfirmDialogFragment extends BaseDialogFragment 41 implements DialogInterface.OnClickListener { 42 private static final String TAG = "ConfirmDialogFragment"; 43 private static final String ARG_TITLE = "title"; 44 private static final String ARG_MSG = "msg"; 45 private static final String ARG_POS_BUTTON_STRING = "pos_button_string"; 46 private static final String ARG_NEG_BUTTON_STRING = "neg_button_string"; 47 private static final String ARG_LIST = "list"; 48 49 /** 50 * Interface defining the method that will be invoked when the user has done with the dialog. 51 */ 52 public interface OnConfirmListener { 53 /** 54 * @param tag The tag in the caller. 55 * @param confirmed True if the user has clicked the positive button. False if the 56 * user has 57 * clicked the negative button or cancel the dialog. 58 * @param itemPosition It is the position of item, if user selects one of the list item. 59 * If the user select "cancel" or the dialog does not have list, then 60 * the value is -1. 61 */ onConfirm(int tag, boolean confirmed, int itemPosition)62 void onConfirm(int tag, boolean confirmed, int itemPosition); 63 } 64 65 /** Displays a confirmation dialog which has confirm and cancel buttons. */ show( FragmentActivity activity, Class<T> callbackInterfaceClass, int tagInCaller, String title, String msg, String posButtonString, String negButtonString)66 public static <T> void show( 67 FragmentActivity activity, 68 Class<T> callbackInterfaceClass, 69 int tagInCaller, 70 String title, 71 String msg, 72 String posButtonString, 73 String negButtonString) { 74 ConfirmDialogFragment fragment = new ConfirmDialogFragment(); 75 Bundle arguments = new Bundle(); 76 arguments.putString(ARG_TITLE, title); 77 arguments.putCharSequence(ARG_MSG, msg); 78 arguments.putString(ARG_POS_BUTTON_STRING, posButtonString); 79 arguments.putString(ARG_NEG_BUTTON_STRING, negButtonString); 80 setListener(activity, null, callbackInterfaceClass, tagInCaller, arguments); 81 fragment.setArguments(arguments); 82 fragment.show(activity.getSupportFragmentManager(), TAG); 83 } 84 85 /** Displays a confirmation dialog which has confirm and cancel buttons and carrier list.*/ show( FragmentActivity activity, Class<T> callbackInterfaceClass, int tagInCaller, String title, String msg, String posButtonString, String negButtonString, ArrayList<String> list)86 public static <T> void show( 87 FragmentActivity activity, 88 Class<T> callbackInterfaceClass, 89 int tagInCaller, 90 String title, 91 String msg, 92 String posButtonString, 93 String negButtonString, 94 ArrayList<String> list) { 95 ConfirmDialogFragment fragment = new ConfirmDialogFragment(); 96 Bundle arguments = new Bundle(); 97 arguments.putString(ARG_TITLE, title); 98 arguments.putCharSequence(ARG_MSG, msg); 99 arguments.putString(ARG_POS_BUTTON_STRING, posButtonString); 100 arguments.putString(ARG_NEG_BUTTON_STRING, negButtonString); 101 arguments.putStringArrayList(ARG_LIST, list); 102 setListener(activity, null, callbackInterfaceClass, tagInCaller, arguments); 103 fragment.setArguments(arguments); 104 fragment.show(activity.getSupportFragmentManager(), TAG); 105 } 106 107 @Override onCreateDialog(Bundle savedInstanceState)108 public final Dialog onCreateDialog(Bundle savedInstanceState) { 109 String title = getArguments().getString(ARG_TITLE); 110 String message = getArguments().getString(ARG_MSG); 111 String posBtnString = getArguments().getString(ARG_POS_BUTTON_STRING); 112 String negBtnString = getArguments().getString(ARG_NEG_BUTTON_STRING); 113 ArrayList<String> list = getArguments().getStringArrayList(ARG_LIST); 114 115 Log.i(TAG, "Showing dialog with title =" + title); 116 AlertDialog.Builder builder = new AlertDialog.Builder(getContext()) 117 .setPositiveButton(posBtnString, this) 118 .setNegativeButton(negBtnString, this); 119 View content = LayoutInflater.from(getContext()).inflate( 120 R.layout.sim_confirm_dialog_multiple_enabled_profiles_supported, null); 121 122 if (list != null && !list.isEmpty() && content != null) { 123 Log.i(TAG, "list =" + list.toString()); 124 125 if (!TextUtils.isEmpty(title)) { 126 View titleView = LayoutInflater.from(getContext()).inflate( 127 R.layout.sim_confirm_dialog_title_multiple_enabled_profiles_supported, 128 null); 129 TextView titleTextView = titleView.findViewById(R.id.title); 130 titleTextView.setText(title); 131 builder.setCustomTitle(titleTextView); 132 } 133 TextView dialogMessage = content.findViewById(R.id.msg); 134 if (!TextUtils.isEmpty(message) && dialogMessage != null) { 135 dialogMessage.setText(message); 136 dialogMessage.setVisibility(View.VISIBLE); 137 } 138 139 final ArrayAdapter<String> arrayAdapterItems = new ArrayAdapter<String>( 140 getContext(), 141 R.layout.sim_confirm_dialog_item_multiple_enabled_profiles_supported, list); 142 final ListView lvItems = content.findViewById(R.id.carrier_list); 143 if (lvItems != null) { 144 lvItems.setVisibility(View.VISIBLE); 145 lvItems.setAdapter(arrayAdapterItems); 146 lvItems.setOnItemClickListener(new AdapterView.OnItemClickListener() { 147 @Override 148 public void onItemClick(AdapterView<?> parent, View view, int position, 149 long id) { 150 Log.i(TAG, "list onClick =" + position); 151 Log.i(TAG, "list item =" + list.get(position)); 152 153 if (position == list.size() - 1) { 154 // user select the "cancel" item; 155 informCaller(false, -1); 156 } else { 157 informCaller(true, position); 158 } 159 } 160 }); 161 } 162 final LinearLayout infoOutline = content.findViewById(R.id.info_outline_layout); 163 if (infoOutline != null) { 164 infoOutline.setVisibility(View.VISIBLE); 165 } 166 builder.setView(content); 167 } else { 168 if (!TextUtils.isEmpty(title)) { 169 builder.setTitle(title); 170 } 171 if (!TextUtils.isEmpty(message)) { 172 builder.setMessage(message); 173 } 174 } 175 176 AlertDialog dialog = builder.create(); 177 dialog.setCanceledOnTouchOutside(false); 178 return dialog; 179 } 180 181 @Override onClick(DialogInterface dialog, int which)182 public void onClick(DialogInterface dialog, int which) { 183 Log.i(TAG, "dialog onClick =" + which); 184 185 informCaller(which == DialogInterface.BUTTON_POSITIVE, -1); 186 } 187 188 @Override onCancel(DialogInterface dialog)189 public void onCancel(DialogInterface dialog) { 190 informCaller(false, -1); 191 } 192 informCaller(boolean confirmed, int itemPosition)193 private void informCaller(boolean confirmed, int itemPosition) { 194 OnConfirmListener listener = getListener(OnConfirmListener.class); 195 if (listener == null) { 196 return; 197 } 198 listener.onConfirm(getTagInCaller(), confirmed, itemPosition); 199 } 200 } 201