如何获取AutoCompleteTextView适配器的正确ID

6
我是Android开发的新手,遇到了一个难以解决的问题。我正在尝试弄清楚如何正确使用AutoCompleteTextView小部件。我想创建一个AutoCompleteTextView,使用来自Web服务的XML数据。我设法让它工作了,但输出结果并不令人满意。
我想把一个id => name对的HashMap放入AutoCompleteTextView中,并获取点击项的id。当我点击自动完成过滤集输出时,我希望在自动完成框下面填充一个列表,这也是我成功实现的。
已完成的内容:
  • 简单的ArrayList可以正常过滤
  • 点击后触发了onItemClick事件
  • parent.getItemAtPosition(position)返回了正确的被点击项的字符串表示形式
onItemClick(AdapterView parent, View v, int position, long id)事件不像我期望的那样工作。我该如何找出被点击项未过滤数组的位置?我不关心过滤后的位置。
更进一步的问题:
  • 如何处理HashMapsCollectionsAutoCompleteTextView
  • 如何在onItemClick事件中获取正确的itemId
我已经对这个问题进行了非常广泛的研究,但没有找到任何有价值的信息来回答我的问题。

朋友,我尝试解决了这个问题,但是没能成功...我想知道,为什么安卓高手们没有提供解决方案呢? - i leaf
4个回答

13

onItemClick(AdapterView parent, View v, int position, long id)事件的行为不符合我的期望。

当过滤一个适配器时,这是一种正常情况。虽然从其角度来看适配器保留对初始未过滤数据的引用,但它基于一组数据(无论是初始数据还是过滤操作结果)进行操作。但这不应该引起任何问题。使用默认的SDK适配器(或子类),在onItemClick()中,您可以获取基于适配器的当前列表的position。然后,您可以使用getItem()来获取该position的数据项(再次强调,初始数据和过滤后的数据都可以)。

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

假设您使用SimpleAdapter,这将适用于列表和Maps。对于Maps,您始终可以选择添加附加键来设置初始列表中的未过滤位置。

如果您使用自己的适配器以及AutoCompleteTextView,则可以使onItemClick()提供正确的id(但是您无法更改位置)。

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


}

以及适配器:

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

}

如果您还为适配器实现Filter类,则无需覆盖AutoCompleTextView类即可从那里获取ID。


1

为AutoCompleteTextView实现onItemClickListener,然后在列表中使用indexOf查找所选项的索引。

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

1
使用Luksprog方法,我制作了一些类似于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;
        }

    }

0

首先将数据添加到自定义数组列表中

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

现在,要从我们上面添加的模型中获取任何值,可以像这样获取。

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

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