How to get correct ID of AutoCompleteTextView adapter

放肆的年华 提交于 2020-01-03 15:21:20

问题


I am new to Android development and I ran into a problem which I find difficult to solve. I am trying to figure out how to use an AutoCompleteTextView widget properly. I want to create a AutoCompleteTextView, using XML data from a web service. I managed to get it to work, but I am defenitely not pleased with the output.

I would like to put a HashMap with id => name pairs into the AutoCompleteTextView and get the id of the clicked item. When I click on the autocomplete filtered set output, I want to populate a list underneath the autocompletion box, which I also managed to get to work.

Done so far:

  • autocomplete works well for simple ArrayList, all data filtered correct
  • onItemClick event fires properly after click
  • parent.getItemAtPosition(position) returns correct String representation of the clicked item

The event onItemClick(AdapterView parent, View v, int position, long id) does not behave as I would like. How can I figure out the unfiltered array position of the clicked item? The position of the filtered one is the one I am not interested in.

Further questions:

  • How to handle HashMaps or Collections in AutoCompleteTextView
  • How to get the right itemId in the onItemClick event

I did very extensive research on this issue, but did not find any valuable information which would answer my questions.


回答1:


The event onItemClick(AdapterView parent, View v, int position, long id) does not behave as I would like.

This is a normal situation when filtering an adapter. Although the adapter keeps a reference to the initial unfiltered data from its point of view it has a single set of data on which is based(no matter if is the initial one or resulted from a filter operation). But this shouldn't raise any problems. With the default sdk adapters(or with a subclass), in the onItemClick() you get the position for the current list on which the adapter is based. You could then use getItem() to get data item for that position(again it doesn't matter if initial or filtered).

String data = getItem(position);
int realPosition = list.indexOf(data); // if you want to know the unfiltered position

this will work for lists and Maps(assuming that you use the SimpleAdapter). And for a Maps you always have the option of adding an additional key to set the unfiltered position in the initial list.

If you use your own adapter along with an AutoCompleteTextView you could make the onItemClick() give you the right id(the position however you can't change).

public class SpecialAutoComplete extends AutoCompleteTextView {

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

    @Override
    public void onFilterComplete(int count) {
        // this will be called when the adapter finished the filter
        // operation and it notifies the AutoCompleteTextView
        long[] realIds = new long[count]; // this will hold the real ids from our maps
        for (int i = 0; i < count; i++) {
            final HashMap<String, String> item = (HashMap<String, String>) getAdapter()
                    .getItem(i);
            realIds[i] = Long.valueOf(item.get("id")); // get the ids from the filtered items
        }
        // update the adapter with the real ids so it has the proper data
        ((SimpleAdapterExtension) getAdapter()).setRealIds(realIds);
        super.onFilterComplete(count);
    }


}

and the adapter:

public class SimpleAdapterExtension extends SimpleAdapter {

    private List<? extends Map<String, String>> mData;
    private long[] mCurrentIds;

    public SimpleAdapterExtension(Context context,
            List<? extends Map<String, String>> data, int resource,
            String[] from, int[] to) {
        super(context, data, resource, from, to);
        mData = data;
    }

    @Override
    public long getItemId(int position) {       
        // this will be used to get the id provided to the onItemClick callback
        return mCurrentIds[position];
    }

    @Override
    public boolean hasStableIds() {
        return true;
    }

    public void setRealIds(long[] realIds) {
        mCurrentIds = realIds;
    }

}

If you also implement the Filter class for the adapter then you could get the ids from there without the need to override the AutoCompleTextView class.




回答2:


Using the Luksprog approach, I made some similar with ArrayAdapter.

    public class SimpleAutoCompleteAdapter extends ArrayAdapter<String>{
        private String[] mData;
        private int[] mCurrentIds;

        public SimpleAutoCompleteAdapter(Context context, int textViewResourceId,
             String[] objects) {
             super(context, textViewResourceId, objects);
             mData=objects;
        }

        @Override
        public long getItemId(int position) {
            String data = getItem(position);
            int index = Arrays.asList(mData).indexOf(data);
            /*
             * Atention , if your list has more that one same String , you have to improve here  
             */
            // this will be used to get the id provided to the onItemClick callback
            if (index>0)
                return (long)mCurrentIds[index];
            else return 0;
        }

        @Override
        public boolean hasStableIds() {
            return true;
        }

        public void setRealIds(int[] realIds) {
            mCurrentIds = realIds;
        }

    }



回答3:


Implement onItemClickListener for AutoCompleteTextView, then use indexOf on your list to find the index of selected item.

actvCity.setOnItemClickListener(new OnItemClickListener() {

     @Override
     public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
          long arg3) {
          int index = cityNames.indexOf(actvCity.getText().toString());
          // Do Whatever you want to do ;)
     }
});



回答4:


First add your data into custom arraylist

    // mList used for adding custom data into your model
        private List<OutletListSRModel> mList = new ArrayList<>();
      // listdata used for adding string data for auto completing.
        ArrayList<String> listdata = new ArrayList<String>();
        for (int i = 0; i < JArray.length(); i++) {
           JSONObject responseJson = JArray.getJSONObject(i);
           OutletListSRModel mModel = new OutletListSRModel();
           mModel.setId(responseJson.getString("id"));
           mModel.name(responseJson.getString("outlet_name"));
           listdata.add(responseJson.getString("outlet_name"));
        }

    ArrayAdapter adapter = new
                            ArrayAdapter(getActivity(),
 android.R.layout.simple_list_item_1, listdata);
    searchOutletKey.setAdapter(adapter);

Now for getting any value from model which we added above. we can get like this.

searchOutletKey.setOnItemClickListener ( new AdapterView.OnItemClickListener ( ) {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                String txtOutletId = mOutletListSRModel.get(position).getId();
            }
        });


来源:https://stackoverflow.com/questions/11522592/how-to-get-correct-id-of-autocompletetextview-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!