Android-在AutoCompleteTextView中选择项目后防止下拉列表消失

4

尽管我在AutoCompleteTextView上设置了setOnItemClickListener并对其执行了一些自定义操作,但一旦该方法完成,列表就会关闭并在编辑框中打印出object.toString。

我想防止在选择项时关闭下拉菜单,并希望它不要替换编辑框。 我该如何实现这个?

6个回答

2

我也想实现相同的功能,我使用下面的代码来实现它。

创建一个自定义类并扩展AutoCompleteTextView。

重写dismissDropDown()方法并从中删除super调用。 这样对你有用。

public class CustomAutoComplete extends AutoCompleteTextView {
    public NoSelectionAutoComplete(Context context) {
        super(context);
    }

    public NoSelectionAutoComplete(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoSelectionAutoComplete(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void replaceText(CharSequence text) {

    }

    @Override
    public void dismissDropDown() {

    }
}

1

至少看起来他们计划在不久的将来添加这个功能。

/**
 * Sets whether the drop-down should remain visible as long as there is there is
 * {@link #enoughToFilter()}.  This is useful if an unknown number of results are expected
 * to show up in the adapter sometime in the future.
 *
 * The drop-down will occupy the entire screen below {@link #getDropDownAnchor} regardless
 * of the size or content of the list.  {@link #getDropDownBackground()} will fill any space
 * that is not used by the list.
 *
 * @param dropDownAlwaysVisible Whether to keep the drop-down visible.
 *
 * @hide Pending API council approval
 */
public void setDropDownAlwaysVisible(boolean dropDownAlwaysVisible) {
    mPopup.setDropDownAlwaysVisible(dropDownAlwaysVisible);
}

1

我在使用下拉适配器的自定义行布局中添加了一个onClickListener。这样,每当单击该行时,将调用我的行onClickListener,而不是下拉列表的默认onClickListener。


1

第一个问题 - 防止下拉菜单消失:

以下已解决。

第二个问题 - 防止文本替换:(对其他人感兴趣)

您可以扩展AutoCompleteTextView并覆盖

protected void replaceText(CharSequence text) {}

不做任何事情。

正如其他人提到的,覆盖 performCompletion() 方法在这里是无效的。


replaceText 使得下拉菜单的性能变得太慢。 - Ahamadullah Saikat

0

覆盖replaceText而不调用super可以正常工作(防止将建议的文本输入到AutoCompleteTextView中),但覆盖dismissDropDown会导致在点击项目时不关闭下拉菜单,以及在onBackPressed、对话框外部触摸等情况下也不关闭...

我最终没有使用AutoCompleteTextView中的setOnItemClickListener方法。我在我的自定义ArrayAdapter中创建了自定义的onClick,并将其设置为getView方法返回的所有View

View.OnClickListener onClick=null;

public void setOnItemClickListener(View.OnClickListener onClick) {
    this.onClick=onClick;
    /*this.onClick=new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            if(v.getTag()==null)
                return;
            Integer position = (Integer) v.getTag();
            Toast.makeText(v.getContext(), "position: "+postion, Toast.LENGTH_SHORT).show();
        }
    });*/
}

@NonNull
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
    ... call super/inflate convertView and do your stuff here
    setCustomOnClick(convertView, position);
    return convertView;
}

private void setCustomOnClick(final View view, final int position){
    view.setTag(position); 
    view.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            if(onClick==null)
                return;
            // inside called onClick method v.getTag() will return pressed position
            onClick.onClick(v);
        }
    });
}

实际上,为整个视图设置onClick将覆盖“原始”的始终解除和始终替换文本的onClick(然后根本不被调用)。请记住,在调用“原始”onClick时添加自定义图形表示时,会显示涟漪/选择器。

我还需要始终可见的功能,因为我的自动完成必须始终显示第一个位置(功能),即使没有建议(如果存在,则在1+位置下方显示)

public class AlwaysVisibleAutoCompleteTextView extends AppCompatAutoCompleteTextView {

    private boolean showAlways=true;

    public AlwaysVisibleAutoCompleteTextView(Context context) {
        super(context);
    }

    public AlwaysVisibleAutoCompleteTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public AlwaysVisibleAutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setShowAlways(boolean showAlways) {
        this.showAlways = showAlways;
    }

    @Override
    public boolean enoughToFilter() {
        return showAlways || super.enoughToFilter();
    }

    @Override
    protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
        super.onFocusChanged(focused, direction, previouslyFocusedRect);
        showDropDownIfFocused();
    }

    private void showDropDownIfFocused() {
        if (enoughToFilter() && isFocused() && getWindowVisibility() == View.VISIBLE)
            showDropDown();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        showDropDownIfFocused();
    }

}

当焦点在AlwaysVisibleAutoCompleteTextView上,但下拉菜单被关闭并且用户再次按下view时,下拉菜单不会显示,因为焦点状态没有改变(onFocusChanged未被调用),所以...
autoComplete.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (event.getAction() == MotionEvent.ACTION_UP) 
                autoComplete.showDropDown();
            return false;
        }
    });

如果您不打算在AutoCompleteTextView中使用setOnTouchListener进行任何其他用途,那么OnTouchListener可以在AlwaysVisibleAutoCompleteTextView类中设置(在每个构造函数中)。


0

编辑,新答案: 这对我有用,但它会关闭一秒钟,然后再次打开。

            class task extends TimerTask {

            @Override
            public void run() {
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        autoComplete.showDropDown();
                    }
                });
            }
       };
    autoComplete.setOnItemClickListener(new OnItemClickListener() {

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
                long arg3) {

             new Timer().schedule(new task(),0, 10);
        }

    });

我已经有一个TextWatcher了。我需要它在最低API级别10上工作。 - user1018916
我尝试扩展AutoCompleteTextView并覆盖performCompletion方法,但该方法从未被调用。 - user1018916
@user1018916,有常规的setOnClickListener(仅适用于TextView点击)和setOnFocusChangeListener。我发现的唯一事情是来自我给你的API 17答案的代码片段。显然,TextWatcher无法检测到从下拉菜单单击引起的更改,这很遗憾。 - user1779374

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接