简体   繁体   中英

AutoCompleteTextView drop down list is not hiding when an item selected for the first time

When a user types something in AutoCompleteTextView, I am fetching data from database in async task. I have addTextChangedListener with TextWatcher in AutoCompleteTextView. The problem is that when the user selects an item from the suggested list, this data is entered into the text watcher but the drop down list even visible to the user. Because, when user select an item from drop down then TextWatcher.onTextChanged() gets called again and this call send a new request. This happens for the first time an item selected, if the user clicks the item again, the dropdown list won't show up.

So how to hide this drop down list when user select an item from the suggested list for the first time?

I have done this:

autoComplete = (AutoCompleteTextView) findViewById(R.id.my_text);



     final TextWatcher yourTextWatcher = new TextWatcher() {

        @Override
        public void afterTextChanged(Editable s) {
            Log.d(TAG, "afterTextChanged:" + s.toString());
            afterTextChanged = s.toString();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            Log.d(TAG, "beforeTextChanged:" + s.toString());
            beforeTextChanged = s.toString();
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

            Log.e(TAG, "beforeTextChanged:" + beforeTextChanged + ",afterTextChanged:" + afterTextChanged + ",onTextChanged:" + s.toString());
            if (!beforeTextChanged.equals(s.toString())) {
                new doPopulate().execute(s.toString());
            }
        }
    };

Logcat: when an item is selected (Google) after typing "go"

beforeTextChanged:go
beforeTextChanged:go,afterTextChanged:go,onTextChanged:Google
afterTextChanged:Google

Keep a boolean flag for if the user selects, and add an onItemClickListener to your AutoCompleteTextView, ie

boolean selectedText = false;

autoComplete.setOnItemClickedListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
        selectedText = true;
    }
});

Then check the selectedText flag in your TextWatcher:

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

        Log.e(TAG, "beforeTextChanged:" + beforeTextChanged + ",afterTextChanged:" + afterTextChanged + ",onTextChanged:" + s.toString());
        if (!beforeTextChanged.equals(s.toString()) && !selectedText) { //Here we check selectedText
            new doPopulate().execute(s.toString());
        }
        selectedText = false; //Clear selectedText flag
    }

Cheers

Add the following line of code in your onTextChanged method : if(autoComplete.isPerformingCompletion()) { // An item has been selected from the list. return; } if(autoComplete.isPerformingCompletion()) { // An item has been selected from the list. return; }

i have added double spaces before the ArrayAdapter items of which displayed on Autocomplete dropdown and when user select an item from dropdown and when onTextChanged fired check the condition string is not equal to double spaces then execute asyn task.

ontextchanged code

autoComplete = (AutoCompleteTextView) findViewById(R.id.autoComplete);          
            autoComplete.addTextChangedListener(new TextWatcher() {         
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                String SearchProd = s.toString(); 
                 if (SearchProd.length()>=2){
                     String SearchProdSpace=SearchProd.substring(0,2);                  

                        if(SearchProdSpace!="  " && itemselected==false)
                        {
                            try{
                             new GetProductData(SearchProd).execute(); 
                            }catch(Exception e){ e.printStackTrace();}
                       }
               }
                 itemselected=false;
            }

AsyncTask code

public class GetProductData extends AsyncTask<String, Void, Void> {
    private ProgressDialog Dialog = new ProgressDialog(context);

    GetProductData(String str) {            
          try {
              qryText= URLEncoder.encode(str, "UTF-8");              
        } catch (UnsupportedEncodingException e1) {
            e1.printStackTrace();

        }
    }

    protected void onPreExecute() {
        Dialog.setMessage("Loading ...");
        Dialog.setCanceledOnTouchOutside(false);
        Dialog.show();
    }

    @Override
    protected Void doInBackground(String... params) {
        try {
            JSONObject json = new JSONObject(getProductData());
            ProductList=new ArrayList<String>();
            Status = json.getBoolean("Status");
            if (Status) {                   
                JSONArray Products=json.getJSONArray("Products");                   
                if (Products.length() > 0) {
                    for (int i = 0; i < Products.length(); i++) {
                        JSONObject ProductObj = Products.getJSONObject(i);                      
                        ProductList.add("  "+ProductObj.getString("Name"));
                    }
                }
            } else {
                Error = json.getString("Message");
            }
        } catch (JSONException e) {
            Error = e.getMessage();
        }
        return null;
    }

    protected void onPostExecute(Void unused) {
        Dialog.dismiss();
        if (Error != null) {
            Toast.makeText(context, "Some Error Occured : " + Error,
                    Toast.LENGTH_LONG).show();
        } else {
                try {
                    ArrayAdapter<String> Arrayadapter = new ArrayAdapter<String>(context, android.R.layout.simple_dropdown_item_1line,ProductList);   
                    Arrayadapter.setNotifyOnChange(true);                   
                    autoComplete.setAdapter(Arrayadapter); 
                    autoComplete.showDropDown();
                    autoComplete.requestFocus();

                    autoComplete.setOnItemClickListener(new OnItemClickListener() {                    
                        @Override
                        public void onItemClick(AdapterView<?> parent, View view,
                           int position, long id) {
                            itemselected=true;
                            String itemstr=ProductList.get(position).trim();
                            autoComplete.setText(itemstr);
                        }
                   }); 

                   // ItemName.setSelected(selected)

                } catch (Exception e) {e.printStackTrace(); }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM