Android: AutoCompleteTextView แสดงคำแนะนำเมื่อไม่ได้ป้อนข้อความ


127

ฉันกำลังใช้AutoCompleteTextViewเมื่อผู้ใช้คลิกที่ฉันต้องการแสดงข้อเสนอแนะแม้ว่าจะไม่มีข้อความ - แต่setThreshold(0)ทำงานเหมือนกับsetThreshold(1)- ดังนั้นผู้ใช้จะต้องป้อนอย่างน้อย 1 ตัวอักษรเพื่อแสดงคำแนะนำ


ฉันกำลังทำสิ่งที่คล้ายกันที่นี่ !!! stackoverflow.com/questions/12854336/…
toobsco42

คำตอบ:


159

นี่คือพฤติกรรมที่บันทึกไว้ :

เมื่อthresholdน้อยกว่าหรือเท่ากับ 0 จะมีการใช้ขีด จำกัด 1

คุณสามารถแสดงรายการแบบเลื่อนลงผ่านทางด้วยตนเองshowDropDown()ดังนั้นบางทีคุณสามารถจัดเรียงเพื่อแสดงเมื่อคุณต้องการ หรือคลาสย่อยAutoCompleteTextViewและแทนที่enoughToFilter()โดยส่งคืนtrueเวลาทั้งหมด


7
showDropDown () ดูเหมือนจะทำงานได้ดีบน seting OnClickListener แต่สิ่ง subclass ไม่ทำงานจนกว่าผู้ใช้ป้อนตัวอักษรและมา dels back.But ไม่เพียงกับ onClick ...
AMJ

9
สิ่งนี้ทำงานได้อย่างสมบูรณ์แบบเมื่อใช้ร่วมกับ OnFocusChangeListener ที่เรียก showDropDown () เมื่อมุมมองได้รับโฟกัส
Grishka

ฉันต้องแทนที่ onFocusChanged ตามที่ระบุไว้ในคำตอบด้านล่างโดย @David Vávra
Gabriel

4
@commonsWare showDropDown()ไม่ทำงานafterTextChangedเมื่อ.getText().toString().length()==0ใด WHYYY
Prabs

1
มีเพียงการเอาชนะเท่านั้นตัวกรองช่วยฉันได้ ขอบคุณ!
Fedir Tsapana

121

นี่คือชั้นเรียนของฉันInstantAutoComplete มันเป็นสิ่งที่ระหว่างและ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);
        }
    }

}

ใช้ใน xml ของคุณเช่นนี้:

<your.namespace.InstantAutoComplete ... />

12
เยี่ยมมาก! ฉันยังต้องการจะชี้ให้เห็นว่าในไฟล์ XML รูปแบบของคุณคุณจะมีการเปลี่ยนแปลงไป<AutoCompleteTextView ... /> <your.namespace.InstantAutoComplete ... />ฉันหายไปบางครั้งการหานี้ :)
จูลส์ Colle

3
Great class - ข้อเสนอแนะเท่านั้นที่จะอยู่ในวิธีการ onFocusChanged เปลี่ยน "if (focus)" เป็น "if (focus && getAdapter ()! = null)"
Jacob Tabak

สำหรับAndroidXandroidx.appcompat.widget.AppCompatAutoCompleteTextViewขยาย
Mahmudul Hasan Shohag

สิ่งนี้จะไม่แสดงรายการแบบเลื่อนลงของการเปลี่ยนแปลงการวางแนว
Miha_x64

45

วิธีที่ง่ายที่สุด:

เพียงใช้ setOnTouchListener และ showDropDown ()

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

เพื่อให้ใช้งานได้ดียิ่งขึ้นหาก (! text.isPopupShowing ()) {text.showDropDown (); }
Boldijar Paul

7
ไม่บ่อยนัก แต่สิ่งนี้จะไม่ทำงานในกรณีที่ผู้ใช้ไม่ได้สัมผัสเพื่อไปที่ EditText นี้ ตัวอย่างเช่นเมื่อใช้รีโมทคอนโทรลพร้อมปุ่มต่างๆ (เช่น Android TV เป็นต้น)
นักพัฒนา android

2
คุณควรใช้ setOnFocusChanged ใครบางคนสามารถมีแป้นพิมพ์และกดปุ่ม TAB มิฉะนั้นการใช้เม้าส์และระบบสัมผัสจะไม่ถูกเรียก
barwnikk

onTouchListener จะได้รับการเรียกเวลาที่ต่างกันสำหรับการแตะครั้งเดียว - Ex: เหตุการณ์สามารถ MotionEvent.ACTION_DOWN, MotionEvent.ACTION_UP ดังนั้นจึงเป็นการดีกว่าที่จะตรวจสอบเหตุการณ์ที่เฉพาะเจาะจงและเขียนรหัส
Govind

18

โค้ดของ Destil นั้นยอดเยี่ยมมากเมื่อมีInstantAutoCompleteวัตถุเพียงชิ้นเดียว มันไม่ได้ทำงานกับสองแม้ว่า - ไม่รู้ว่าทำไม แต่เมื่อฉันใส่showDropDown()(เช่น CommonsWare แนะนำ) ลงในonFocusChanged()แบบนี้:

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

มันแก้ปัญหาได้

มันเป็นเพียงคำตอบสองข้อที่รวมกันอย่างเหมาะสม แต่ฉันหวังว่ามันอาจช่วยใครซักคนได้สักพัก


2
การเพิ่มของคุณช่วย แต่ฉันได้รับข้อผิดพลาดหากมีข้อความใน InstantAutoComplete และการวางแนวหน้าจอเปลี่ยนไป ฉันแก้ไขด้วยการตรวจสอบการมองเห็นหน้าต่างฉันโพสต์รหัสใหม่ที่นี่: gist.github.com/furycomptuers/4961368
FuryComputers

9

อะแดปเตอร์ไม่ทำการกรองในตอนแรก
เมื่อไม่ได้ทำการกรองรายการดรอปดาวน์จะว่างเปล่า
ดังนั้นคุณอาจต้องเริ่มการกรองก่อน

ในการทำเช่นนั้นคุณสามารถเรียกใช้filter()หลังจากคุณเพิ่มรายการเสร็จแล้ว

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

6

คุณสามารถใช้ onFocusChangeListener;

TCKimlikNo.setOnFocusChangeListener(new OnFocusChangeListener() {

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

            }

        }
    });

6

คำตอบของ Destil ด้านบนเกือบจะใช้ได้ แต่มีข้อบกพร่องเล็กน้อย เมื่อผู้ใช้ก่อนให้ความสำคัญกับเขตข้อมูลมันทำงานอย่างไร แต่ถ้าพวกเขาออกแล้วกลับไปที่สนามมันจะไม่แสดงแบบเลื่อนลงเพราะค่าของ mPopupCanBeUpdated จะยังคงเป็นเท็จจากเมื่อมันถูกซ่อนอยู่ การแก้ไขคือการเปลี่ยนวิธี onFocusChanged เป็น:

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

แต่นี่ก็หมายความว่าข้อความจะถูกรีเซ็ต (แม้ว่าปกติแล้วค่อนข้างโอเค) ...
นักพัฒนา Android

3

เพื่อให้ CustomAutoCompleteTextView 1. แทนที่เมธอด setThreshold, เพียงพอถึงตัวกรอง, onFocusChanged

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

ลองมัน

    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

เพียงเรียกวิธีนี้เมื่อแตะหรือคลิกเหตุการณ์ของ autoCompleteTextView หรือที่ที่คุณต้องการ

autoCompleteTextView.showDropDown()

0

สิ่งนี้ใช้งานได้สำหรับฉันรหัสหลอก:

    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

เพียงแค่วางสิ่งนี้กับวิธีการสร้างของคุณใน 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();

        }
    });

และนี่คือไฟล์ Xml ของคุณ ...

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

และสร้าง Array ใน string.xml ภายใต้ 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>

และคุณจะไปดี


0

เจ็ดปีต่อมาพวกปัญหายังคงเหมือนเดิม นี่คือคลาสที่มีฟังก์ชั่นที่บังคับให้ป๊อปอัปโง่ที่จะแสดงตัวเองในทุกสภาวะ สิ่งที่คุณต้องทำคือตั้งค่าอะแดปเตอร์เป็น AutoCompleteTextView ของคุณเพิ่มข้อมูลลงไปและshowDropdownNow()ฟังก์ชั่นการโทรได้ทุกเวลา

เครดิตให้กับ @David Vávra มันขึ้นอยู่กับรหัสของเขา

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

บน FocusChangeListener ตรวจสอบ

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

ในตัวกรองของคุณเพียงตัดค่านี้:

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

และมันจะแสดงคำแนะนำทั้งหมดเมื่อคุณมุ่งเน้นไปที่มุมมองนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.