Note that there are some explanatory texts on larger screens.

plurals
  1. PORefreshing a ListView with a custom adapter
    text
    copied!<p>I am writing a small google talk client for android and I am having trouble refreshing my ListView correcty.</p> <p>This list contains the contact list and is showing the name and the presence of the contact. My listener works fine and I can see the presence changes of each contact in the log cat window, but my ListView is not refreshing... here is some code:</p> <pre><code>package de.marc.messenger; // ofc here are the imports public class RosterActivity extends Activity { private Roster _roster; private XMPPConnection _connection; private List&lt;HashMap&lt;String, String&gt;&gt; _buddies; private BuddyAdapter _adapter; private ListView _list; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.roster); _buddies = new ArrayList&lt;HashMap&lt;String, String&gt;&gt;(); _connection = LoginActivity.CONNECTION; makePauseForRoster(); _roster = _connection.getRoster(); addRosterListener(); fillBuddyList(); sortBuddyList(); initializeListView(); } /** * Lets the thread sleep for a second to ensure that the presence of every * user will be available */ private void makePauseForRoster() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } /** * Adds a listener to the roster, primarily for changes of presence */ private void addRosterListener() { _roster.addRosterListener(new RosterListener() { public void presenceChanged(Presence presence) { String user = presence.getFrom().split("/")[0]; HashMap&lt;String, String&gt; buddy = findBuddyInRoster(user); String p = getPresenceString(user); buddy.put("presence", p); System.out.println(buddy.values().toString()); // this works _adapter.notifyDataSetChanged(); // this doesn't _list.invalidate(); // this neither } }); } /** * Fills the list view with the roster entries */ private void initializeListView() { _adapter = new BuddyAdapter(this, R.layout.roster_item, _buddies); _list = (ListView) findViewById(R.id.list_roster); _list.setAdapter(_adapter); } /** * Fills the buddy list with relevant data from a RosterEntry. Relevant data * is the users' name, email and presence */ private void fillBuddyList() { // this just fills my list of hashmaps (_buddies) } /** * Get a predefined String depending on the presence of a user */ private String getPresenceString(String user) { // something like "available: away ()" -&gt; "away" } /** * Sorts the buddy list. Only criterion is the presence of the user, because * we have linear algorithms for this kind of problem. */ private void sortBuddyList() { // move all offline contacts to the end // move all online contacts to the beginning // all other kind of contacts will stay in the middle } /** * Finds a specific buddy object for a user via his hashed email */ private HashMap&lt;String, String&gt; findBuddyInRoster(String user) { for (HashMap&lt;String, String&gt; buddy : _buddies) { if (user.equals(buddy.get("user"))) { return buddy; } } return null; } </code></pre> <p>}</p> <p>This works fine, everything is shown correctly.. only trouble seems to be in the addRosterListener() method, where the onPresenceChanged() is implemented.. </p> <p>Here is my adapter:</p> <pre><code>package de.marc.messenger; // as well some imports public class BuddyAdapter extends ArrayAdapter&lt;HashMap&lt;String, String&gt;&gt; { private Context _context; private List&lt;HashMap&lt;String, String&gt;&gt; _map; private LayoutInflater _inflater; public BuddyAdapter(Context context, int id, List&lt;HashMap&lt;String, String&gt;&gt; map) { super(context, id, map); _context = context; _map = map; _inflater = (LayoutInflater) _context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public View getView(int position, View convertView, ViewGroup parent) { // find view of a single row in a listview View row = convertView; if (convertView == null) { row = _inflater.inflate(R.layout.roster_item, null); } // get data for a specific row String name = _map.get(position).get("name"); String user = _map.get(position).get("user"); String presence = _map.get(position).get("presence"); // extract views from the row view TextView nameText = (TextView) row.findViewById(R.id.text_name); TextView userText = (TextView) row.findViewById(R.id.text_id); ImageView presenceImg = (ImageView) row .findViewById(R.id.image_presence); // set data in extracted views nameText.setText(name); userText.setText(user); int resource = 0; // something is done with this variable presenceImg.setImageResource(resource); return row; } </code></pre> <p>}</p> <p>Is there anything I am missing?</p> <p><strong>Edit:</strong> I changed my onPresenceChanged method like this:</p> <pre><code>public void presenceChanged(Presence presence) { String user = presence.getFrom().split("/")[0]; HashMap&lt;String, String&gt; buddy = findBuddyInRoster(user); _adapter.remove(buddy); String p = getPresenceString(user); buddy.put("presence", p); _adapter.add(buddy); _adapter.notifyDataSetChanged(); } </code></pre> <p>It works to some extend: After swiping a bit on the screen, the contact that changed his presence is now out of the list :/</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload