I am trying to add an EditText field with autocomplete functionality
(in the form of a dropdown with a list of options that can be selected as the user types into the input box) to a popup dialog.
However, rather than simply have the autocomplete suggest options based on the input text,
I need to be able to control what is suggested on each key press, and update any adaptor options accordingly.
I have tried to use two separate widgets: android.widget.AutoCompleteTextView, and “AutoCompleteDropDown” an extenstion of androidx.appcompat.widget.AppCompatAutoCompleteTextView
obtained from another thread (which I will attempt to link here if I can find it again)
My dialog code is as follows:
private static class CreateDialog {
final private AlertDialog createDialog;
public CreateDialog(Activity activity){
AlertDialog.Builder alertDialog = new AlertDialog.Builder(activity);
alertDialog.setIcon(R.drawable.ic_baseline_search_24);
alertDialog.setTitle("Search");
//Initialise layout for dialog
LinearLayout layout = new LinearLayout(activity);
layout.setOrientation(LinearLayout.VERTICAL);
//Search selection
TextView label = new TextView(activity);
label.setText("Selection");
layout.addView(label);
//AutoCompleteDropDown value = new AutoCompleteDropDown(activity);
AutoCompleteTextView value = new AutoCompleteTextView(activity);
ArrayAdapter<String> adaptor = new ArrayAdapter(activity, android.R.layout.simple_dropdown_item_1line, new String[]{"A", "AAA", "AAAAA"});
value.setAdapter(adaptor);
layout.addView(value);
//Construct dialog and add button functionality
alertDialog.setView(layout);
alertDialog.setPositiveButton("Save", (dialog, which) -> dialog.dismiss());
alertDialog.setNegativeButton("Cancel", (dialog, which) -> dialog.dismiss());
createDialog = alertDialog.create();
}
public void show(){
createDialog.show();
}
public void onSubmit(){}
}
(AutoCompleteTextView is enabled here on line 20)
With this enabled, the autocomplete widget will only display options which are a case insensitive extension to what is already typed:
I’m not sure if it’s possible to override this.
The code for AutoCompleteDropDown is as follows:
public class AutoCompleteDropDown extends AppCompatAutoCompleteTextView {
// implements AdapterView.OnItemClickListener
private static final int MAX_CLICK_DURATION = 200;
private long startClickTime;
private boolean isPopup;
private int mPosition = ListView.INVALID_POSITION;
public AutoCompleteDropDown(Context context) {
super(context);
// setOnItemClickListener(this);
}
public AutoCompleteDropDown(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
// setOnItemClickListener(this);
}
public AutoCompleteDropDown(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
// setOnItemClickListener(this);
}
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
if(this.getText().length()>0 && this.getAdapter() !=null) { performFiltering("", 0); }
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getWindowToken(), 0);
setKeyListener(null);
dismissDropDown();
} else {
isPopup = false;
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_UP: {
if (isPopup) {
dismissDropDown();
} else {
requestFocus();
showDropDown();
}
break;
}
}
return super.onTouchEvent(event);
}
@Override
public void showDropDown() {
super.showDropDown();
isPopup = true;
}
@Override
public void dismissDropDown() {
super.dismissDropDown();
isPopup = false;
}
@Override
public void setCompoundDrawablesWithIntrinsicBounds(Drawable left, Drawable top, Drawable right, Drawable bottom) {
Drawable dropdownIcon = ContextCompat.getDrawable(getContext(), R.drawable.ic_baseline_keyboard_arrow_down_24);
if (dropdownIcon != null) {
right = dropdownIcon;
right.mutate().setAlpha(66);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
super.setCompoundDrawablesRelativeWithIntrinsicBounds(left, top, right, bottom);
} else {
super.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
}
}
public int getPosition() {
return mPosition;
}
}
With this enabled, I can toggle the expansion of the dropdown and have it display all items in the adaptor (which I can dynamically update).
However, typing into the input field is having no effect and nothing is displayed (unless a dropdown option is selected, in which case it will display fine)
Is there a way to achieve my requirements of controlling which autocomplete options are presented on each key press, and still have what the user types be displayed?