Android: AutoCompleteTextView hiển thị đề xuất khi không có văn bản nào được nhập


127

Tôi đang sử dụng AutoCompleteTextView, khi người dùng nhấp vào nó, tôi muốn hiển thị các đề xuất ngay cả khi nó không có văn bản - nhưng setThreshold(0)hoạt động chính xác như setThreshold(1)- vì vậy người dùng phải nhập ít nhất 1 ký tự để hiển thị các đề xuất.


Tôi đang làm một cái gì đó tương tự TẠI ĐÂY !!! stackoverflow.com/questions/12854336/ cường
toobsco42

Câu trả lời:


159

Đây là hành vi được ghi lại :

Khi thresholdnhỏ hơn hoặc bằng 0, ngưỡng 1 được áp dụng.

Bạn có thể tự hiển thị trình đơn thả xuống qua showDropDown(), vì vậy có lẽ bạn có thể sắp xếp để hiển thị nó khi bạn muốn. Hoặc, phân lớp AutoCompleteTextViewvà ghi đè enoughToFilter(), trả lại truetất cả thời gian.


7
Các showDropDown () dường như làm việc tốt trên seting OnClickListener, nhưng lớp con điều không hoạt động cho đến khi người dùng nhập thư và đi kèm dels back.But không chỉ với onClick ...
AMJ

9
Điều này hoạt động hoàn hảo khi kết hợp với OnF FocusChangeListener gọi showDropDown () khi chế độ xem đạt được tiêu điểm.
Grishka

Tôi cũng phải ghi đè lên onF FocusChanged, như đã nêu trong câu trả lời dưới đây của @David Vávra
Gabriel

4
@commonsWare showDropDown()không hoạt động afterTextChangedkhi nào .getText().toString().length()==0. TẠI SAO
Mitchs

1
Chỉ ghi đè đủ ToFilter giúp tôi. Cảm ơn bạn!
Fedir Tsapana

121

Đây là lớp học của tôi InstantAutoComplete . Đó là một cái gì đó giữa AutoCompleteTextViewSpinner.

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);
        }
    }

}

Sử dụng nó trong xml của bạn như thế này:

<your.namespace.InstantAutoComplete ... />

12
Thật tuyệt! Tôi cũng muốn chỉ ra rằng trong tệp XML bố trí của bạn, bạn phải thay đổi <AutoCompleteTextView ... />thành <your.namespace.InstantAutoComplete ... />. Tôi đã mất một thời gian để tìm ra điều này :)
Jules Colle

3
Lớp tuyệt vời - chỉ đề xuất sẽ có trong phương thức onF FocusChanged, thay đổi "if (tập trung)" thành "if (tập trung && getAd CHƯƠNG ()! = Null)".
Jacob Tabak

Đối với AndroidX , hãy gia hạn androidx.appcompat.widget.AppCompatAutoCompleteTextView.
Mahmudul Hasan Shohag

Điều này không hiển thị thả xuống về thay đổi định hướng.
Miha_x64

45

Cách dễ nhất:

Chỉ cần sử dụng setOnTouchListener và showDropDown ()

AutoCompleteTextView text;
.....
.....
text.setOnTouchListener(new View.OnTouchListener(){
   @Override
   public boolean onTouch(View v, MotionEvent event){
      text.showDropDown();
      return false;
   }
});

Để làm cho điều này thậm chí sử dụng tốt hơn nếu (! Text.isPopupShowing ()) {text.showDropDown (); }
Boldijar Paul

7
không phổ biến lắm, nhưng điều này sẽ không hoạt động trong trường hợp người dùng không chạm vào để vào EditText này. Ví dụ: khi sử dụng điều khiển từ xa với các nút (chẳng hạn như Android TV).
nhà phát triển Android

2
Bạn nên sử dụng setOnF FocusChanged. Ai đó có thể có bàn phím và nhấn nút TAB hoặc sử dụng chuột và cảm ứng nghe sẽ không được gọi.
barwnikk

onTouchListener sẽ được gọi nhiều lần khác nhau cho một lần nhấn - Ví dụ: sự kiện có thể là MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP. Vì vậy, tốt hơn để kiểm tra một sự kiện cụ thể và viết mã
Govind

18

Mã của Destil chỉ hoạt động tuyệt vời khi chỉ có một InstantAutoCompleteđối tượng. Nó không hoạt động với hai mặc dù - không biết tại sao. Nhưng khi tôi đưa showDropDown()(giống như CommonsWare khuyên) vào onFocusChanged()như thế này:

@Override
protected void onFocusChanged(boolean focused, int direction,
        Rect previouslyFocusedRect) {
    super.onFocusChanged(focused, direction, previouslyFocusedRect);
    if (focused) {
        performFiltering(getText(), 0);
        showDropDown();
    }
}

nó đã giải quyết vấn đề

Nó chỉ là hai câu trả lời được kết hợp đúng, nhưng tôi hy vọng nó có thể tiết kiệm thời gian cho ai đó.


2
Sự bổ sung của bạn đã giúp, nhưng tôi đã gặp lỗi nếu có văn bản trong InstantAutoComplete và hướng màn hình thay đổi. Tôi đã sửa nó bằng một kiểm tra về khả năng hiển thị của cửa sổ, tôi đã đăng mã mới tại đây: gist.github.com/furycomptuers/4961368
FuryComputers 15/213

9

Bộ điều hợp không thực hiện lọc ban đầu.
Khi quá trình lọc không được thực hiện, danh sách thả xuống trống.
vì vậy bạn có thể phải bắt đầu lọc.

Để làm như vậy, bạn có thể gọi filter()sau khi bạn hoàn thành việc thêm các mục:

adapter.add("a1");
adapter.add("a2");
adapter.add("a3");
adapter.getFilter().filter(null);

6

Bạn có thể sử dụng onF FocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {

        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            if (hasFocus) {
                TCKimlikNo.showDropDown();

            }

        }
    });

6

Câu trả lời của Destil ở trên gần như hoạt động, nhưng có một lỗi tinh vi. Khi người dùng lần đầu tiên tập trung vào trường mà nó hoạt động, tuy nhiên nếu họ rời đi và sau đó quay lại trường thì nó sẽ không hiển thị thả xuống vì giá trị của mPopupCanBeUpdated vẫn sẽ sai từ khi nó bị ẩn. Cách khắc phục là thay đổi phương thức onF FocusChanged thành:

@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("");
        }
    }
}

nhưng điều này cũng có nghĩa là văn bản sẽ được đặt lại (mặc dù điều đó thường khá ổn) ...
nhà phát triển Android

3

Để tạo CustomAutoCompleteTextView. 1. ghi đè phương thức setThrưỡng, enoughToFilter, onF FocusChanged

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; 
    } 
}

3

thử nó

    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;
            }
        }):

3

Chỉ cần gọi phương thức này khi chạm hoặc bấm vào sự kiện autoCompleteTextView hoặc nơi bạn muốn.

autoCompleteTextView.showDropDown()

0

Điều này làm việc cho tôi, mã giả:

    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);
    }
}


0

Chỉ cần dán nó vào Phương thức onCreate của bạn trong 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();

        }
    });

Và đây là tệp Xml của bạn ...

<AutoCompleteTextView
            android:layout_width="200dp"
            android:layout_height="30dp"
            android:hint="@string/select_location"
            android:id="@+id/acT1"
            android:textAlignment="center"/>

Và tạo một Mảng trong chuỗi XML trong Giá trị ...

<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>

Và bạn tốt để đi.


0

Bảy năm sau, các bạn, vấn đề vẫn như cũ. Đây là một lớp có chức năng buộc cửa sổ bật lên ngu ngốc đó hiển thị trong mọi điều kiện. Tất cả những gì bạn cần làm là đặt bộ điều hợp cho AutoCompleteTextView, thêm một số dữ liệu vào đó và gọi showDropdownNow()chức năng bất cứ lúc nào.

Tín dụng cho @David Vávra. Nó dựa trên mã của anh ấy.

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)
        }
    }
}

0

trên FocusChangeListener, kiểm tra

if (hasFocus) {
            tvAutoComplete.setText(" ")

trong bộ lọc của bạn, chỉ cần cắt giá trị này:

filter { it.contains(constraint.trim(), true) }

và nó sẽ hiển thị tất cả các đề xuất khi bạn tập trung vào quan điểm này.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.