AutoCompleteTextView threshhold is not working as expected - android

I want to show dropdown list even for completely empty string. Because my coded logic in Adapter is that if filtering constraint is empty or null, show all results available. But for some reason, results are filtered and returned, but dropdown is hidden while text is empty.
I set threshold to 0 but its not working. I even tried negative values.
I tried to override afterTextChanged listener and force to show dropdown while query is empty or null, but AutoCompleteTextview is forcing to hide dropdown anyways.
In documentation I found this line:
When threshold is less than or equals 0, a threshold of 1 is applied.
That means I cant do this behavior?

You have to create your own custom autocomplete text view by extending e.g. the AppCompatAutoCompleteTextView.
Here is mine:
public class InstantAutoCompleteTextView extends AppCompatAutoCompleteTextView {
public InstantAutoCompleteTextView(Context context) {
super(context);
}
public InstantAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public InstantAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
#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) {
performFiltering(getText(), 0);
}
}
#SuppressLint("ClickableViewAccessibility")
#Override
public boolean onTouchEvent(MotionEvent event) {
if (MotionEvent.ACTION_UP != event.getAction()) {
return super.onTouchEvent(event);
}
if (!isPopupShowing() && getAdapter() != null) {
showDropDown();
}
return super.onTouchEvent(event);
}
}
Then you can use it in the layout file:
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<your.package.name.util.InstantAutoCompleteTextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="#string/hint"
android:imeOptions="actionDone"
android:inputType="text|textCapWords" />
</com.google.android.material.textfield.TextInputLayout>

Related

Edit text is not editable in Android Pie 9.0

Hello Everyone,
I m having an issue with the AppCompatEditText. I have override an AppCompatEditText and add Enter button in keyboard (setImeOptions(EditorInfo.IME_ACTION_GO)). This is working fine on all Android versions, expect on 9.0. Here is the code of my Class
public class EditTextWithGOButton extends AppCompatEditText {
private EditTextAction editTextAction;
public interface EditTextAction {
void onGoButtonClicked(String text);
}
public void setEditTextAction(EditTextAction editTextAction) {
this.editTextAction = editTextAction;
}
public EditTextWithGOButton(Context context) {
super(context);
changeImeOption();
}
public EditTextWithGOButton(Context context, AttributeSet attrs) {
super(context, attrs);
changeImeOption();
}
public EditTextWithGOButton(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
changeImeOption();
}
private void changeImeOption() {
this.setImeOptions(EditorInfo.IME_ACTION_GO);
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
(keyCode == KeyEvent.KEYCODE_ENTER)) {
if (editTextAction != null){
editTextAction.onGoButtonClicked(getText().toString());
}
}
// Returning false allows other listeners to react to the press.
return false;
// Handle all other keys in the default way
// return super.onKeyDown(keyCode, event);
}
}
And My XML.
<com.app.common.views.EditTextWithGOButton
android:id="#+id/edt_search_bar"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3.2"
android:background="#drawable/search_edittext_rounded_corner_background"
android:drawableRight="#android:drawable/ic_menu_search"
android:drawableTint="#color/colorPrimary"
android:hint="#string/search_your_activity"
android:paddingRight="10dp"
android:paddingLeft="10dp"
android:maxLines="1"
android:paddingTop="05dp"
android:paddingBottom="05dp"
android:textColorHint="#color/colorPrimary" />
I have tired to set it focus able manually. When I remove this.setImeOptions(EditorInfo.IME_ACTION_GO); and onKeyDown listener, AppCompatEditText became editable , But keyboard won't pop up. I have tried EditText as well.But issue remain same. Any Solution ??

InputType has no effect on a custom EditText

I created this custom view extended from AppCompatEditText :
public class NoteEditText extends AppCompatEditText {
// INTERFACES ----------------------------------------------------------------------------------------------------
public interface OnKeyPreImeListener {
void onKeyPreIme(int keyCode, KeyEvent event);
}
// ATTRIBUTES ----------------------------------------------------------------------------------------------------
private MovementMethod movementMethod;
private KeyListener keyListener;
private OnKeyPreImeListener onKeyPreImeListener;
// CONSTRUCTORS ----------------------------------------------------------------------------------------------------
public NoteEditText(Context context) {
super(context);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
public NoteEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.movementMethod = this.getMovementMethod();
this.keyListener = this.getKeyListener();
}
// SETTERS ----------------------------------------------------------------------------------------------------
public void setOnKeyPreImeListener(OnKeyPreImeListener onKeyPreImeListener) {
this.onKeyPreImeListener = onKeyPreImeListener;
}
// METHODS ----------------------------------------------------------------------------------------------------
public void enable() {
this.setMovementMethod(this.movementMethod);
this.setKeyListener(this.keyListener);
this.setFocusableInTouchMode(true);
this.setImeOptions(EditorInfo.IME_ACTION_DONE);
this.setRawInputType(InputType.TYPE_CLASS_TEXT);
}
public void disable() {
this.setMovementMethod(null);
this.setKeyListener(null);
}
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (this.onKeyPreImeListener != null)
this.onKeyPreImeListener.onKeyPreIme(keyCode, event);
return true;
}
}
I call it like this :
<com.company.adapters.items.NoteEditText
android:id="#+id/note"
style="#style/AppTheme.SubItem"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="#dimen/content_margin_xs"
android:gravity="center_vertical"
android:hint=""
android:imeOptions="actionDone"
android:inputType="textMultiLine|textCapSentences|textNoSuggestions"
android:minHeight="#dimen/content_subitem_height"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="#id/note_icon"
app:layout_constraintTop_toBottomOf="#+id/name" />
It works well, except the "textMultiLine|textCapSentences|textNoSuggestions" inputTypes. Neither "textCapSentences" nor "textNoSuggestions" are applied, although "textMultiLine" is working.
If I use the exact same configuration but with the original EditText view, all the inputTypes work... very strange.
this.setRawInputType(InputType.TYPE_CLASS_TEXT);
From your enable function. This is overriding the input type.

Android TimePicker (Wheel Style) not responding correctly to flick gestures inside ScrollView

I have a dialog box that contains a Scrollview, which contains a layout with two TimePickers.
The timepickers are the newer style ones, what's in ICS.
The problem is that they seem to fight for focus when you change the time by dragging the wheel, or flicking it. It will change the time just a little, and then the layout will scroll instead.
Any ideas?
Thanks in advance.
I had the same problem when using the Holo theme, and here is where I found the solution: https://groups.google.com/forum/?fromgroups#!topic/android-developers/FkSfJI6dH8w
You must implement your custom DatePicker or TimePicker and override the following method:
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN)
{
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
Because the link from Klemens Zleptnig is broken, here is a complete example. This fix helps with the scroll of a TabLayout too btw. I excluded the area around the big numbers in the top of the TimePicker because they don't need the scroll event anyway.
xml:
<com.name.app.MyTimePicker
android:id="#+id/timePicker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
.../>
java:
public class MyTimePicker extends TimePicker {
public MyTimePicker(Context context) {
super(context);
}
//This is the important constructor
public MyTimePicker(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public MyTimePicker(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
#Override
public boolean onInterceptTouchEvent(MotionEvent ev)
{
if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) {
//Excluding the top of the view
if(ev.getY() < getHeight()/3.3F)
return false;
ViewParent p = getParent();
if (p != null)
p.requestDisallowInterceptTouchEvent(true);
}
return false;
}
}

How do I get text to Marquee in the Android-wheel?

I am using the android-wheel http://code.google.com/p/android-wheel/ in an application.
I have three of the wheels side by side on my screen. When the text in a wheel is wider than the wheel I would like it to scroll to the side (As per Marquee)
I have implemented an AbstractWheelTextAdapter and created a custom ScrollingTextView for the items as follows: (ScrollingTextView is to overcome the issue with Marquee only working when an item has focus)
public class ScrollingTextView extends TextView {
public ScrollingTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public ScrollingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollingTextView(Context context) {
super(context);
}
#Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if(focused)
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
#Override
public void onWindowFocusChanged(boolean focused) {
if(focused)
super.onWindowFocusChanged(focused);
}
#Override
public boolean isFocused() {
return true;
}
}
And the xml:
<com.test.app.ScrollingTextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id = "#+id/wheel_text"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:inputType="text"
android:scrollHorizontally="true"
android:textColor="#F000"
android:lines="1"
android:focusable="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:focusableInTouchMode="true"/>
Has anyone been able to get this to work?
(I have also tried setting the Ellipse in the code for the AbstractWheelTextAdapter without success)
Because the WheelView didn't invalidate itself.In Activity,add the code :
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
wheelview.invalidate();
sendEmptyMessageDelayed(0, 0);
}
};
handler.sendEmptyMessage(0);
Then the TextView Marquee effect works.But when you scroll the WheelView,the TextView string reset from start.
I had try the TextView Marquee effect in ListView, the Marquee effect works.I gonna check the ListView source code ,see what differences between ListView and WheelView.

Android: AutoCompleteTextView show suggestions when no text entered

I am using AutoCompleteTextView, when the user clicks on it, I want to show suggestions even if it has no text - but setThreshold(0) works exactly the same as setThreshold(1) - so the user has to enter at least 1 character to show the suggestions.
This is documented behavior:
When threshold is less than or equals 0, a threshold of 1 is
applied.
You can manually show the drop-down via showDropDown(), so perhaps you can arrange to show it when you want. Or, subclass AutoCompleteTextView and override enoughToFilter(), returning true all of time.
Here is my class InstantAutoComplete. It's something between AutoCompleteTextView and Spinner.
import android.content.Context;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.widget.AutoCompleteTextView;
public class InstantAutoComplete extends AutoCompleteTextView {
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) {
performFiltering(getText(), 0);
}
}
}
Use it in your xml like this:
<your.namespace.InstantAutoComplete ... />
Easiest way:
Just use setOnTouchListener and showDropDown()
AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
#Override
public boolean onTouch(View v, MotionEvent event){
text.showDropDown();
return false;
}
});
Destil's code works just great when there is only one InstantAutoComplete object. It didn't work with two though - no idea why. But when I put showDropDown() (just like CommonsWare advised) into onFocusChanged() like this:
#Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
showDropDown();
}
}
it solved the problem.
It is just the two answers properly combined, but I hope it may save somebody some time.
The adapter does not perform filtering initially.
When the filtering is not performed, the dropdown list is empty.
so you might have to get the filtering going initially.
To do so, you can invoke filter() after you finish adding the entries:
adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);
You can use onFocusChangeListener;
TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {
#Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {
TCKimlikNo.showDropDown();
}
}
});
Destil's answer above almost works, but has one subtle bug. When the user first gives focus to the field it works, however if they leave and then return to the field it will not show the drop down because the value of mPopupCanBeUpdated will still be false from when it was hidden. The fix is to change the onFocusChanged method to:
#Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
if (getText().toString().length() == 0) {
// We want to trigger the drop down, replace the text.
setText("");
}
}
}
Just call this method on touch or click event of autoCompleteTextView or where you want.
autoCompleteTextView.showDropDown()
To make CustomAutoCompleteTextView.
1. override setThreshold,enoughToFilter,onFocusChanged method
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
private int myThreshold;
public CustomAutoCompleteTextView (Context context) {
super(context);
}
public CustomAutoCompleteTextView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public CustomAutoCompleteTextView (Context context, AttributeSet attrs) {
super(context, attrs);
}
//set threshold 0.
public void setThreshold(int threshold) {
if (threshold < 0) {
threshold = 0;
}
myThreshold = threshold;
}
//if threshold is 0 than return true
public boolean enoughToFilter() {
return true;
}
//invoke on focus
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
//skip space and backspace
super.performFiltering("", 67);
// TODO Auto-generated method stub
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
protected void performFiltering(CharSequence text, int keyCode) {
// TODO Auto-generated method stub
super.performFiltering(text, keyCode);
}
public int getThreshold() {
return myThreshold;
}
}
try it
searchAutoComplete.setThreshold(0);
searchAutoComplete.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {//cut last probel
if (charSequence.length() > 1) {
if (charSequence.charAt(charSequence.length() - 1) == ' ') {
searchAutoComplete.setText(charSequence.subSequence(0, charSequence.length() - 1));
searchAutoComplete.setSelection(charSequence.length() - 1);
}
}
}
#Override
public void afterTextChanged(Editable editable) {
}
});
//when clicked in autocomplete text view
#Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.header_search_etv:
if (searchAutoComplete.getText().toString().length() == 0) {
searchAutoComplete.setText(" ");
}
break;
}
}):
Seven years later, guys, the problem stays the same. Here's a class with a function which forces that stupid pop-up to show itself in any conditions. All you need to do is to set an adapter to your AutoCompleteTextView, add some data into it, and call showDropdownNow() function anytime.
Credits to #David Vávra. It's based on his code.
import android.content.Context
import android.util.AttributeSet
import android.widget.AutoCompleteTextView
class InstantAutoCompleteTextView : AutoCompleteTextView {
constructor(context: Context) : super(context)
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs)
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
override fun enoughToFilter(): Boolean {
return true
}
fun showDropdownNow() {
if (adapter != null) {
// Remember a current text
val savedText = text
// Set empty text and perform filtering. As the result we restore all items inside of
// a filter's internal item collection.
setText(null, true)
// Set back the saved text and DO NOT perform filtering. As the result of these steps
// we have a text shown in UI, and what is more important we have items not filtered
setText(savedText, false)
// Move cursor to the end of a text
setSelection(text.length)
// Now we can show a dropdown with full list of options not filtered by displayed text
performFiltering(null, 0)
}
}
}
on FocusChangeListener, check
if (hasFocus) {
tvAutoComplete.setText(" ")
in your filter, just trim this value:
filter { it.contains(constraint.trim(), true) }
and it will show all suggestion when you focus on this view.
This worked for me, pseudo code:
public class CustomAutoCompleteTextView extends AutoCompleteTextView {
public CustomAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
#Override
public boolean enoughToFilter() {
return true;
}
#Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
performFiltering(getText(), 0);
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
this.showDropDown();
return super.onTouchEvent(event);
}
}
Just paste this to your onCreate Method in Java
final ArrayAdapter<String> arrayAdapter = new ArrayAdapter<>(
this, android.R.layout.simple_spinner_dropdown_item,
getResources().getStringArray(R.array.Loc_names));
textView1 =(AutoCompleteTextView) findViewById(R.id.acT1);
textView1.setAdapter(arrayAdapter);
textView1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View arg0) {
textView1.setMaxLines(5);
textView1.showDropDown();
}
});
And this to your Xml file...
<AutoCompleteTextView
android:layout_width="200dp"
android:layout_height="30dp"
android:hint="#string/select_location"
android:id="#+id/acT1"
android:textAlignment="center"/>
And create an Array in string.xml under Values...
<string-array name="Loc_names">
<item>Pakistan</item>
<item>Germany</item>
<item>Russia/NCR</item>
<item>China</item>
<item>India</item>
<item>Sweden</item>
<item>Australia</item>
</string-array>
And you are good to go.
For me, It is :
autoCompleteText.setThreshold(0);
do the trick.

Categories

Resources