2018-07-25 01:59:25 +02:00
|
|
|
/*#######################################################
|
|
|
|
*
|
|
|
|
* Maintained by Gregor Santner, 2017-
|
|
|
|
* https://gsantner.net/
|
|
|
|
*
|
|
|
|
* License: Apache 2.0
|
|
|
|
* https://github.com/gsantner/opoc/#licensing
|
|
|
|
* https://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
#########################################################*/
|
|
|
|
package net.gsantner.opoc.ui;
|
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.annotation.SuppressLint;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.app.Activity;
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.app.Dialog;
|
2020-12-09 00:57:31 +01:00
|
|
|
import android.content.Context;
|
2019-11-20 00:34:10 +01:00
|
|
|
import android.content.res.ColorStateList;
|
|
|
|
import android.graphics.Color;
|
2018-10-01 21:12:17 +02:00
|
|
|
import android.graphics.Typeface;
|
2019-11-20 00:34:10 +01:00
|
|
|
import android.os.Build;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.support.annotation.ColorInt;
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.support.annotation.DrawableRes;
|
2020-12-09 00:57:31 +01:00
|
|
|
import android.support.annotation.LayoutRes;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.support.annotation.NonNull;
|
|
|
|
import android.support.annotation.Nullable;
|
|
|
|
import android.support.annotation.StringRes;
|
|
|
|
import android.support.v7.app.AlertDialog;
|
|
|
|
import android.support.v7.widget.AppCompatEditText;
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.support.v7.widget.TooltipCompat;
|
2021-01-12 20:23:10 +01:00
|
|
|
import android.text.InputType;
|
2020-12-09 00:57:31 +01:00
|
|
|
import android.text.Spannable;
|
|
|
|
import android.text.SpannableString;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.text.TextUtils;
|
2019-11-20 00:34:10 +01:00
|
|
|
import android.view.Gravity;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.view.KeyEvent;
|
2020-12-09 00:57:31 +01:00
|
|
|
import android.view.LayoutInflater;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.view.View;
|
|
|
|
import android.view.ViewGroup;
|
2019-07-26 03:19:28 +02:00
|
|
|
import android.view.Window;
|
2018-10-01 21:12:17 +02:00
|
|
|
import android.view.WindowManager;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.widget.ArrayAdapter;
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.widget.Button;
|
|
|
|
import android.widget.Checkable;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.widget.Filter;
|
2021-08-01 13:30:21 +02:00
|
|
|
import android.widget.ImageView;
|
2018-07-25 01:59:25 +02:00
|
|
|
import android.widget.LinearLayout;
|
|
|
|
import android.widget.ListView;
|
|
|
|
import android.widget.TextView;
|
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
import net.gsantner.opoc.android.dummy.TextWatcherDummy;
|
2018-07-25 01:59:25 +02:00
|
|
|
import net.gsantner.opoc.util.Callback;
|
|
|
|
import net.gsantner.opoc.util.ContextUtils;
|
|
|
|
|
|
|
|
import java.util.ArrayList;
|
2021-08-01 13:30:21 +02:00
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.HashSet;
|
2018-07-25 01:59:25 +02:00
|
|
|
import java.util.List;
|
|
|
|
import java.util.Locale;
|
2021-08-01 13:30:21 +02:00
|
|
|
import java.util.Set;
|
2019-07-26 03:19:28 +02:00
|
|
|
import java.util.regex.Pattern;
|
2018-07-25 01:59:25 +02:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
@SuppressLint("SetTextI18n")
|
2018-07-25 01:59:25 +02:00
|
|
|
public class SearchOrCustomTextDialog {
|
|
|
|
|
|
|
|
public static class DialogOptions {
|
2021-08-01 13:30:21 +02:00
|
|
|
|
|
|
|
// Callback for search text or text of single item
|
|
|
|
@Nullable
|
|
|
|
public Callback.a1<String> callback = null;
|
|
|
|
|
|
|
|
// Callback for indices of selected items.
|
|
|
|
// List will contain single item if isMultiSelectEnabled == false;
|
|
|
|
@Nullable
|
|
|
|
public Callback.a1<List<Integer>> positionCallback = null;
|
|
|
|
|
|
|
|
public boolean isMultiSelectEnabled = false;
|
|
|
|
public List<? extends CharSequence> data = null;
|
|
|
|
public List<? extends CharSequence> highlightData = null;
|
2020-12-09 00:57:31 +01:00
|
|
|
public List<Integer> iconsForData;
|
2018-07-25 01:59:25 +02:00
|
|
|
public String messageText = "";
|
2020-12-09 00:57:31 +01:00
|
|
|
public String defaultText = "";
|
2018-07-25 01:59:25 +02:00
|
|
|
public boolean isSearchEnabled = true;
|
|
|
|
public boolean isDarkDialog = false;
|
2019-11-20 00:34:10 +01:00
|
|
|
public int dialogWidthDp = WindowManager.LayoutParams.MATCH_PARENT;
|
|
|
|
public int dialogHeightDp = WindowManager.LayoutParams.WRAP_CONTENT;
|
|
|
|
public int gravity = Gravity.NO_GRAVITY;
|
2021-01-12 20:23:10 +01:00
|
|
|
public int searchInputType = InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS;
|
2020-12-09 00:57:31 +01:00
|
|
|
public boolean searchIsRegex = false;
|
2021-08-01 13:30:21 +02:00
|
|
|
public Callback.a1<Spannable> highlighter = null;
|
2020-12-09 00:57:31 +01:00
|
|
|
public String extraFilter = null;
|
2021-08-01 13:30:21 +02:00
|
|
|
public List<Integer> preSelected = null;
|
2020-12-09 00:57:31 +01:00
|
|
|
|
|
|
|
public Callback.a0 neutralButtonCallback = null;
|
2018-07-25 01:59:25 +02:00
|
|
|
|
|
|
|
@ColorInt
|
|
|
|
public int textColor = 0xFF000000;
|
|
|
|
@ColorInt
|
|
|
|
public int highlightColor = 0xFF00FF00;
|
|
|
|
@StringRes
|
|
|
|
public int cancelButtonText = android.R.string.cancel;
|
|
|
|
@StringRes
|
2020-12-09 00:57:31 +01:00
|
|
|
public int neutralButtonText = 0;
|
|
|
|
@StringRes
|
2018-07-25 01:59:25 +02:00
|
|
|
public int okButtonText = android.R.string.ok;
|
|
|
|
@StringRes
|
2020-12-09 00:57:31 +01:00
|
|
|
public int titleText = 0;
|
2018-07-25 01:59:25 +02:00
|
|
|
@StringRes
|
|
|
|
public int searchHintText = android.R.string.search_go;
|
2021-08-01 13:30:21 +02:00
|
|
|
@DrawableRes
|
|
|
|
public int clearInputIcon = android.R.drawable.ic_input_delete;
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
private static class Adapter extends ArrayAdapter<Integer> {
|
2021-01-12 20:23:10 +01:00
|
|
|
@LayoutRes
|
2021-08-01 13:30:21 +02:00
|
|
|
private final int _layout;
|
|
|
|
private final int _layoutHeight;
|
|
|
|
private final LayoutInflater _inflater;
|
|
|
|
private final DialogOptions _dopt;
|
|
|
|
private final List<Integer> _filteredItems;
|
|
|
|
private final Set<Integer> _selectedItems;
|
|
|
|
private final Pattern _extraPattern;
|
|
|
|
|
|
|
|
public static Adapter create(final Context context, final DialogOptions dopt) {
|
|
|
|
return new Adapter(context, dopt, dopt.isMultiSelectEnabled ? android.R.layout.simple_list_item_multiple_choice : android.R.layout.simple_list_item_1, new ArrayList<>());
|
|
|
|
}
|
|
|
|
|
|
|
|
private Adapter(final Context context, final DialogOptions dopt, final int layout, final List<Integer> filteredItems) {
|
|
|
|
super(context, layout, filteredItems);
|
|
|
|
_layout = layout;
|
|
|
|
_filteredItems = filteredItems;
|
|
|
|
_inflater = LayoutInflater.from(context);
|
|
|
|
_dopt = dopt;
|
|
|
|
_extraPattern = (_dopt.extraFilter == null ? null : Pattern.compile(_dopt.extraFilter));
|
|
|
|
_selectedItems = new HashSet<>(_dopt.preSelected != null ? _dopt.preSelected : Collections.emptyList());
|
|
|
|
ContextUtils cu = new ContextUtils(context);
|
|
|
|
_layoutHeight = (int) cu.convertDpToPx(36);
|
|
|
|
cu.freeContextRef();
|
2020-12-09 00:57:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@NonNull
|
|
|
|
@Override
|
|
|
|
public View getView(int pos, @Nullable View convertView, @NonNull ViewGroup parent) {
|
2021-08-01 13:30:21 +02:00
|
|
|
final int index = getItem(pos);
|
2020-12-09 00:57:31 +01:00
|
|
|
|
|
|
|
final TextView textView;
|
|
|
|
if (convertView == null) {
|
2021-01-12 20:23:10 +01:00
|
|
|
textView = (TextView) _inflater.inflate(_layout, parent, false);
|
2021-08-01 13:30:21 +02:00
|
|
|
textView.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
|
|
|
|
textView.setMinHeight(_layoutHeight);
|
2020-12-09 00:57:31 +01:00
|
|
|
} else {
|
|
|
|
textView = (TextView) convertView;
|
|
|
|
}
|
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
if (textView instanceof Checkable) {
|
|
|
|
((Checkable) textView).setChecked(_selectedItems.contains(index));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index >= 0 && _dopt.iconsForData != null && index < _dopt.iconsForData.size() && _dopt.iconsForData.get(index) != 0) {
|
|
|
|
textView.setCompoundDrawablesWithIntrinsicBounds(_dopt.iconsForData.get(index), 0, 0, 0);
|
2020-12-09 00:57:31 +01:00
|
|
|
textView.setCompoundDrawablePadding(32);
|
|
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
2021-01-12 20:23:10 +01:00
|
|
|
textView.setCompoundDrawableTintList(ColorStateList.valueOf(_dopt.isDarkDialog ? Color.WHITE : Color.BLACK));
|
2019-11-20 00:34:10 +01:00
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
} else {
|
|
|
|
textView.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
|
|
|
|
}
|
2019-11-20 00:34:10 +01:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
final CharSequence text = _dopt.data.get(index).toString();
|
2021-01-12 20:23:10 +01:00
|
|
|
if (_dopt.highlightData != null) {
|
|
|
|
final boolean hl = _dopt.highlightData.contains(text);
|
|
|
|
textView.setTextColor(hl ? _dopt.highlightColor : _dopt.textColor);
|
2018-10-01 21:12:17 +02:00
|
|
|
textView.setTypeface(null, hl ? Typeface.BOLD : Typeface.NORMAL);
|
2020-12-09 00:57:31 +01:00
|
|
|
}
|
2018-10-01 21:12:17 +02:00
|
|
|
|
2021-01-12 20:23:10 +01:00
|
|
|
if (_dopt.highlighter != null) {
|
2020-12-09 00:57:31 +01:00
|
|
|
Spannable s = new SpannableString(text);
|
2021-01-12 20:23:10 +01:00
|
|
|
_dopt.highlighter.callback(s);
|
2020-12-09 00:57:31 +01:00
|
|
|
textView.setText(s);
|
|
|
|
} else {
|
|
|
|
textView.setText(text);
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
|
|
|
|
2020-12-09 00:57:31 +01:00
|
|
|
return textView;
|
|
|
|
}
|
2018-07-25 01:59:25 +02:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
@NonNull
|
2020-12-09 00:57:31 +01:00
|
|
|
@Override
|
|
|
|
public Filter getFilter() {
|
|
|
|
return new Filter() {
|
|
|
|
@SuppressWarnings("unchecked")
|
|
|
|
@Override
|
|
|
|
protected void publishResults(final CharSequence constraint, final FilterResults results) {
|
2021-01-12 20:23:10 +01:00
|
|
|
_filteredItems.clear();
|
2021-08-01 13:30:21 +02:00
|
|
|
_filteredItems.addAll((List<Integer>) results.values);
|
2020-12-09 00:57:31 +01:00
|
|
|
notifyDataSetChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected FilterResults performFiltering(final CharSequence constraint) {
|
2021-08-01 13:30:21 +02:00
|
|
|
final List<Integer> resList = new ArrayList<>();
|
2018-07-25 01:59:25 +02:00
|
|
|
|
2021-01-12 20:23:10 +01:00
|
|
|
if (_dopt.data != null) {
|
2020-12-09 00:57:31 +01:00
|
|
|
final String fil = constraint.toString();
|
|
|
|
final boolean emptySearch = fil.isEmpty();
|
2021-01-12 20:23:10 +01:00
|
|
|
for (int i = 0; i < _dopt.data.size(); i++) {
|
2021-08-01 13:30:21 +02:00
|
|
|
final String str = _dopt.data.get(i).toString();
|
2021-01-12 20:23:10 +01:00
|
|
|
final boolean matchExtra = (_extraPattern == null) || _extraPattern.matcher(str).find();
|
2021-08-01 13:30:21 +02:00
|
|
|
final Locale locale = Locale.getDefault();
|
|
|
|
final boolean matchNormal = str.toLowerCase(locale).contains(fil.toLowerCase(locale));
|
|
|
|
final boolean matchRegex = _dopt.searchIsRegex && (str.matches(fil));
|
2020-12-09 00:57:31 +01:00
|
|
|
if (matchExtra && (matchNormal || matchRegex || emptySearch)) {
|
2021-08-01 13:30:21 +02:00
|
|
|
resList.add(i);
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
|
|
|
|
final FilterResults res = new FilterResults();
|
|
|
|
res.values = resList;
|
|
|
|
res.count = resList.size();
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void showMultiChoiceDialogWithSearchFilterUI(final Activity activity, final DialogOptions dopt) {
|
|
|
|
final AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(activity, dopt.isDarkDialog
|
|
|
|
? android.support.v7.appcompat.R.style.Theme_AppCompat_Dialog
|
|
|
|
: android.support.v7.appcompat.R.style.Theme_AppCompat_Light_Dialog
|
|
|
|
);
|
2021-08-01 13:30:21 +02:00
|
|
|
final Adapter listAdapter = Adapter.create(activity, dopt);
|
2018-07-25 01:59:25 +02:00
|
|
|
|
|
|
|
final AppCompatEditText searchEditText = new AppCompatEditText(activity);
|
2020-12-09 00:57:31 +01:00
|
|
|
searchEditText.setText(dopt.defaultText);
|
2018-07-25 01:59:25 +02:00
|
|
|
searchEditText.setSingleLine(true);
|
|
|
|
searchEditText.setMaxLines(1);
|
|
|
|
searchEditText.setTextColor(dopt.textColor);
|
|
|
|
searchEditText.setHintTextColor((dopt.textColor & 0x00FFFFFF) | 0x99000000);
|
|
|
|
searchEditText.setHint(dopt.searchHintText);
|
2019-11-20 00:34:10 +01:00
|
|
|
searchEditText.setInputType(dopt.searchInputType == 0 ? searchEditText.getInputType() : dopt.searchInputType);
|
2021-08-01 13:30:21 +02:00
|
|
|
searchEditText.addTextChangedListener(TextWatcherDummy.after((cbEditable) -> listAdapter.getFilter().filter(cbEditable)));
|
|
|
|
|
|
|
|
final ContextUtils cu = new ContextUtils(activity);
|
|
|
|
final int margin = (int) cu.convertDpToPx(8);
|
|
|
|
cu.freeContextRef();
|
|
|
|
|
|
|
|
final LinearLayout searchLayout = new LinearLayout(activity);
|
|
|
|
searchLayout.setOrientation(LinearLayout.HORIZONTAL);
|
|
|
|
|
|
|
|
LinearLayout.LayoutParams lp;
|
|
|
|
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 1);
|
|
|
|
lp.gravity = Gravity.START | Gravity.BOTTOM;
|
|
|
|
searchLayout.addView(searchEditText, lp);
|
|
|
|
|
|
|
|
// 'Button to clear the search box'
|
|
|
|
final ImageView clearButton = new ImageView(activity);
|
|
|
|
clearButton.setImageResource(dopt.clearInputIcon);
|
|
|
|
TooltipCompat.setTooltipText(clearButton, activity.getString(android.R.string.cancel));
|
|
|
|
clearButton.setColorFilter(dopt.isDarkDialog ? Color.WHITE : Color.parseColor("#ff505050"));
|
|
|
|
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
|
|
|
lp.gravity = Gravity.END | Gravity.CENTER_VERTICAL;
|
|
|
|
lp.setMargins(margin, 0, (int) (margin * 1.5), 0);
|
|
|
|
searchLayout.addView(clearButton, lp);
|
|
|
|
clearButton.setOnClickListener((v) -> searchEditText.setText(""));
|
2018-07-25 01:59:25 +02:00
|
|
|
|
|
|
|
final ListView listView = new ListView(activity);
|
|
|
|
final LinearLayout linearLayout = new LinearLayout(activity);
|
|
|
|
listView.setAdapter(listAdapter);
|
2019-07-26 03:19:28 +02:00
|
|
|
listView.setVisibility(dopt.data != null && !dopt.data.isEmpty() ? View.VISIBLE : View.GONE);
|
2018-07-25 01:59:25 +02:00
|
|
|
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
2020-12-09 00:57:31 +01:00
|
|
|
|
2018-07-25 01:59:25 +02:00
|
|
|
if (dopt.isSearchEnabled) {
|
2021-08-01 13:30:21 +02:00
|
|
|
lp = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
|
|
|
|
lp.setMargins(margin, margin / 2, margin, margin / 2);
|
|
|
|
linearLayout.addView(searchLayout, lp);
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
|
2018-07-25 01:59:25 +02:00
|
|
|
final LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, 0);
|
|
|
|
layoutParams.weight = 1;
|
|
|
|
linearLayout.addView(listView, layoutParams);
|
|
|
|
if (!TextUtils.isEmpty(dopt.messageText)) {
|
|
|
|
dialogBuilder.setMessage(dopt.messageText);
|
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
|
2018-07-25 01:59:25 +02:00
|
|
|
dialogBuilder.setView(linearLayout)
|
|
|
|
.setOnCancelListener(null)
|
2019-07-26 03:19:28 +02:00
|
|
|
.setNegativeButton(dopt.cancelButtonText, (dialogInterface, i) -> dialogInterface.dismiss());
|
2020-12-09 00:57:31 +01:00
|
|
|
|
2019-11-20 00:34:10 +01:00
|
|
|
if (dopt.titleText != 0) {
|
|
|
|
dialogBuilder.setTitle(dopt.titleText);
|
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
// Ok button action
|
|
|
|
if ((dopt.isSearchEnabled && dopt.callback != null) || (dopt.isMultiSelectEnabled)) {
|
2018-07-25 01:59:25 +02:00
|
|
|
dialogBuilder.setPositiveButton(dopt.okButtonText, (dialogInterface, i) -> {
|
2021-08-01 13:30:21 +02:00
|
|
|
final String searchText = dopt.isSearchEnabled ? searchEditText.getText().toString() : null;
|
|
|
|
if (dopt.positionCallback != null && !listAdapter._selectedItems.isEmpty()) {
|
|
|
|
final List<Integer> sel = new ArrayList<>(listAdapter._selectedItems);
|
|
|
|
Collections.sort(sel);
|
|
|
|
dopt.positionCallback.callback(sel);
|
|
|
|
} else if (dopt.callback != null && !TextUtils.isEmpty(searchText)) {
|
|
|
|
dopt.callback.callback(searchText);
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
// Setup neutralbutton
|
|
|
|
if (dopt.neutralButtonCallback != null && dopt.neutralButtonText != 0) {
|
|
|
|
dialogBuilder.setNeutralButton(dopt.neutralButtonText, (dialogInterface, i) -> {
|
|
|
|
dopt.neutralButtonCallback.callback();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2018-07-25 01:59:25 +02:00
|
|
|
final AlertDialog dialog = dialogBuilder.create();
|
|
|
|
|
|
|
|
searchEditText.setOnKeyListener((keyView, keyCode, keyEvent) -> {
|
|
|
|
if ((keyEvent.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
|
|
|
|
dialog.dismiss();
|
|
|
|
if (dopt.callback != null && !TextUtils.isEmpty(searchEditText.getText().toString())) {
|
|
|
|
dopt.callback.callback(searchEditText.getText().toString());
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
|
2019-07-26 03:19:28 +02:00
|
|
|
Window w;
|
|
|
|
if ((w = dialog.getWindow()) != null && dopt.isSearchEnabled) {
|
|
|
|
w.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE | WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
|
2018-10-01 21:12:17 +02:00
|
|
|
}
|
2018-07-25 01:59:25 +02:00
|
|
|
dialog.show();
|
2019-07-26 03:19:28 +02:00
|
|
|
if ((w = dialog.getWindow()) != null) {
|
2019-11-20 00:34:10 +01:00
|
|
|
int ds_w = dopt.dialogWidthDp < 100 ? dopt.dialogWidthDp : ((int) (dopt.dialogWidthDp * activity.getResources().getDisplayMetrics().density));
|
|
|
|
int ds_h = dopt.dialogHeightDp < 100 ? dopt.dialogHeightDp : ((int) (dopt.dialogHeightDp * activity.getResources().getDisplayMetrics().density));
|
|
|
|
w.setLayout(ds_w, ds_h);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((w = dialog.getWindow()) != null && dopt.gravity != Gravity.NO_GRAVITY) {
|
|
|
|
WindowManager.LayoutParams wlp = w.getAttributes();
|
|
|
|
wlp.gravity = dopt.gravity;
|
|
|
|
w.setAttributes(wlp);
|
2019-07-26 03:19:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dopt.isSearchEnabled) {
|
|
|
|
searchEditText.requestFocus();
|
|
|
|
}
|
2020-12-09 00:57:31 +01:00
|
|
|
if (dopt.defaultText != null) {
|
|
|
|
listAdapter.getFilter().filter(searchEditText.getText());
|
|
|
|
}
|
2019-07-26 03:19:28 +02:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
// Helper function to trigger callback with single item
|
|
|
|
final Callback.b1<Integer> directActivate = (position) -> {
|
|
|
|
final int index = listAdapter._filteredItems.get(position);
|
|
|
|
dialog.dismiss();
|
|
|
|
if (dopt.callback != null) {
|
|
|
|
dopt.callback.callback(dopt.data.get(index).toString());
|
2019-07-26 03:19:28 +02:00
|
|
|
}
|
2021-08-01 13:30:21 +02:00
|
|
|
if (dopt.positionCallback != null) {
|
|
|
|
dopt.positionCallback.callback(Collections.singletonList(index));
|
2019-08-24 14:54:25 +02:00
|
|
|
}
|
2021-08-01 13:30:21 +02:00
|
|
|
return true;
|
|
|
|
};
|
|
|
|
|
|
|
|
// Helper function to append selection count to OK button
|
|
|
|
final Button okButton = dialog.getButton(Dialog.BUTTON_POSITIVE);
|
|
|
|
final String okText = activity.getString(dopt.okButtonText) + (dopt.isMultiSelectEnabled ? " (%d)" : "");
|
|
|
|
final Callback.a0 setOkButtonState = () -> {
|
|
|
|
okButton.setText(okText.replace("%d", Integer.toString(listAdapter._selectedItems.size())));
|
|
|
|
};
|
|
|
|
|
|
|
|
// Set ok button text initially
|
|
|
|
setOkButtonState.callback();
|
|
|
|
|
|
|
|
// Item click action
|
|
|
|
listView.setOnItemClickListener((parent, textView, pos, id) -> {
|
|
|
|
if (dopt.isMultiSelectEnabled) {
|
|
|
|
final int index = listAdapter._filteredItems.get(pos);
|
|
|
|
if (listAdapter._selectedItems.contains(index)) {
|
|
|
|
listAdapter._selectedItems.remove(index);
|
|
|
|
} else {
|
|
|
|
listAdapter._selectedItems.add(index);
|
2019-07-26 03:19:28 +02:00
|
|
|
}
|
2021-08-01 13:30:21 +02:00
|
|
|
if (textView instanceof Checkable) {
|
|
|
|
((Checkable) textView).setChecked(listAdapter._selectedItems.contains(index));
|
2019-07-26 03:19:28 +02:00
|
|
|
}
|
2021-08-01 13:30:21 +02:00
|
|
|
setOkButtonState.callback();
|
|
|
|
} else {
|
|
|
|
directActivate.callback(pos);
|
2019-07-26 03:19:28 +02:00
|
|
|
}
|
2021-08-01 13:30:21 +02:00
|
|
|
});
|
2019-07-26 03:19:28 +02:00
|
|
|
|
2021-08-01 13:30:21 +02:00
|
|
|
// long click always activates
|
|
|
|
listView.setOnItemLongClickListener((parent, view, pos, id) -> directActivate.callback(pos));
|
2018-07-25 01:59:25 +02:00
|
|
|
}
|
|
|
|
}
|