Reputation: 723
Problem: MyAutoCompleteTextView.**showDropDown()**
will work when called by the onFocusChange
but won't work when called by the onTextChanged
. During my debug, the onTextChanged
method gets called correctly when I want it to execute the showDropDown()
according to the logging message I created, just nothing happens. I noticed there is a SpannableStringBuilder
error that occurs prior, but as I recall (could be wrong) when I checked on this error in the past, this is a common error with an open ticket. I wasn't really sure it is the cause.
What I'm trying to do: ... is what everyone that asks this type of question wants to do, get the AutoCompleteTextView
to show the full list anytime the AutoCompleteTextView
is focused and empty (my first item is: "")
What I have tried: I've tried many "green checked" solutions on this forum, but none of them have worked at present EXCEPT when first focused. They will cause the full items list to present, but it is on the backspacing back to zero that it will not. I'm using a combination of change listeners
as most suggestions have. I just really thought this would work based on the logging values and it being called at the proper time?
My logging statement: which writes when I want it to showing the method gets called when I like.
E/SpannableStringBuilder: SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
E/OnTextChanged: showDropDown()
start: 0
before: 1
count: 0
length: 0
My current version and effort:
ArrayAdapter<String> topicsAdapter = DBQueryTools.captureDBTopics(this);
topic.setAdapter(topicsAdapter);
topic.setOnItemClickListener((parent, view, position, id) -> {
if(!topic.getText().toString().equals("")) {
question.setText("");
rListNotes.setAdapter(null);
customSearch.setText(null);
loadNotes(captureNotes(researchDatabase.getNotesDao().getNotesOnTopic(topic.getText().toString())));
}
});
topic.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(before == 1 && count == 0 && s.length()==0) {
topic.showDropDown();
Log.e("OnTextChanged", "showDropDown() " + s + "\n" + "start: " + start + "\nbefore: " + before + "\ncount: " + count + "\nlength: " + s.length());
}
}
@Override
public void afterTextChanged(Editable s) {
}
});
topic.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
topic.showDropDown();
Log.e("HasFocus", "showDropDown");
}
}
});
Upvotes: 1
Views: 498
Reputation: 10910
I was able to get a modified version of the InstantAutoComplete view working (combining from here and here)
public class InstantAutoComplete extends AppCompatAutoCompleteTextView {
public InstantAutoComplete(Context context) {
super(context);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1) {
super(arg0, arg1);
}
public InstantAutoComplete(Context arg0, AttributeSet arg1, int arg2) {
super(arg0, arg1, arg2);
}
@Override
public boolean enoughToFilter() {
return true;
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused && getAdapter() != null) {
// This part was necessary to get it working when not
// inside a TextInputLayout and multiple per activity
if( !maybeShowSuggestions() ) {
post(this::maybeShowSuggestions);
}
}
}
private boolean maybeShowSuggestions() {
if( getWindowVisibility() == View.VISIBLE ) {
performFiltering(getText(), 0);
showDropDown();
return true;
}
else {
return false;
}
}
}
The XML for inserting it looks like (also worked without the TextInputLayout
)
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/text_layout"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.ExposedDropdownMenu"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type words here"
android:layout_margin="16dp"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/focus_stealer" >
<com.example.autocompletetextviewdemo.InstantAutoComplete
android:id="@+id/autocomplete_text_view"
android:layout_width="match_parent"
android:completionThreshold="0"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
and for setting it up with an adapter
private static final String[] WORDS = new String[] {
"Aardvark", "Apple", "Baby", "Boron", "Carbon"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_dropdown_item_1line, WORDS);
AutoCompleteTextView textView = findViewById(R.id.autocomplete_text_view);
textView.setAdapter(adapter);
}
This works with multiple InstantAutoComplete dropdowns per activity, and after navigating back and forth between activities. Without the extra changes to the custom class it didn't work with multiple instances in an activity that weren't in a TextInputLayout
.
Upvotes: 1