Markus
Markus

Reputation: 1563

Add item to Android ListView with BaseAdapter

I'm trying to add an item to my listview after the callback comes from the database.

Here's my onCreateView:

private MessageItemAdapter mAdapter;
private List<DMessage> mMessageList;

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mAdapter = new MessageItemAdapter(getActivity());
// ...

in my AsyncTask:

// ...
mResultList.setAdapter(mAdapter);
// ...

my adapter:

class MessageItemAdapter extends BaseAdapter {

        private LayoutInflater mInflater;

        public MessageItemAdapter(Context context) {
            mInflater = LayoutInflater.from(context);
        }
// ....
if (convertView == null) {
                view = mInflater.inflate(R.layout.message_list, parent, false);
                holder = new ViewHolder();
// ...
holder.message.setText(mMessageList.get(position).getMessage());
// ...

and finally, after I inserted my new message into the database I get the callback where I try to refresh my list:

mMessageList.add(message);
mAdapter.notifyDataSetChanged();

mMessageList gets updated correctly, unfortunatly notifyDataSetChanged() doesn't refresh the listView though. Since that didn't work I also tried (bad) stuff like restarting my async Task, invalidating my ListView, but neither worked. This shouldn't matter, but for the sake of completeness my Callback comes via Socket.IO


edit: here's more code: the Socket.IO Callback which should calls mAdapter.updateList():

.on("send back new message", new Emitter.Listener() {
 @Override
 public void call(Object... args) {
 JSONObject jObj = (JSONObject) args[0];
   try {
     DMessage message = prepareMessageObject(jObj);
       if (message != null) {
         mMessageList.add(message);
         mAdapter.updateList(mMessageList);
       }
   } catch (Exception e) {...}
 }
});

and the fullk code of the MessageItemAdapter:

class MessageItemAdapter extends BaseAdapter {

        private LayoutInflater mInflater;
        private ArrayList<DMessage> messageList;

        public MessageItemAdapter(Context context, ArrayList<DMessage> data) {
            this.mInflater = LayoutInflater.from(context);
            this.messageList = data;
        }

        private class ViewHolder {
            public TextView name;
            public TextView message;
        }

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

        @Override
        public Object getItem(int position) {
            return position;
        }

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

        public void updateList(ArrayList<DMessage> data) {
            messageList = data;
            notifyDataSetChanged();
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = convertView;
            final ViewHolder holder;
            if (convertView == null) {
                view = mInflater.inflate(R.layout.message_list, parent, false);
                holder = new ViewHolder();
                holder.message = (TextView) view.findViewById(R.id.message_list_message);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }

            holder.message.setText(messageList.get(position).getMessage()));

            return view;
        }
    }

SOLUTION

I'm not sure what exactly the problem was, but after I switched to an ArrayAdapter it works fine. The ListView appends the new line correclty. I guess maybe a BaseAdapter doesn't support this?

Upvotes: 1

Views: 5132

Answers (2)

Jayaprakash Marshal
Jayaprakash Marshal

Reputation: 250

Just create the method in adapter class as follows,

   class MessageItemAdapter extends BaseAdapter {

         public MessageItemAdapter(Context context, ArrayList<YourClass> data) {
             mInflater = LayoutInflater.from(context);
             mMessageList = data;
          }

             /*
              * Update and refresh list 
              */
         public void updateList(ArrayList<YourClass> data) {
             mMessageList = data;
             notifyDataSetChanged();
          }


    }

And in your Activity class, call the method with updated list as follows,

   mMessageList.add(message);
   mAdapter.updateList(mMessageList);

Thats all. It will be refreshed automatically as notifyDataSetChanged() is defined in adapter class.

Upvotes: 3

SweetWisher ツ
SweetWisher ツ

Reputation: 7306

Pass the data to the Adapter :

mAdapter = new MessageItemAdapter(getActivity(), mMessageList );

And add this parameter in the Constructor :

public MessageItemAdapter(Context context, ArrayList<YourClass> data) {
        mInflater = LayoutInflater.from(context);
        mMessageList = data;
}

Now you can update the data in the list only with

mAdapter.notifyDataSetChanged();

Upvotes: 0

Related Questions