开发者

What adapter shall I use to use HashMap in a ListView

I want to use HashMap for a list of items of Adapter for a ListView. I was going to use ArrayAdapter<> but I can't because it is working with List&开发者_运维知识库lt;> only. What adapter shall I use?


There are no predefined Adapters which will render a HashMap. I suggest creating your own Adapter by extending BaseAdapter.

Edit: It is posible to use HashMap with and extended BaseAdapter, here's an(untested) example:

public class HashMapAdapter extends BaseAdapter {

    private HashMap<String, String> mData = new HashMap<String, String>();
    private String[] mKeys;
    public HashMapAdapter(HashMap<String, String> data){
        mData  = data;
        mKeys = mData.keySet().toArray(new String[data.size()]);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(mKeys[position]);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {
        String key = mKeys[pos];
        String Value = getItem(pos).toString();

        //do your view stuff here

        return convertView;
    }
}

This comes with the following caveat, the order of the items is not guaranteed to be the same order you added them. Writing this example has made me realize; Don't use HashMap in an adapter :)


Thanks for the answer longhairedsi

This comes with the following caveat, the order of the items is not guaranteed to be the same order you added them. Writing this example has made me realize; Don't use HashMap in an adapter :)

To get around this problem, use a LinkedHashMap instead.

public class HashMapAdapter extends BaseAdapter {
    private LinkedHashMap<String, String> mData = new LinkedHashMap<String, String>();
    private String[] mKeys;
    public HashMapAdapter(LinkedHashMap<String, String> data){
        mData  = data;
        mKeys = mData.keySet().toArray(new String[data.size()]);
    }

    @Override
    public int getCount() {
        return mData.size();
    }

    @Override
    public Object getItem(int position) {
        return mData.get(mKeys[position]);
    }

    @Override
    public long getItemId(int arg0) {
        return arg0;
    }

    @Override
    public View getView(int pos, View convertView, ViewGroup parent) {
        String key = mKeys[pos];
        String Value = getItem(pos).toString();

        //do your view stuff here

        return convertView;
    }
}


You can get an array of your map entries:

Entry<MyKey, MyValue>[] entries =
    map.entrySet().toArray(new Entry<MyKey, MyValue>[0]);

That being said, if you are planning on updating your map or using map features in the adapter then making a custom adapter is not difficult and would make much more sense.

You can start out by subclassing BaseAdapter, which provides implementations for all but a few of the Adapter methods you need to get running.


In your adapter file

MyAdapter.java

 import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;

    import java.util.ArrayList;
    import java.util.Map;

    public class MyAdapter extends BaseAdapter {
        private final ArrayList mData;

        public MyAdapter(Map<String, String> map) {
            mData = new ArrayList();
            mData.addAll(map.entrySet());
        }

        @Override
        public int getCount() {
            return mData.size();
        }

        @Override
        public Map.Entry<String, String> getItem(int position) {
            return (Map.Entry) mData.get(position);
        }

        @Override
        public long getItemId(int position) {
            // TODO implement you own logic with ID
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final View result;

            if (convertView == null) {
                result = LayoutInflater.from(parent.getContext()).inflate(R.layout.my_adapter_item, parent, false);
            } else {
                result = convertView;
            }

            Map.Entry<String, String> item = getItem(position);

            // TODO replace findViewById by ViewHolder
            ((TextView) result.findViewById(R.id.text1)).setText(item.getKey());
            ((TextView) result.findViewById(R.id.text2)).setText(item.getValue());

            return result;
        }
    }

Call this adapter

public void showCinemas(HashMap<String, String> cinemas) {
    MyAdapter adapter = new MyAdapter(cinemas);
    list.setAdapter(adapter);
}


To maintain order in the dictionary, if the key type is applicable, you could always add them to an ArrayList of their own, sort it using Collections.sort, and work with that as your reference point.

private ArrayList<String> mKeys = new ArrayList<>();

for (String aKey :data.keySet()){
        mKeys.add(aKey);
    }
Collections.sort(mKeys);


What you can do, IMHO, is generate a new list for they key values of the Hashmap that you are trying to add, and then pass that list to the custom adapter. Then import the HashMap collection in the adapter and use HashMap.get(key); from the list of reference keys.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜