/* * Copyright (C) 2015-present, Ant Financial Services Group * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alipay.hulu.util; import android.app.Activity; import android.app.Dialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.database.DataSetObserver; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.support.annotation.NonNull; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.util.DisplayMetrics; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.EditText; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListAdapter; import android.widget.ListView; import android.widget.ScrollView; import android.widget.TextView; import com.alipay.hulu.R; import com.alipay.hulu.activity.SettingsActivity; import com.alipay.hulu.common.application.LauncherApplication; import com.alipay.hulu.common.utils.ContextUtil; import com.alipay.hulu.common.utils.GlideApp; import com.alipay.hulu.common.utils.LogUtil; import com.alipay.hulu.common.utils.StringUtil; import com.alipay.hulu.shared.node.action.PerformActionEnum; import com.alipay.hulu.ui.TwoLevelSelectLayout; import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestBuilder; import com.bumptech.glide.RequestManager; import com.bumptech.glide.request.RequestOptions; import java.io.File; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.concurrent.CountDownLatch; /** * Created by ruyao.yry on 2018/3/24. */ public class DialogUtils { private static final String TAG = "DialogUtil"; public static class DialogInfo { private int mResourceId; private String mNegativeButtonText; private String mPositiveButtonText; private String mShowContent; private String mTitle; private boolean mCancelable; private DialogInfo(Builder builder) { mResourceId = builder.mResourceId; mNegativeButtonText = builder.mNegativeButtonText; mPositiveButtonText = builder.mPositiveButtonText; mShowContent = builder.mShowContent; mTitle = builder.mTitle; mCancelable = builder.mCancelable; } public int getResourceId() { return mResourceId; } public String getNegativeButtonText() { return mNegativeButtonText; } public String getPositiveButtonText() { return mPositiveButtonText; } public String getShowContent() { return mShowContent; } public String getTitle() { return mTitle; } public boolean isCancelable() { return mCancelable; } public static class Builder { private String mNegativeButtonText; private String mPositiveButtonText; private String mShowContent; private String mTitle; private boolean mCancelable; private int mResourceId; public Builder setResourceId(int id) { mResourceId = id; return this; } public Builder setNegativeButtonText(String text) { mNegativeButtonText = text; return this; } public Builder setPositiveButtonText(String text) { mPositiveButtonText = text; return this; } public Builder setShowContent(String text) { mShowContent = text; return this; } public Builder setTitle(String text) { mTitle = text; return this; } public Builder setCancelable(boolean cancelable) { mCancelable = cancelable; return this; } public DialogInfo build() { return new DialogInfo(this); } } } public static AlertDialog createDialog(@NonNull Activity activity, @NonNull DialogInfo dialogInfo, @NonNull DialogInterface.OnClickListener onClickListener) { AlertDialog.Builder alertDialogBuilder = dialogInfo.getResourceId() == 0? new AlertDialog.Builder(activity) : new AlertDialog.Builder(activity, dialogInfo.getResourceId()); if (!TextUtils.isEmpty(dialogInfo.getNegativeButtonText())) { alertDialogBuilder.setNegativeButton(dialogInfo.getNegativeButtonText(), onClickListener); } if (!TextUtils.isEmpty(dialogInfo.getPositiveButtonText())) { alertDialogBuilder.setPositiveButton(dialogInfo.getPositiveButtonText(), onClickListener); } if (!TextUtils.isEmpty(dialogInfo.getTitle())) { alertDialogBuilder.setTitle(dialogInfo.getTitle()); } if (!TextUtils.isEmpty(dialogInfo.getShowContent())) { alertDialogBuilder.setMessage(dialogInfo.getShowContent()); } alertDialogBuilder.setCancelable(dialogInfo.isCancelable()); return alertDialogBuilder.create(); } /** * 显示加载悬浮窗 * * @param context * @param str * @return */ public static ProgressDialog showProgressDialog(final Context context, final String str) { if (context == null) { return null; } final ProgressDialog[] dialogs = new ProgressDialog[1]; final CountDownLatch latch = new CountDownLatch(1); LauncherApplication.getInstance().runOnUiThread(new Runnable() { public void run() { ProgressDialog progressDialog = new ProgressDialog(context, R.style.SimpleDialogTheme); progressDialog.setMessage(str); progressDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); progressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER); progressDialog.show(); dialogs[0] = progressDialog; latch.countDown(); } }); try { latch.await(); } catch (InterruptedException e) { LogUtil.e(TAG, "Catch java.lang.InterruptedException: " + e.getMessage(), e); } return dialogs[0]; } /** * 展示单选界面 * @param context * @param names 名称列表 * @param icons 图标列表 * @param callback 选择回调 */ public static void showSingleItemCheckDialog(final Context context,final String[] names , final int[] icons, final ItemCheckCallback callback) { if (callback == null) { return; } // 图标与名称不对应 if (icons != null && icons.length != names.length) { return; } try { ListAdapter listAdapter = new ListAdapter() { @Override public boolean areAllItemsEnabled() { return true; } @Override public boolean isEnabled(int position) { return true; } @Override public void registerDataSetObserver(DataSetObserver observer) { } @Override public void unregisterDataSetObserver(DataSetObserver observer) { } @Override public int getCount() { return names.length; } @Override public Object getItem(int position) { return names[position]; } @Override public long getItemId(int position) { return position; } @Override public boolean hasStableIds() { return true; } @Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { convertView = LayoutInflater.from( ContextUtil.getContextThemeWrapper(context, R.style.AppDialogTheme)).inflate( R.layout.dialog_action_select_item, parent, false); } // 加载资源 TextView text = (TextView) convertView.findViewById(R.id.dialog_action_title); text.setText(names[position]); // 如果有图标信息 if (icons != null) { ImageView img = (ImageView) convertView.findViewById(R.id.dialog_action_icon); img.setImageResource(icons[position]); } return convertView; } @Override public int getItemViewType(int position) { return 0; } @Override public int getViewTypeCount() { return 1; } @Override public boolean isEmpty() { return false; } }; final ListView listView = new ListView(context); listView.setAdapter(listAdapter); listView.setDividerHeight(0); final AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AppDialogTheme) .setTitle(R.string.function__select_function) .setView(listView) .setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { callback.onCancel(dialog); } }); LauncherApplication.getInstance().runOnUiThread(new Runnable() { @Override public void run() { final AlertDialog dialog = builder.create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.setCanceledOnTouchOutside(true); //点击外面区域不会让dialog消失 dialog.setCancelable(true); listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { dialog.dismiss(); callback.onExecute(dialog, position); } }); dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { callback.onDismiss(dialog); } }); dialog.show(); //dialog 尺寸配置 dialog.getWindow().setLayout(ContextUtil.dip2px(context, 225), WindowManager.LayoutParams.WRAP_CONTENT); } }); } catch (Exception e) { LogUtil.e(TAG, "显示悬浮窗抛出异常", e); } } /** * 展示功能界面 * @param context * @param actionEnums * @param callback */ public static void showFunctionView(final Context context,final List<PerformActionEnum> actionEnums , final FunctionViewCallback<PerformActionEnum> callback) { if (callback == null) { return; } // 转换一层 ItemCheckCallback innerCallback = new ItemCheckCallback() { @Override public void onExecute(DialogInterface dialog, int idx) { callback.onExecute(dialog, actionEnums.get(idx)); } @Override public void onCancel(DialogInterface dialog) { callback.onCancel(dialog); } @Override public void onDismiss(DialogInterface dialog) { callback.onDismiss(dialog); } }; String[] names = new String[actionEnums.size()]; int[] icons = new int[actionEnums.size()]; for (int i = 0; i < actionEnums.size(); i++) { PerformActionEnum action = actionEnums.get(i); names[i] = action.getDesc(); icons[i] = action.getIcon(); } // 实际显示 showSingleItemCheckDialog(context, names, icons, innerCallback); } /** * 显示自定义页面 * @param context * @param content * @param confirm * @param onConfirm * @param cancel * @param onCancel */ public static void showCustomView(final Context context, View content, String confirm, final Runnable onConfirm, String cancel, final Runnable onCancel) { ScrollView view = (ScrollView) LayoutInflater.from(ContextUtil.getContextThemeWrapper( context, R.style.AppDialogTheme)) .inflate(R.layout.dialog_setting, null); LinearLayout wrapper = (LinearLayout) view.findViewById(R.id.dialog_content); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); wrapper.addView(content, layoutParams); // 显示Dialog android.app.AlertDialog.Builder dialogB = new android.app.AlertDialog.Builder(context, R.style.AppDialogTheme) .setView(view) .setCancelable(false); if (confirm != null) { // 设置取消 dialogB.setPositiveButton(confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (onConfirm != null) { onConfirm.run(); } } }); } if (cancel != null) { dialogB.setNegativeButton(cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { if (onCancel != null) { onCancel.run(); } } }); } android.app.AlertDialog dialog = dialogB.create(); dialog.setTitle(null); dialog.setCanceledOnTouchOutside(false); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.show(); } /** * 展示分层菜单项 * @param context * @param keys * @param icons * @param secondLevels * @param callback */ public static void showLeveledFunctionView(final Context context, final List<Integer> keys, final List<Integer> icons, final Map<Integer, List<TwoLevelSelectLayout.SubMenuItem>> secondLevels, final FunctionViewCallback<TwoLevelSelectLayout.SubMenuItem> callback) { if (callback == null) { LogUtil.e(TAG,"回调函数为空"); return; } // 校验各个参数 if (icons == null || keys == null || secondLevels == null) { LogUtil.e(TAG,"参数存在空情况"); return; } // 校验长度 if (icons.size() != keys.size()) { LogUtil.e(TAG,"图标与key不对应"); return; } // 校验各个key都有对应子菜单 for (Integer key: keys) { if (!secondLevels.containsKey(key)) { LogUtil.e(TAG, "菜单%s不包含对应子菜单", key); return; } } LauncherApplication.getInstance().runOnUiThread(new Runnable() { @Override public void run() { final TwoLevelSelectLayout layout = new TwoLevelSelectLayout(ContextUtil.getContextThemeWrapper(context, R.style.AppTheme)); layout.updateMenus(keys, icons, secondLevels); AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.AppDialogTheme) .setView(layout); final AlertDialog dialog = builder.create(); dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); dialog.setCanceledOnTouchOutside(true); //点击外面区域不会让dialog消失 dialog.setCancelable(true); dialog.setCustomTitle(null); dialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { callback.onDismiss(dialog); } }); dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { @Override public void onCancel(DialogInterface dialog) { callback.onCancel(dialog); } }); dialog.show(); layout.setOnSubMenuItemClickListener(new TwoLevelSelectLayout.OnSubMenuClickListener() { @Override public void onSubMenuClick(TwoLevelSelectLayout.SubMenuItem item) { callback.onExecute(dialog, item); } }); WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); DisplayMetrics metrics = new DisplayMetrics(); wm.getDefaultDisplay().getMetrics(metrics); // 高度400dp, 宽度260dpa int pix = ContextUtil.dip2px(context, 400); int width = ContextUtil.dip2px(context, 270); if (metrics.heightPixels < pix) { if (metrics.widthPixels < width) { dialog.getWindow().setLayout(WindowManager.LayoutParams.WRAP_CONTENT, WindowManager.LayoutParams.WRAP_CONTENT); } else { dialog.getWindow().setLayout(width, WindowManager.LayoutParams.WRAP_CONTENT); } } else { if (metrics.widthPixels < width) { dialog.getWindow().setLayout(WindowManager.LayoutParams.WRAP_CONTENT, pix); } else { dialog.getWindow().setLayout(width, pix); } } } }); } public interface OnDialogResultListener { void onDialogPositive(List<String> data); } /** * 为多个字段配置输入框 * * @param title * @param data */ public static void showMultipleEditDialog(Context context, final OnDialogResultListener listener, String title, List<Pair<String, String>> data) { LayoutInflater inflater = LayoutInflater.from(ContextUtil.getContextThemeWrapper( context, R.style.AppDialogTheme)); ScrollView v = (ScrollView) inflater.inflate(R.layout.dialog_setting, null); LinearLayout view = (LinearLayout) v.getChildAt(0); final List<EditText> editTexts = new ArrayList<>(); LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); // 对每一个字段添加EditText for (Pair<String, String> source : data) { View editField = inflater.inflate(R.layout.item_edit_field, null); EditText edit = (EditText) editField.findViewById(R.id.item_edit_field_edit); TextView name = (TextView) editField.findViewById(R.id.item_edit_field_name); if (StringUtil.isEmpty(source.first)) { name.setVisibility(View.GONE); } else { // 配置字段 name.setText(source.first); } edit.setHint(source.first); edit.setText(source.second); view.addView(editField, layoutParams); editTexts.add(edit); } // 显示Dialog new AlertDialog.Builder(context, R.style.AppDialogTheme) .setTitle(title) .setView(v) .setPositiveButton(R.string.constant__confirm, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { List<String> result = new ArrayList<>(editTexts.size() + 1); // 获取每个编辑框的文字 for (EditText data : editTexts) { result.add(data.getText().toString().trim()); } if (listener != null) { listener.onDialogPositive(result); } dialog.dismiss(); } }).setNegativeButton(R.string.constant__cancel, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).setCancelable(true) .show(); } /** * 显示图像Dialog * @param context * @param targetFile */ public static void showImageDialog(Context context, File targetFile) { ImageDialog dialog = new ImageDialog(context, targetFile); dialog.show(); } /** * 显示图像Dialog * @param context * @param id resId */ public static void showImageDialog(Context context, int id) { ImageDialog dialog = new ImageDialog(context, id); dialog.show(); } /** * 显示图像Dialog * @param context * @param path 路径 */ public static void showImageDialog(Context context, String path) { ImageDialog dialog = new ImageDialog(context, path); dialog.show(); } /** * 显示图像Dialog * @param context * @param content uri */ public static void showImageDialog(Context context, Uri content) { ImageDialog dialog = new ImageDialog(context, content); dialog.show(); } /** * 显示图像Dialog * @param context * @param bitmap */ public static void showImageDialog(Context context, Bitmap bitmap) { ImageDialog dialog = new ImageDialog(context, bitmap); dialog.show(); } /** * 显示图像Dialog * @param context * @param data */ public static void showImageDialog(Context context, byte[] data) { ImageDialog dialog = new ImageDialog(context, data); dialog.show(); } private static class ImageDialog extends Dialog { private ImageView img; private File file; private Integer id; private String path; private Uri uri; private Bitmap bitmap; private byte[] data; public ImageDialog(@NonNull Context context, File targetFile) { super(context, R.style.ShadowDialogTheme); file = targetFile; } public ImageDialog(@NonNull Context context, int resId) { super(context, R.style.ShadowDialogTheme); id = resId; } public ImageDialog(@NonNull Context context, Bitmap bitmap) { super(context, R.style.ShadowDialogTheme); this.bitmap = bitmap; } public ImageDialog(@NonNull Context context, String path) { super(context, R.style.ShadowDialogTheme); this.path = path; } public ImageDialog(@NonNull Context context, Uri uri) { super(context, R.style.ShadowDialogTheme); this.uri = uri; } public ImageDialog(@NonNull Context context, byte[] data) { super(context, R.style.ShadowDialogTheme); this.data = data; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setCanceledOnTouchOutside(false); initView(); initData(); } private void initView() { LinearLayout linearLayout = new LinearLayout(getContext()); img = new ImageView(getContext()); DisplayMetrics dm = new DisplayMetrics(); ((WindowManager) LauncherApplication.getInstance().getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getMetrics(dm); int height = (int) (dm.heightPixels * 0.8); img.setScaleType(ImageView.ScaleType.CENTER_INSIDE); linearLayout.addView(img, new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height)); setContentView(linearLayout, new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, height)); } /** * 初始化监听器 */ private void initData() { img.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ImageDialog.this.dismiss(); } }); // 对于resourceId类型,暂时只能走直接设置 if (id != null) { img.setImageResource(id); return; } RequestManager manager = GlideApp.with(img.getContext()); RequestBuilder<?> request; if (file != null) { request = manager.load(file); } else if (path != null) { request = manager.load(path); } else if (uri != null) { request = manager.load(uri); } else if (bitmap != null){ request = manager.load(bitmap); } else if (data != null){ request = manager.load(data); } else { return; } request.apply(RequestOptions.fitCenterTransform()).into(img); } } public interface FunctionViewCallback<T> { void onExecute(DialogInterface dialog, T action); void onCancel(DialogInterface dialog); void onDismiss(DialogInterface dialog); } public interface ItemCheckCallback { void onExecute(DialogInterface dialog, int idx); void onCancel(DialogInterface dialog); void onDismiss(DialogInterface dialog); } }